/*
 * Copyright (C) 2011 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "IDBLevelDBCoding.h"

#if ENABLE(INDEXED_DATABASE)
#if USE(LEVELDB)

#include "IDBKey.h"
#include "IDBKeyPath.h"
#include "LevelDBSlice.h"
#include <gtest/gtest.h>
#include <wtf/Vector.h>

using namespace WebCore;
using namespace IDBLevelDBCoding;

namespace {

static PassRefPtr<IDBKey> createArrayIDBKey()
{
    return IDBKey::createArray(IDBKey::KeyArray());
}

static PassRefPtr<IDBKey> createArrayIDBKey(PassRefPtr<IDBKey> prpKey1)
{
    RefPtr<IDBKey> key1 = prpKey1;

    IDBKey::KeyArray array;
    array.append(key1);
    return IDBKey::createArray(array);
}

static PassRefPtr<IDBKey> createArrayIDBKey(PassRefPtr<IDBKey> prpKey1, PassRefPtr<IDBKey> prpKey2)
{
    RefPtr<IDBKey> key1 = prpKey1;
    RefPtr<IDBKey> key2 = prpKey2;

    IDBKey::KeyArray array;
    array.append(key1);
    array.append(key2);
    return IDBKey::createArray(array);
}

TEST(IDBLevelDBCodingTest, EncodeByte)
{
    Vector<char> expected;
    expected.append(0);
    unsigned char c;

    c = 0;
    expected[0] = c;
    EXPECT_EQ(expected, encodeByte(c));

    c = 1;
    expected[0] = c;
    EXPECT_EQ(expected, encodeByte(c));

    c = 255;
    expected[0] = c;
    EXPECT_EQ(expected, encodeByte(c));
}

TEST(IDBLevelDBCodingTest, DecodeByte)
{
    Vector<unsigned char> testCases;
    testCases.append(0);
    testCases.append(1);
    testCases.append(255);

    for (size_t i = 0; i < testCases.size(); ++i) {
        unsigned char n = testCases[i];
        Vector<char> v = encodeByte(n);

        unsigned char res;
        const char* p = decodeByte(v.data(), v.data() + v.size(), res);
        EXPECT_EQ(n, res);
        EXPECT_EQ(v.data() + v.size(), p);
    }
}
   
TEST(IDBLevelDBCodingTest, EncodeBool)
{
    {
        Vector<char> expected;
        expected.append(1);
        EXPECT_EQ(expected, encodeBool(true));
    }
    {
        Vector<char> expected;
        expected.append(0);
        EXPECT_EQ(expected, encodeBool(false));
    }
}

TEST(IDBLevelDBCodingTest, MaxIDBKey)
{
    Vector<char> maxKey = maxIDBKey();

    Vector<char> minKey = minIDBKey();
    Vector<char> arrayKey = encodeIDBKey(*IDBKey::createArray(IDBKey::KeyArray()));
    Vector<char> stringKey = encodeIDBKey(*IDBKey::createString("Hello world"));
    Vector<char> numberKey = encodeIDBKey(*IDBKey::createNumber(3.14));
    Vector<char> dateKey = encodeIDBKey(*IDBKey::createDate(1000000));

    EXPECT_GT(compareEncodedIDBKeys(maxKey, minKey), 0);
    EXPECT_GT(compareEncodedIDBKeys(maxKey, arrayKey), 0);
    EXPECT_GT(compareEncodedIDBKeys(maxKey, stringKey), 0);
    EXPECT_GT(compareEncodedIDBKeys(maxKey, numberKey), 0);
    EXPECT_GT(compareEncodedIDBKeys(maxKey, dateKey), 0);
}

TEST(IDBLevelDBCodingTest, MinIDBKey)
{
    Vector<char> minKey = minIDBKey();

    Vector<char> maxKey = maxIDBKey();
    Vector<char> arrayKey = encodeIDBKey(*IDBKey::createArray(IDBKey::KeyArray()));
    Vector<char> stringKey = encodeIDBKey(*IDBKey::createString("Hello world"));
    Vector<char> numberKey = encodeIDBKey(*IDBKey::createNumber(3.14));
    Vector<char> dateKey = encodeIDBKey(*IDBKey::createDate(1000000));

    EXPECT_LT(compareEncodedIDBKeys(minKey, maxKey), 0);
    EXPECT_LT(compareEncodedIDBKeys(minKey, arrayKey), 0);
    EXPECT_LT(compareEncodedIDBKeys(minKey, stringKey), 0);
    EXPECT_LT(compareEncodedIDBKeys(minKey, numberKey), 0);
    EXPECT_LT(compareEncodedIDBKeys(minKey, dateKey), 0);
}

TEST(IDBLevelDBCodingTest, EncodeInt)
{
    EXPECT_EQ(static_cast<size_t>(1), encodeInt(0).size());
    EXPECT_EQ(static_cast<size_t>(1), encodeInt(1).size());
    EXPECT_EQ(static_cast<size_t>(1), encodeInt(255).size());
    EXPECT_EQ(static_cast<size_t>(2), encodeInt(256).size());
    EXPECT_EQ(static_cast<size_t>(4), encodeInt(0xffffffff).size());
#ifdef NDEBUG
    EXPECT_EQ(static_cast<size_t>(8), encodeInt(-1).size());
#endif
}

TEST(IDBLevelDBCodingTest, DecodeBool)
{
    {
        Vector<char> encoded;
        encoded.append(1);
        EXPECT_TRUE(decodeBool(encoded.data(), encoded.data() + encoded.size()));
    }
    {
        Vector<char> encoded;
        encoded.append(0);
        EXPECT_FALSE(decodeBool(encoded.data(), encoded.data() + encoded.size()));
    }
}

TEST(IDBLevelDBCodingTest, DecodeInt)
{
    Vector<int64_t> testCases;
    testCases.append(0);
    testCases.append(1);
    testCases.append(255);
    testCases.append(256);
    testCases.append(65535);
    testCases.append(655536);
    testCases.append(7711192431755665792ll);
    testCases.append(0x7fffffffffffffffll);
#ifdef NDEBUG
    testCases.append(-3);
#endif

    for (size_t i = 0; i < testCases.size(); ++i) {
        int64_t n = testCases[i];
        Vector<char> v = encodeInt(n);
        EXPECT_EQ(n, decodeInt(v.data(), v.data() + v.size()));
    }
}

TEST(IDBLevelDBCodingTest, EncodeVarInt)
{
    EXPECT_EQ(static_cast<size_t>(1), encodeVarInt(0).size());
    EXPECT_EQ(static_cast<size_t>(1), encodeVarInt(1).size());
    EXPECT_EQ(static_cast<size_t>(2), encodeVarInt(255).size());
    EXPECT_EQ(static_cast<size_t>(2), encodeVarInt(256).size());
    EXPECT_EQ(static_cast<size_t>(5), encodeVarInt(0xffffffff).size());
    EXPECT_EQ(static_cast<size_t>(8), encodeVarInt(0xfffffffffffffLL).size());
    EXPECT_EQ(static_cast<size_t>(9), encodeVarInt(0x7fffffffffffffffLL).size());
#ifdef NDEBUG
    EXPECT_EQ(static_cast<size_t>(10), encodeVarInt(-100).size());
#endif
}

TEST(IDBLevelDBCodingTest, DecodeVarInt)
{
    Vector<int64_t> testCases;
    testCases.append(0);
    testCases.append(1);
    testCases.append(255);
    testCases.append(256);
    testCases.append(65535);
    testCases.append(655536);
    testCases.append(7711192431755665792ll);
    testCases.append(0x7fffffffffffffffll);
#ifdef NDEBUG
    testCases.append(-3);
#endif

    for (size_t i = 0; i < testCases.size(); ++i) {
        int64_t n = testCases[i];
        Vector<char> v = encodeVarInt(n);

        int64_t res;
        const char* p = decodeVarInt(v.data(), v.data() + v.size(), res);
        EXPECT_EQ(n, res);
        EXPECT_EQ(v.data() + v.size(), p);

        p = decodeVarInt(v.data(), v.data() + v.size() - 1, res);
        EXPECT_EQ(0, p);
        p = decodeVarInt(v.data(), v.data(), res);
        EXPECT_EQ(0, p);
    }
}

TEST(IDBLevelDBCodingTest, EncodeString)
{
    const UChar testStringA[] = {'f', 'o', 'o', '\0'};
    const UChar testStringB[] = {0xdead, 0xbeef, '\0'};

    EXPECT_EQ(static_cast<size_t>(0), encodeString(String("")).size());
    EXPECT_EQ(static_cast<size_t>(2), encodeString(String("a")).size());
    EXPECT_EQ(static_cast<size_t>(6), encodeString(String("foo")).size());
    EXPECT_EQ(static_cast<size_t>(6), encodeString(String(testStringA)).size());
    EXPECT_EQ(static_cast<size_t>(4), encodeString(String(testStringB)).size());
}

TEST(IDBLevelDBCodingTest, DecodeString)
{
    const UChar testStringA[] = {'f', 'o', 'o', '\0'};
    const UChar testStringB[] = {0xdead, 0xbeef, '\0'};
    Vector<char> v;

    v = encodeString(String(""));
    EXPECT_EQ(String(""), decodeString(v.data(), v.data() + v.size()));

    v = encodeString(String("a"));
    EXPECT_EQ(String("a"), decodeString(v.data(), v.data() + v.size()));

    v = encodeString(String("foo"));
    EXPECT_EQ(String("foo"), decodeString(v.data(), v.data() + v.size()));

    v = encodeString(String(testStringA));
    EXPECT_EQ(String(testStringA), decodeString(v.data(), v.data() + v.size()));

    v = encodeString(String(testStringB));
    EXPECT_EQ(String(testStringB), decodeString(v.data(), v.data() + v.size()));
}

TEST(IDBLevelDBCodingTest, EncodeStringWithLength)
{
    const UChar testStringA[] = {'f', 'o', 'o', '\0'};
    const UChar testStringB[] = {0xdead, 0xbeef, '\0'};

    EXPECT_EQ(static_cast<size_t>(1), encodeStringWithLength(String("")).size());
    EXPECT_EQ(static_cast<size_t>(3), encodeStringWithLength(String("a")).size());
    EXPECT_EQ(static_cast<size_t>(7), encodeStringWithLength(String(testStringA)).size());
    EXPECT_EQ(static_cast<size_t>(5), encodeStringWithLength(String(testStringB)).size());
}

TEST(IDBLevelDBCodingTest, DecodeStringWithLength)
{
    const UChar testStringA[] = {'f', 'o', 'o', '\0'};
    const UChar testStringB[] = {0xdead, 0xbeef, '\0'};

    const int kLongStringLen = 1234;
    UChar longString[kLongStringLen + 1];
    for (int i = 0; i < kLongStringLen; ++i)
        longString[i] = i;
    longString[kLongStringLen] = 0;

    Vector<String> testCases;
    testCases.append(String(""));
    testCases.append(String("a"));
    testCases.append(String("foo"));
    testCases.append(String(testStringA));
    testCases.append(String(testStringB));
    testCases.append(String(longString));

    for (size_t i = 0; i < testCases.size(); ++i) {
        String s = testCases[i];
        Vector<char> v = encodeStringWithLength(s);
        String res;
        const char* p = decodeStringWithLength(v.data(), v.data() + v.size(), res);
        EXPECT_EQ(s, res);
        EXPECT_EQ(v.data() + v.size(), p);

        EXPECT_EQ(0, decodeStringWithLength(v.data(), v.data() + v.size() - 1, res));
        EXPECT_EQ(0, decodeStringWithLength(v.data(), v.data(), res));
    }
}

static int compareStrings(const char* p, const char* limitP, const char* q, const char* limitQ)
{
    int result = compareEncodedStringsWithLength(p, limitP, q, limitQ);
    EXPECT_EQ(p, limitP);
    EXPECT_EQ(q, limitQ);
    return result;
}

TEST(IDBLevelDBCodingTest, CompareEncodedStringsWithLength)
{
    const UChar testStringA[] = {0x1000, 0x1000, '\0'};
    const UChar testStringB[] = {0x1000, 0x1000, 0x1000, '\0'};
    const UChar testStringC[] = {0x1000, 0x1000, 0x1001, '\0'};
    const UChar testStringD[] = {0x1001, 0x1000, 0x1000, '\0'};
    const UChar testStringE[] = {0xd834, 0xdd1e, '\0'};
    const UChar testStringF[] = {0xfffd, '\0'};

    Vector<String> testCases;
    testCases.append(String(""));
    testCases.append(String("a"));
    testCases.append(String("b"));
    testCases.append(String("baaa"));
    testCases.append(String("baab"));
    testCases.append(String("c"));
    testCases.append(String(testStringA));
    testCases.append(String(testStringB));
    testCases.append(String(testStringC));
    testCases.append(String(testStringD));
    testCases.append(String(testStringE));
    testCases.append(String(testStringF));

    for (size_t i = 0; i < testCases.size() - 1; ++i) {
        String a = testCases[i];
        String b = testCases[i + 1];

        EXPECT_LT(codePointCompare(a, b), 0);
        EXPECT_GT(codePointCompare(b, a), 0);
        EXPECT_EQ(codePointCompare(a, a), 0);
        EXPECT_EQ(codePointCompare(b, b), 0);

        Vector<char> encodedA = encodeStringWithLength(a);
        EXPECT_TRUE(encodedA.size());
        Vector<char> encodedB = encodeStringWithLength(b);
        EXPECT_TRUE(encodedA.size());

        const char* p = encodedA.data();
        const char* limitP = p + encodedA.size();
        const char* q = encodedB.data();
        const char* limitQ = q + encodedB.size();

        EXPECT_LT(compareStrings(p, limitP, q, limitQ), 0);
        EXPECT_GT(compareStrings(q, limitQ, p, limitP), 0);
        EXPECT_EQ(compareStrings(p, limitP, p, limitP), 0);
        EXPECT_EQ(compareStrings(q, limitQ, q, limitQ), 0);
    }
}

TEST(IDBLevelDBCodingTest, EncodeDouble)
{
    EXPECT_EQ(static_cast<size_t>(8), encodeDouble(0).size());
    EXPECT_EQ(static_cast<size_t>(8), encodeDouble(3.14).size());
}

TEST(IDBLevelDBCodingTest, DecodeDouble)
{
    Vector<char> v;
    const char* p;
    double d;

    v = encodeDouble(3.14);
    p = decodeDouble(v.data(), v.data() + v.size(), &d);
    EXPECT_EQ(3.14, d);
    EXPECT_EQ(v.data() + v.size(), p);

    v = encodeDouble(-3.14);
    p = decodeDouble(v.data(), v.data() + v.size(), &d);
    EXPECT_EQ(-3.14, d);
    EXPECT_EQ(v.data() + v.size(), p);

    v = encodeDouble(3.14);
    p = decodeDouble(v.data(), v.data() + v.size() - 1, &d);
    EXPECT_EQ(0, p);
}

TEST(IDBLevelDBCodingTest, EncodeDecodeIDBKey)
{
    RefPtr<IDBKey> expectedKey;
    RefPtr<IDBKey> decodedKey;
    Vector<char> v;
    const char* p;

    expectedKey = IDBKey::createNumber(1234);
    v = encodeIDBKey(*expectedKey);
    p = decodeIDBKey(v.data(), v.data() + v.size(), decodedKey);
    EXPECT_TRUE(decodedKey->isEqual(expectedKey.get()));
    EXPECT_EQ(v.data() + v.size(), p);
    EXPECT_EQ(0, decodeIDBKey(v.data(), v.data() + v.size() - 1, decodedKey));

    expectedKey = IDBKey::createString("Hello World!");
    v = encodeIDBKey(*expectedKey);
    p = decodeIDBKey(v.data(), v.data() + v.size(), decodedKey);
    EXPECT_TRUE(decodedKey->isEqual(expectedKey.get()));
    EXPECT_EQ(v.data() + v.size(), p);
    EXPECT_EQ(0, decodeIDBKey(v.data(), v.data() + v.size() - 1, decodedKey));

    expectedKey = createArrayIDBKey();
    v = encodeIDBKey(*expectedKey);
    p = decodeIDBKey(v.data(), v.data() + v.size(), decodedKey);
    EXPECT_TRUE(decodedKey->isEqual(expectedKey.get()));
    EXPECT_EQ(v.data() + v.size(), p);
    EXPECT_EQ(0, decodeIDBKey(v.data(), v.data() + v.size() - 1, decodedKey));

    expectedKey = IDBKey::createDate(7890);
    v = encodeIDBKey(*expectedKey);
    p = decodeIDBKey(v.data(), v.data() + v.size(), decodedKey);
    EXPECT_TRUE(decodedKey->isEqual(expectedKey.get()));
    EXPECT_EQ(v.data() + v.size(), p);
    EXPECT_EQ(0, decodeIDBKey(v.data(), v.data() + v.size() - 1, decodedKey));

    IDBKey::KeyArray array;
    array.append(IDBKey::createNumber(1234));
    array.append(IDBKey::createString("Hello World!"));
    array.append(IDBKey::createDate(7890));
    expectedKey = IDBKey::createArray(array);
    v = encodeIDBKey(*expectedKey);
    p = decodeIDBKey(v.data(), v.data() + v.size(), decodedKey);
    EXPECT_TRUE(decodedKey->isEqual(expectedKey.get()));
    EXPECT_EQ(v.data() + v.size(), p);
    EXPECT_EQ(0, decodeIDBKey(v.data(), v.data() + v.size() - 1, decodedKey));
}

TEST(IDBLevelDBCodingTest, EncodeIDBKeyPath)
{
    const unsigned char kIDBKeyPathTypeCodedByte1 = 0;
    const unsigned char kIDBKeyPathTypeCodedByte2 = 0;
    {
        IDBKeyPath keyPath;
        EXPECT_EQ(keyPath.type(), IDBKeyPath::NullType);
        Vector<char> v = encodeIDBKeyPath(keyPath);
        EXPECT_EQ(v.size(), 3U);
        EXPECT_EQ(v[0], kIDBKeyPathTypeCodedByte1);
        EXPECT_EQ(v[1], kIDBKeyPathTypeCodedByte2);
        EXPECT_EQ(v[2], IDBKeyPath::NullType);
    }

    {
        Vector<String> testCases;
        testCases.append("");
        testCases.append("foo");
        testCases.append("foo.bar");

        for (size_t i = 0; i < testCases.size(); ++i) {
            IDBKeyPath keyPath = IDBKeyPath(testCases[i]);
            Vector<char> v = encodeIDBKeyPath(keyPath);
            EXPECT_EQ(v.size(), encodeStringWithLength(testCases[i]).size() + 3);
            const char* p = v.data();
            const char* limit = v.data() + v.size();
            EXPECT_EQ(*p++, kIDBKeyPathTypeCodedByte1);
            EXPECT_EQ(*p++, kIDBKeyPathTypeCodedByte2);
            EXPECT_EQ(*p++, IDBKeyPath::StringType);
            String string;
            p = decodeStringWithLength(p, limit, string);
            EXPECT_EQ(string, testCases[i]);
            EXPECT_EQ(p, limit);
        }
    }

    {
        Vector<String> testCase;
        testCase.append("");
        testCase.append("foo");
        testCase.append("foo.bar");

        IDBKeyPath keyPath(testCase);
        EXPECT_EQ(keyPath.type(), IDBKeyPath::ArrayType);
        Vector<char> v = encodeIDBKeyPath(keyPath);
        const char* p = v.data();
        const char* limit = v.data() + v.size();
        EXPECT_EQ(*p++, kIDBKeyPathTypeCodedByte1);
        EXPECT_EQ(*p++, kIDBKeyPathTypeCodedByte2);
        EXPECT_EQ(*p++, IDBKeyPath::ArrayType);
        int64_t count;
        p = decodeVarInt(p, limit, count);
        EXPECT_EQ(count, static_cast<int64_t>(testCase.size()));
        for (size_t i = 0; i < static_cast<size_t>(count); ++i) {
            String string;
            p = decodeStringWithLength(p, limit, string);
            EXPECT_EQ(string, testCase[i]);
        }
        EXPECT_EQ(p, limit);
    }
}

TEST(IDBLevelDBCodingTest, DecodeIDBKeyPath)
{
    const unsigned char kIDBKeyPathTypeCodedByte1 = 0;
    const unsigned char kIDBKeyPathTypeCodedByte2 = 0;
    {
        // Legacy encoding of string key paths.
        Vector<String> testCases;
        testCases.append("");
        testCases.append("foo");
        testCases.append("foo.bar");

        for (size_t i = 0; i < testCases.size(); ++i) {
            Vector<char> v = encodeString(testCases[i]);
            IDBKeyPath keyPath = decodeIDBKeyPath(v.data(), v.data() + v.size());
            EXPECT_EQ(keyPath.type(), IDBKeyPath::StringType);
            EXPECT_EQ(testCases[i], keyPath.string());
        }
    }
    {
        Vector<char> v;
        v.append(kIDBKeyPathTypeCodedByte1);
        v.append(kIDBKeyPathTypeCodedByte2);
        v.append(IDBKeyPath::NullType);
        IDBKeyPath keyPath = decodeIDBKeyPath(v.data(), v.data() + v.size());
        EXPECT_EQ(keyPath.type(), IDBKeyPath::NullType);
        EXPECT_TRUE(keyPath.isNull());
    }
    {
        Vector<String> testCases;
        testCases.append("");
        testCases.append("foo");
        testCases.append("foo.bar");

        for (size_t i = 0; i < testCases.size(); ++i) {
            Vector<char> v;
            v.append(kIDBKeyPathTypeCodedByte1);
            v.append(kIDBKeyPathTypeCodedByte2);
            v.append(IDBKeyPath::StringType);
            v.append(encodeStringWithLength(testCases[i]));
            IDBKeyPath keyPath = decodeIDBKeyPath(v.data(), v.data() + v.size());
            EXPECT_EQ(keyPath.type(), IDBKeyPath::StringType);
            EXPECT_EQ(testCases[i], keyPath.string());
        }
    }
    {
        Vector<String> testCase;
        testCase.append("");
        testCase.append("foo");
        testCase.append("foo.bar");

        Vector<char> v;
        v.append(kIDBKeyPathTypeCodedByte1);
        v.append(kIDBKeyPathTypeCodedByte2);
        v.append(IDBKeyPath::ArrayType);
        v.append(encodeVarInt(testCase.size()));
        for (size_t i = 0; i < testCase.size(); ++i)
            v.append(encodeStringWithLength(testCase[i]));
        IDBKeyPath keyPath = decodeIDBKeyPath(v.data(), v.data() + v.size());
        EXPECT_EQ(keyPath.type(), IDBKeyPath::ArrayType);
        EXPECT_EQ(keyPath.array().size(), testCase.size());
        for (size_t i = 0; i < testCase.size(); ++i)
            EXPECT_EQ(keyPath.array()[i], testCase[i]);
    }
}

TEST(IDBLevelDBCodingTest, ExtractAndCompareIDBKeys)
{
    Vector<RefPtr<IDBKey> > keys;

    keys.append(IDBKey::createNumber(-10));
    keys.append(IDBKey::createNumber(0));
    keys.append(IDBKey::createNumber(3.14));

    keys.append(IDBKey::createDate(0));
    keys.append(IDBKey::createDate(100));
    keys.append(IDBKey::createDate(100000));

    keys.append(IDBKey::createString(""));
    keys.append(IDBKey::createString("a"));
    keys.append(IDBKey::createString("b"));
    keys.append(IDBKey::createString("baaa"));
    keys.append(IDBKey::createString("baab"));
    keys.append(IDBKey::createString("c"));

    keys.append(createArrayIDBKey());
    keys.append(createArrayIDBKey(IDBKey::createNumber(0)));
    keys.append(createArrayIDBKey(IDBKey::createNumber(0), IDBKey::createNumber(3.14)));
    keys.append(createArrayIDBKey(IDBKey::createDate(0)));
    keys.append(createArrayIDBKey(IDBKey::createDate(0), IDBKey::createDate(0)));
    keys.append(createArrayIDBKey(IDBKey::createString("")));
    keys.append(createArrayIDBKey(IDBKey::createString(""), IDBKey::createString("a")));
    keys.append(createArrayIDBKey(createArrayIDBKey()));
    keys.append(createArrayIDBKey(createArrayIDBKey(), createArrayIDBKey()));
    keys.append(createArrayIDBKey(createArrayIDBKey(createArrayIDBKey())));
    keys.append(createArrayIDBKey(createArrayIDBKey(createArrayIDBKey(createArrayIDBKey()))));

    for (size_t i = 0; i < keys.size() - 1; ++i) {
        RefPtr<IDBKey> keyA = keys[i];
        RefPtr<IDBKey> keyB = keys[i + 1];

        EXPECT_TRUE(keyA->isLessThan(keyB.get()));

        Vector<char> encodedA = encodeIDBKey(*keyA);
        EXPECT_TRUE(encodedA.size());
        Vector<char> encodedB = encodeIDBKey(*keyB);
        EXPECT_TRUE(encodedB.size());

        Vector<char> extractedA;
        Vector<char> extractedB;

        const char* p = extractEncodedIDBKey(encodedA.data(), encodedA.data() + encodedA.size(), &extractedA);
        EXPECT_EQ(encodedA.data() + encodedA.size(), p);
        EXPECT_EQ(encodedA, extractedA);

        const char* q = extractEncodedIDBKey(encodedB.data(), encodedB.data() + encodedB.size(), &extractedB);
        EXPECT_EQ(encodedB.data() + encodedB.size(), q);
        EXPECT_EQ(encodedB, extractedB);

        EXPECT_LT(compareEncodedIDBKeys(extractedA, extractedB), 0);
        EXPECT_GT(compareEncodedIDBKeys(extractedB, extractedA), 0);
        EXPECT_EQ(compareEncodedIDBKeys(extractedA, extractedA), 0);
        EXPECT_EQ(compareEncodedIDBKeys(extractedB, extractedB), 0);

        EXPECT_EQ(0, extractEncodedIDBKey(encodedA.data(), encodedA.data() + encodedA.size() - 1, &extractedA));
    }
}

TEST(IDBLevelDBCodingTest, ComparisonTest)
{
    Vector<Vector<char> > keys;
    keys.append(SchemaVersionKey::encode());
    keys.append(MaxDatabaseIdKey::encode());
    keys.append(DatabaseFreeListKey::encode(0));
    keys.append(DatabaseFreeListKey::encodeMaxKey());
    keys.append(DatabaseNameKey::encode("", ""));
    keys.append(DatabaseNameKey::encode("", "a"));
    keys.append(DatabaseNameKey::encode("a", "a"));
    keys.append(DatabaseMetaDataKey::encode(1, DatabaseMetaDataKey::OriginName));
    keys.append(ObjectStoreMetaDataKey::encode(1, 1, 0));
    keys.append(ObjectStoreMetaDataKey::encode(1, 1, 1));
    keys.append(ObjectStoreMetaDataKey::encodeMaxKey(1, 1));
    keys.append(ObjectStoreMetaDataKey::encodeMaxKey(1, 2));
    keys.append(ObjectStoreMetaDataKey::encodeMaxKey(1));
    keys.append(IndexMetaDataKey::encode(1, 1, 30, 0));
    keys.append(IndexMetaDataKey::encode(1, 1, 31, 0));
    keys.append(IndexMetaDataKey::encode(1, 1, 31, 1));
    keys.append(IndexMetaDataKey::encodeMaxKey(1, 1, 31));
    keys.append(IndexMetaDataKey::encodeMaxKey(1, 1, 32));
    keys.append(IndexMetaDataKey::encodeMaxKey(1, 1));
    keys.append(IndexMetaDataKey::encodeMaxKey(1, 2));
    keys.append(ObjectStoreFreeListKey::encode(1, 1));
    keys.append(ObjectStoreFreeListKey::encodeMaxKey(1));
    keys.append(IndexFreeListKey::encode(1, 1, MinimumIndexId));
    keys.append(IndexFreeListKey::encodeMaxKey(1, 1));
    keys.append(IndexFreeListKey::encode(1, 2, MinimumIndexId));
    keys.append(IndexFreeListKey::encodeMaxKey(1, 2));
    keys.append(ObjectStoreNamesKey::encode(1, ""));
    keys.append(ObjectStoreNamesKey::encode(1, "a"));
    keys.append(IndexNamesKey::encode(1, 1, ""));
    keys.append(IndexNamesKey::encode(1, 1, "a"));
    keys.append(IndexNamesKey::encode(1, 2, "a"));
    keys.append(ObjectStoreDataKey::encode(1, 1, minIDBKey()));
    keys.append(ObjectStoreDataKey::encode(1, 1, maxIDBKey()));
    keys.append(ExistsEntryKey::encode(1, 1, minIDBKey()));
    keys.append(ExistsEntryKey::encode(1, 1, maxIDBKey()));
    keys.append(IndexDataKey::encode(1, 1, 30, minIDBKey(), minIDBKey(), 0));
    keys.append(IndexDataKey::encode(1, 1, 30, minIDBKey(), minIDBKey(), 1));
    keys.append(IndexDataKey::encode(1, 1, 30, minIDBKey(), maxIDBKey(), 0));
    keys.append(IndexDataKey::encode(1, 1, 30, minIDBKey(), maxIDBKey(), 1));
    keys.append(IndexDataKey::encode(1, 1, 30, maxIDBKey(), minIDBKey(), 0));
    keys.append(IndexDataKey::encode(1, 1, 30, maxIDBKey(), minIDBKey(), 1));
    keys.append(IndexDataKey::encode(1, 1, 30, maxIDBKey(), maxIDBKey(), 0));
    keys.append(IndexDataKey::encode(1, 1, 30, maxIDBKey(), maxIDBKey(), 1));
    keys.append(IndexDataKey::encode(1, 1, 31, minIDBKey(), minIDBKey(), 0));
    keys.append(IndexDataKey::encode(1, 2, 30, minIDBKey(), minIDBKey(), 0));
    keys.append(IndexDataKey::encodeMaxKey(1, 2, INT32_MAX));

    for (size_t i = 0; i < keys.size(); ++i) {
        const LevelDBSlice keyA(keys[i]);
        EXPECT_EQ(compare(keyA, keyA), 0);

        for (size_t j = i + 1; j < keys.size(); ++j) {
            const LevelDBSlice keyB(keys[j]);
            EXPECT_LT(compare(keyA, keyB), 0);
            EXPECT_GT(compare(keyB, keyA), 0);
        }
    }
}

TEST(IDBLevelDBCodingTest, EncodeVarIntVSEncodeByteTest)
{
    Vector<unsigned char> testCases;
    testCases.append(0);
    testCases.append(1);
    testCases.append(127);

    for (size_t i = 0; i < testCases.size(); ++i) {
        unsigned char n = testCases[i];

        Vector<char> vA = encodeByte(n);
        Vector<char> vB = encodeVarInt(static_cast<int64_t>(n));

        EXPECT_EQ(vA.size(), vB.size());
        EXPECT_EQ(*(vA.data()), *(vB.data()));
    }
}

} // namespace

#endif // USE(LEVELDB)
#endif // ENABLE(INDEXED_DATABASE)
