indexed_db_leveldb_coding_unittest.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
6
7#include <limits>
8#include <string>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/strings/string16.h"
13#include "base/strings/string_piece.h"
14#include "base/strings/utf_string_conversions.h"
15#include "content/browser/indexed_db/leveldb/leveldb_slice.h"
16#include "content/common/indexed_db/indexed_db_key.h"
17#include "content/common/indexed_db/indexed_db_key_path.h"
18#include "testing/gtest/include/gtest/gtest.h"
19
20using base::StringPiece;
21using WebKit::WebIDBKey;
22using WebKit::WebIDBKeyPath;
23
24namespace content {
25
26namespace {
27
28static IndexedDBKey CreateArrayIDBKey() {
29  return IndexedDBKey(IndexedDBKey::KeyArray());
30}
31
32static IndexedDBKey CreateArrayIDBKey(const IndexedDBKey& key1) {
33  IndexedDBKey::KeyArray array;
34  array.push_back(key1);
35  return IndexedDBKey(array);
36}
37
38static IndexedDBKey CreateArrayIDBKey(const IndexedDBKey& key1,
39                                      const IndexedDBKey& key2) {
40  IndexedDBKey::KeyArray array;
41  array.push_back(key1);
42  array.push_back(key2);
43  return IndexedDBKey(array);
44}
45
46static std::vector<char> WrappedEncodeByte(char value) {
47  std::vector<char> buffer;
48  EncodeByte(value, &buffer);
49  return buffer;
50}
51
52TEST(IndexedDBLevelDBCodingTest, EncodeByte) {
53  std::vector<char> expected;
54  expected.push_back(0);
55  unsigned char c;
56
57  c = 0;
58  expected[0] = c;
59  EXPECT_EQ(expected, WrappedEncodeByte(c));
60
61  c = 1;
62  expected[0] = c;
63  EXPECT_EQ(expected, WrappedEncodeByte(c));
64
65  c = 255;
66  expected[0] = c;
67  EXPECT_EQ(expected, WrappedEncodeByte(c));
68}
69
70TEST(IndexedDBLevelDBCodingTest, DecodeByte) {
71  std::vector<unsigned char> test_cases;
72  test_cases.push_back(0);
73  test_cases.push_back(1);
74  test_cases.push_back(255);
75
76  for (size_t i = 0; i < test_cases.size(); ++i) {
77    unsigned char n = test_cases[i];
78    std::vector<char> v;
79    EncodeByte(n, &v);
80
81    unsigned char res;
82    ASSERT_GT(v.size(), static_cast<size_t>(0));
83    StringPiece slice(&*v.begin(), v.size());
84    EXPECT_TRUE(DecodeByte(&slice, &res));
85    EXPECT_EQ(n, res);
86    EXPECT_TRUE(slice.empty());
87  }
88
89  {
90    StringPiece slice;
91    unsigned char value;
92    EXPECT_FALSE(DecodeByte(&slice, &value));
93  }
94}
95
96static std::vector<char> WrappedEncodeBool(bool value) {
97  std::vector<char> buffer;
98  EncodeBool(value, &buffer);
99  return buffer;
100}
101
102TEST(IndexedDBLevelDBCodingTest, EncodeBool) {
103  {
104    std::vector<char> expected;
105    expected.push_back(1);
106    EXPECT_EQ(expected, WrappedEncodeBool(true));
107  }
108  {
109    std::vector<char> expected;
110    expected.push_back(0);
111    EXPECT_EQ(expected, WrappedEncodeBool(false));
112  }
113}
114
115static int CompareKeys(const std::vector<char>& a, const std::vector<char>& b) {
116  bool ok;
117  int result = CompareEncodedIDBKeys(a, b, &ok);
118  EXPECT_TRUE(ok);
119  return result;
120}
121
122TEST(IndexedDBLevelDBCodingTest, MaxIDBKey) {
123  std::vector<char> max_key = MaxIDBKey();
124
125  std::vector<char> min_key = MinIDBKey();
126  std::vector<char> array_key;
127  EncodeIDBKey(IndexedDBKey(IndexedDBKey::KeyArray()), &array_key);
128  std::vector<char> string_key;
129  EncodeIDBKey(IndexedDBKey(ASCIIToUTF16("Hello world")), &string_key);
130  std::vector<char> number_key;
131  EncodeIDBKey(IndexedDBKey(3.14, WebIDBKey::NumberType), &number_key);
132  std::vector<char> date_key;
133  EncodeIDBKey(IndexedDBKey(1000000, WebIDBKey::DateType), &date_key);
134
135  EXPECT_GT(CompareKeys(max_key, min_key), 0);
136  EXPECT_GT(CompareKeys(max_key, array_key), 0);
137  EXPECT_GT(CompareKeys(max_key, string_key), 0);
138  EXPECT_GT(CompareKeys(max_key, number_key), 0);
139  EXPECT_GT(CompareKeys(max_key, date_key), 0);
140}
141
142TEST(IndexedDBLevelDBCodingTest, MinIDBKey) {
143  std::vector<char> min_key = MinIDBKey();
144
145  std::vector<char> max_key = MaxIDBKey();
146  std::vector<char> array_key;
147  EncodeIDBKey(IndexedDBKey(IndexedDBKey::KeyArray()), &array_key);
148  std::vector<char> string_key;
149  EncodeIDBKey(IndexedDBKey(ASCIIToUTF16("Hello world")), &string_key);
150  std::vector<char> number_key;
151  EncodeIDBKey(IndexedDBKey(3.14, WebIDBKey::NumberType), &number_key);
152  std::vector<char> date_key;
153  EncodeIDBKey(IndexedDBKey(1000000, WebIDBKey::DateType), &date_key);
154
155  EXPECT_LT(CompareKeys(min_key, max_key), 0);
156  EXPECT_LT(CompareKeys(min_key, array_key), 0);
157  EXPECT_LT(CompareKeys(min_key, string_key), 0);
158  EXPECT_LT(CompareKeys(min_key, number_key), 0);
159  EXPECT_LT(CompareKeys(min_key, date_key), 0);
160}
161
162static std::vector<char> WrappedEncodeInt(int64 value) {
163  std::vector<char> buffer;
164  EncodeInt(value, &buffer);
165  return buffer;
166}
167
168TEST(IndexedDBLevelDBCodingTest, EncodeInt) {
169  EXPECT_EQ(static_cast<size_t>(1), WrappedEncodeInt(0).size());
170  EXPECT_EQ(static_cast<size_t>(1), WrappedEncodeInt(1).size());
171  EXPECT_EQ(static_cast<size_t>(1), WrappedEncodeInt(255).size());
172  EXPECT_EQ(static_cast<size_t>(2), WrappedEncodeInt(256).size());
173  EXPECT_EQ(static_cast<size_t>(4), WrappedEncodeInt(0xffffffff).size());
174#ifdef NDEBUG
175  EXPECT_EQ(static_cast<size_t>(8), WrappedEncodeInt(-1).size());
176#endif
177}
178
179TEST(IndexedDBLevelDBCodingTest, DecodeBool) {
180  {
181    std::vector<char> encoded;
182    encoded.push_back(1);
183    StringPiece slice(&*encoded.begin(), encoded.size());
184    bool value;
185    EXPECT_TRUE(DecodeBool(&slice, &value));
186    EXPECT_TRUE(value);
187    EXPECT_TRUE(slice.empty());
188  }
189  {
190    std::vector<char> encoded;
191    encoded.push_back(0);
192    StringPiece slice(&*encoded.begin(), encoded.size());
193    bool value;
194    EXPECT_TRUE(DecodeBool(&slice, &value));
195    EXPECT_FALSE(value);
196    EXPECT_TRUE(slice.empty());
197  }
198  {
199    StringPiece slice;
200    bool value;
201    EXPECT_FALSE(DecodeBool(&slice, &value));
202  }
203}
204
205TEST(IndexedDBLevelDBCodingTest, DecodeInt) {
206  std::vector<int64> test_cases;
207  test_cases.push_back(0);
208  test_cases.push_back(1);
209  test_cases.push_back(255);
210  test_cases.push_back(256);
211  test_cases.push_back(65535);
212  test_cases.push_back(655536);
213  test_cases.push_back(7711192431755665792ll);
214  test_cases.push_back(0x7fffffffffffffffll);
215#ifdef NDEBUG
216  test_cases.push_back(-3);
217#endif
218
219  for (size_t i = 0; i < test_cases.size(); ++i) {
220    int64 n = test_cases[i];
221    std::vector<char> v = WrappedEncodeInt(n);
222    ASSERT_GT(v.size(), static_cast<size_t>(0));
223    StringPiece slice(&*v.begin(), v.size());
224    int64 value;
225    EXPECT_TRUE(DecodeInt(&slice, &value));
226    EXPECT_EQ(n, value);
227    EXPECT_TRUE(slice.empty());
228
229    // Verify decoding at an offset, to detect unaligned memory access.
230    v.insert(v.begin(), static_cast<size_t>(1), static_cast<char>(0));
231    slice = StringPiece(&*v.begin() + 1, v.size() - 1);
232    EXPECT_TRUE(DecodeInt(&slice, &value));
233    EXPECT_EQ(n, value);
234    EXPECT_TRUE(slice.empty());
235  }
236  {
237    StringPiece slice;
238    int64 value;
239    EXPECT_FALSE(DecodeInt(&slice, &value));
240  }
241}
242
243static std::vector<char> WrappedEncodeVarInt(int64 value) {
244  std::vector<char> buffer;
245  EncodeVarInt(value, &buffer);
246  return buffer;
247}
248
249TEST(IndexedDBLevelDBCodingTest, EncodeVarInt) {
250  EXPECT_EQ(static_cast<size_t>(1), WrappedEncodeVarInt(0).size());
251  EXPECT_EQ(static_cast<size_t>(1), WrappedEncodeVarInt(1).size());
252  EXPECT_EQ(static_cast<size_t>(2), WrappedEncodeVarInt(255).size());
253  EXPECT_EQ(static_cast<size_t>(2), WrappedEncodeVarInt(256).size());
254  EXPECT_EQ(static_cast<size_t>(5), WrappedEncodeVarInt(0xffffffff).size());
255  EXPECT_EQ(static_cast<size_t>(8),
256            WrappedEncodeVarInt(0xfffffffffffffLL).size());
257  EXPECT_EQ(static_cast<size_t>(9),
258            WrappedEncodeVarInt(0x7fffffffffffffffLL).size());
259#ifdef NDEBUG
260  EXPECT_EQ(static_cast<size_t>(10), WrappedEncodeVarInt(-100).size());
261#endif
262}
263
264TEST(IndexedDBLevelDBCodingTest, DecodeVarInt) {
265  std::vector<int64> test_cases;
266  test_cases.push_back(0);
267  test_cases.push_back(1);
268  test_cases.push_back(255);
269  test_cases.push_back(256);
270  test_cases.push_back(65535);
271  test_cases.push_back(655536);
272  test_cases.push_back(7711192431755665792ll);
273  test_cases.push_back(0x7fffffffffffffffll);
274#ifdef NDEBUG
275  test_cases.push_back(-3);
276#endif
277
278  for (size_t i = 0; i < test_cases.size(); ++i) {
279    int64 n = test_cases[i];
280    std::vector<char> v = WrappedEncodeVarInt(n);
281    ASSERT_GT(v.size(), static_cast<size_t>(0));
282    StringPiece slice(&*v.begin(), v.size());
283    int64 res;
284    EXPECT_TRUE(DecodeVarInt(&slice, &res));
285    EXPECT_EQ(n, res);
286    EXPECT_TRUE(slice.empty());
287
288    slice = StringPiece(&*v.begin(), v.size() - 1);
289    EXPECT_FALSE(DecodeVarInt(&slice, &res));
290
291    slice = StringPiece(&*v.begin(), static_cast<size_t>(0));
292    EXPECT_FALSE(DecodeVarInt(&slice, &res));
293
294    // Verify decoding at an offset, to detect unaligned memory access.
295    v.insert(v.begin(), static_cast<size_t>(1), static_cast<char>(0));
296    slice = StringPiece(&*v.begin() + 1, v.size() - 1);
297    EXPECT_TRUE(DecodeVarInt(&slice, &res));
298    EXPECT_EQ(n, res);
299    EXPECT_TRUE(slice.empty());
300  }
301}
302
303static std::vector<char> WrappedEncodeString(string16 value) {
304  std::vector<char> buffer;
305  EncodeString(value, &buffer);
306  return buffer;
307}
308
309TEST(IndexedDBLevelDBCodingTest, EncodeString) {
310  const char16 test_string_a[] = {'f', 'o', 'o', '\0'};
311  const char16 test_string_b[] = {0xdead, 0xbeef, '\0'};
312
313  EXPECT_EQ(static_cast<size_t>(0),
314            WrappedEncodeString(ASCIIToUTF16("")).size());
315  EXPECT_EQ(static_cast<size_t>(2),
316            WrappedEncodeString(ASCIIToUTF16("a")).size());
317  EXPECT_EQ(static_cast<size_t>(6),
318            WrappedEncodeString(ASCIIToUTF16("foo")).size());
319  EXPECT_EQ(static_cast<size_t>(6),
320            WrappedEncodeString(string16(test_string_a)).size());
321  EXPECT_EQ(static_cast<size_t>(4),
322            WrappedEncodeString(string16(test_string_b)).size());
323}
324
325TEST(IndexedDBLevelDBCodingTest, DecodeString) {
326  const char16 test_string_a[] = {'f', 'o', 'o', '\0'};
327  const char16 test_string_b[] = {0xdead, 0xbeef, '\0'};
328
329  std::vector<string16> test_cases;
330  test_cases.push_back(string16());
331  test_cases.push_back(ASCIIToUTF16("a"));
332  test_cases.push_back(ASCIIToUTF16("foo"));
333  test_cases.push_back(test_string_a);
334  test_cases.push_back(test_string_b);
335
336  for (size_t i = 0; i < test_cases.size(); ++i) {
337    const string16& test_case = test_cases[i];
338    std::vector<char> v = WrappedEncodeString(test_case);
339
340    StringPiece slice;
341    if (v.size()) {
342      slice = StringPiece(&*v.begin(), v.size());
343    }
344
345    string16 result;
346    EXPECT_TRUE(DecodeString(&slice, &result));
347    EXPECT_EQ(test_case, result);
348    EXPECT_TRUE(slice.empty());
349
350    // Verify decoding at an offset, to detect unaligned memory access.
351    v.insert(v.begin(), static_cast<size_t>(1), static_cast<char>(0));
352    slice = StringPiece(&*v.begin() + 1, v.size() - 1);
353    EXPECT_TRUE(DecodeString(&slice, &result));
354    EXPECT_EQ(test_case, result);
355    EXPECT_TRUE(slice.empty());
356  }
357}
358
359static std::vector<char> WrappedEncodeStringWithLength(string16 value) {
360  std::vector<char> buffer;
361  EncodeStringWithLength(value, &buffer);
362  return buffer;
363}
364
365TEST(IndexedDBLevelDBCodingTest, EncodeStringWithLength) {
366  const char16 test_string_a[] = {'f', 'o', 'o', '\0'};
367  const char16 test_string_b[] = {0xdead, 0xbeef, '\0'};
368
369  EXPECT_EQ(static_cast<size_t>(1),
370            WrappedEncodeStringWithLength(string16()).size());
371  EXPECT_EQ(static_cast<size_t>(3),
372            WrappedEncodeStringWithLength(ASCIIToUTF16("a")).size());
373  EXPECT_EQ(static_cast<size_t>(7),
374            WrappedEncodeStringWithLength(string16(test_string_a)).size());
375  EXPECT_EQ(static_cast<size_t>(5),
376            WrappedEncodeStringWithLength(string16(test_string_b)).size());
377}
378
379TEST(IndexedDBLevelDBCodingTest, DecodeStringWithLength) {
380  const char16 test_string_a[] = {'f', 'o', 'o', '\0'};
381  const char16 test_string_b[] = {0xdead, 0xbeef, '\0'};
382
383  const int kLongStringLen = 1234;
384  char16 long_string[kLongStringLen + 1];
385  for (int i = 0; i < kLongStringLen; ++i)
386    long_string[i] = i;
387  long_string[kLongStringLen] = 0;
388
389  std::vector<string16> test_cases;
390  test_cases.push_back(ASCIIToUTF16(""));
391  test_cases.push_back(ASCIIToUTF16("a"));
392  test_cases.push_back(ASCIIToUTF16("foo"));
393  test_cases.push_back(string16(test_string_a));
394  test_cases.push_back(string16(test_string_b));
395  test_cases.push_back(string16(long_string));
396
397  for (size_t i = 0; i < test_cases.size(); ++i) {
398    string16 s = test_cases[i];
399    std::vector<char> v = WrappedEncodeStringWithLength(s);
400    ASSERT_GT(v.size(), static_cast<size_t>(0));
401    StringPiece slice(&*v.begin(), v.size());
402    string16 res;
403    EXPECT_TRUE(DecodeStringWithLength(&slice, &res));
404    EXPECT_EQ(s, res);
405    EXPECT_TRUE(slice.empty());
406
407    slice = StringPiece(&*v.begin(), v.size() - 1);
408    EXPECT_FALSE(DecodeStringWithLength(&slice, &res));
409
410    slice = StringPiece(&*v.begin(), static_cast<size_t>(0));
411    EXPECT_FALSE(DecodeStringWithLength(&slice, &res));
412
413    // Verify decoding at an offset, to detect unaligned memory access.
414    v.insert(v.begin(), static_cast<size_t>(1), static_cast<char>(0));
415    slice = StringPiece(&*v.begin() + 1, v.size() - 1);
416    EXPECT_TRUE(DecodeStringWithLength(&slice, &res));
417    EXPECT_EQ(s, res);
418    EXPECT_TRUE(slice.empty());
419  }
420}
421
422static int CompareStrings(const std::vector<char>& p,
423                          const std::vector<char>& q) {
424  bool ok;
425  DCHECK(!p.empty());
426  DCHECK(!q.empty());
427  StringPiece slice_p(&*p.begin(), p.size());
428  StringPiece slice_q(&*q.begin(), q.size());
429  int result = CompareEncodedStringsWithLength(&slice_p, &slice_q, &ok);
430  EXPECT_TRUE(ok);
431  EXPECT_TRUE(slice_p.empty());
432  EXPECT_TRUE(slice_q.empty());
433  return result;
434}
435
436TEST(IndexedDBLevelDBCodingTest, CompareEncodedStringsWithLength) {
437  const char16 test_string_a[] = {0x1000, 0x1000, '\0'};
438  const char16 test_string_b[] = {0x1000, 0x1000, 0x1000, '\0'};
439  const char16 test_string_c[] = {0x1000, 0x1000, 0x1001, '\0'};
440  const char16 test_string_d[] = {0x1001, 0x1000, 0x1000, '\0'};
441  const char16 test_string_e[] = {0xd834, 0xdd1e, '\0'};
442  const char16 test_string_f[] = {0xfffd, '\0'};
443
444  std::vector<string16> test_cases;
445  test_cases.push_back(ASCIIToUTF16(""));
446  test_cases.push_back(ASCIIToUTF16("a"));
447  test_cases.push_back(ASCIIToUTF16("b"));
448  test_cases.push_back(ASCIIToUTF16("baaa"));
449  test_cases.push_back(ASCIIToUTF16("baab"));
450  test_cases.push_back(ASCIIToUTF16("c"));
451  test_cases.push_back(string16(test_string_a));
452  test_cases.push_back(string16(test_string_b));
453  test_cases.push_back(string16(test_string_c));
454  test_cases.push_back(string16(test_string_d));
455  test_cases.push_back(string16(test_string_e));
456  test_cases.push_back(string16(test_string_f));
457
458  for (size_t i = 0; i < test_cases.size() - 1; ++i) {
459    string16 a = test_cases[i];
460    string16 b = test_cases[i + 1];
461
462    EXPECT_LT(a.compare(b), 0);
463    EXPECT_GT(b.compare(a), 0);
464    EXPECT_EQ(a.compare(a), 0);
465    EXPECT_EQ(b.compare(b), 0);
466
467    std::vector<char> encoded_a = WrappedEncodeStringWithLength(a);
468    EXPECT_TRUE(encoded_a.size());
469    std::vector<char> encoded_b = WrappedEncodeStringWithLength(b);
470    EXPECT_TRUE(encoded_a.size());
471
472    EXPECT_LT(CompareStrings(encoded_a, encoded_b), 0);
473    EXPECT_GT(CompareStrings(encoded_b, encoded_a), 0);
474    EXPECT_EQ(CompareStrings(encoded_a, encoded_a), 0);
475    EXPECT_EQ(CompareStrings(encoded_b, encoded_b), 0);
476  }
477}
478
479static std::vector<char> WrappedEncodeDouble(double value) {
480  std::vector<char> buffer;
481  EncodeDouble(value, &buffer);
482  return buffer;
483}
484
485TEST(IndexedDBLevelDBCodingTest, EncodeDouble) {
486  EXPECT_EQ(static_cast<size_t>(8), WrappedEncodeDouble(0).size());
487  EXPECT_EQ(static_cast<size_t>(8), WrappedEncodeDouble(3.14).size());
488}
489
490TEST(IndexedDBLevelDBCodingTest, DecodeDouble) {
491  std::vector<double> test_cases;
492  test_cases.push_back(3.14);
493  test_cases.push_back(-3.14);
494
495  for (size_t i = 0; i < test_cases.size(); ++i) {
496    double value = test_cases[i];
497    std::vector<char> v = WrappedEncodeDouble(value);
498    ASSERT_GT(v.size(), static_cast<size_t>(0));
499    StringPiece slice(&*v.begin(), v.size());
500    double result;
501    EXPECT_TRUE(DecodeDouble(&slice, &result));
502    EXPECT_EQ(value, result);
503    EXPECT_TRUE(slice.empty());
504
505    slice = StringPiece(&*v.begin(), v.size() - 1);
506    EXPECT_FALSE(DecodeDouble(&slice, &result));
507
508    slice = StringPiece(&*v.begin(), static_cast<size_t>(0));
509    EXPECT_FALSE(DecodeDouble(&slice, &result));
510
511    // Verify decoding at an offset, to detect unaligned memory access.
512    v.insert(v.begin(), static_cast<size_t>(1), static_cast<char>(0));
513    slice = StringPiece(&*v.begin() + 1, v.size() - 1);
514    EXPECT_TRUE(DecodeDouble(&slice, &result));
515    EXPECT_EQ(value, result);
516    EXPECT_TRUE(slice.empty());
517  }
518}
519
520TEST(IndexedDBLevelDBCodingTest, EncodeDecodeIDBKey) {
521  IndexedDBKey expected_key;
522  scoped_ptr<IndexedDBKey> decoded_key;
523  std::vector<char> v;
524  StringPiece slice;
525
526  std::vector<IndexedDBKey> test_cases;
527  test_cases.push_back(IndexedDBKey(1234, WebIDBKey::NumberType));
528  test_cases.push_back(IndexedDBKey(7890, WebIDBKey::DateType));
529  test_cases.push_back(IndexedDBKey(ASCIIToUTF16("Hello World!")));
530  test_cases.push_back(IndexedDBKey(IndexedDBKey::KeyArray()));
531
532  IndexedDBKey::KeyArray array;
533  array.push_back(IndexedDBKey(1234, WebIDBKey::NumberType));
534  array.push_back(IndexedDBKey(7890, WebIDBKey::DateType));
535  array.push_back(IndexedDBKey(ASCIIToUTF16("Hello World!")));
536  array.push_back(IndexedDBKey(IndexedDBKey::KeyArray()));
537  test_cases.push_back(IndexedDBKey(array));
538
539  for (size_t i = 0; i < test_cases.size(); ++i) {
540    expected_key = test_cases[i];
541    v.clear();
542    EncodeIDBKey(expected_key, &v);
543    slice = StringPiece(&*v.begin(), v.size());
544    EXPECT_TRUE(DecodeIDBKey(&slice, &decoded_key));
545    EXPECT_TRUE(decoded_key->IsEqual(expected_key));
546    EXPECT_TRUE(slice.empty());
547
548    slice = StringPiece(&*v.begin(), v.size() - 1);
549    EXPECT_FALSE(DecodeIDBKey(&slice, &decoded_key));
550
551    slice = StringPiece(&*v.begin(), static_cast<size_t>(0));
552    EXPECT_FALSE(DecodeIDBKey(&slice, &decoded_key));
553  }
554}
555
556static std::vector<char> WrappedEncodeIDBKeyPath(
557    const IndexedDBKeyPath& value) {
558  std::vector<char> buffer;
559  EncodeIDBKeyPath(value, &buffer);
560  return buffer;
561}
562
563TEST(IndexedDBLevelDBCodingTest, EncodeDecodeIDBKeyPath) {
564  std::vector<IndexedDBKeyPath> key_paths;
565  std::vector<std::vector<char> > encoded_paths;
566
567  {
568    key_paths.push_back(IndexedDBKeyPath());
569    char expected[] = {0, 0,  // Header
570                       0      // Type is null
571    };
572    encoded_paths.push_back(
573        std::vector<char>(expected, expected + arraysize(expected)));
574  }
575
576  {
577    key_paths.push_back(IndexedDBKeyPath(string16()));
578    char expected[] = {0, 0,  // Header
579                       1,     // Type is string
580                       0      // Length is 0
581    };
582    encoded_paths.push_back(
583        std::vector<char>(expected, expected + arraysize(expected)));
584  }
585
586  {
587    key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo")));
588    char expected[] = {0, 0,                      // Header
589                       1,                         // Type is string
590                       3, 0, 'f', 0, 'o', 0, 'o'  // String length 3, UTF-16BE
591    };
592    encoded_paths.push_back(
593        std::vector<char>(expected, expected + arraysize(expected)));
594  }
595
596  {
597    key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo.bar")));
598    char expected[] = {0, 0,  // Header
599                       1,     // Type is string
600                       7, 0, 'f', 0, 'o', 0, 'o', 0, '.', 0, 'b', 0, 'a', 0,
601                       'r'  // String length 7, UTF-16BE
602    };
603    encoded_paths.push_back(
604        std::vector<char>(expected, expected + arraysize(expected)));
605  }
606
607  {
608    std::vector<string16> array;
609    array.push_back(string16());
610    array.push_back(ASCIIToUTF16("foo"));
611    array.push_back(ASCIIToUTF16("foo.bar"));
612
613    key_paths.push_back(IndexedDBKeyPath(array));
614    char expected[] = {0, 0,                       // Header
615                       2, 3,                       // Type is array, length is 3
616                       0,                          // Member 1 (String length 0)
617                       3, 0, 'f', 0, 'o', 0, 'o',  // Member 2 (String length 3)
618                       7, 0, 'f', 0, 'o', 0, 'o', 0, '.', 0, 'b', 0, 'a', 0,
619                       'r'  // Member 3 (String length 7)
620    };
621    encoded_paths.push_back(
622        std::vector<char>(expected, expected + arraysize(expected)));
623  }
624
625  ASSERT_EQ(key_paths.size(), encoded_paths.size());
626  for (size_t i = 0; i < key_paths.size(); ++i) {
627    IndexedDBKeyPath key_path = key_paths[i];
628    std::vector<char> encoded = encoded_paths[i];
629
630    std::vector<char> v = WrappedEncodeIDBKeyPath(key_path);
631    EXPECT_EQ(encoded, v);
632
633    StringPiece slice(&*encoded.begin(), encoded.size());
634    IndexedDBKeyPath decoded;
635    EXPECT_TRUE(DecodeIDBKeyPath(&slice, &decoded));
636    EXPECT_EQ(key_path, decoded);
637    EXPECT_TRUE(slice.empty());
638  }
639}
640
641TEST(IndexedDBLevelDBCodingTest, DecodeLegacyIDBKeyPath) {
642  // Legacy encoding of string key paths.
643  std::vector<IndexedDBKeyPath> key_paths;
644  std::vector<std::string> encoded_paths;
645
646  {
647    key_paths.push_back(IndexedDBKeyPath(string16()));
648    encoded_paths.push_back(std::string());
649  }
650  {
651    key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo")));
652    char expected[] = {0, 'f', 0, 'o', 0, 'o'};
653    encoded_paths.push_back(std::string(expected, arraysize(expected)));
654  }
655  {
656    key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo.bar")));
657    char expected[] = {0, 'f', 0, 'o', 0, 'o', 0, '.', 0, 'b', 0, 'a', 0, 'r'};
658    encoded_paths.push_back(std::string(expected, arraysize(expected)));
659  }
660
661  ASSERT_EQ(key_paths.size(), encoded_paths.size());
662  for (size_t i = 0; i < key_paths.size(); ++i) {
663    IndexedDBKeyPath key_path = key_paths[i];
664    std::string encoded = encoded_paths[i];
665
666    StringPiece slice(encoded);
667    IndexedDBKeyPath decoded;
668    EXPECT_TRUE(DecodeIDBKeyPath(&slice, &decoded));
669    EXPECT_EQ(key_path, decoded);
670    EXPECT_TRUE(slice.empty());
671  }
672}
673
674TEST(IndexedDBLevelDBCodingTest, ExtractAndCompareIDBKeys) {
675  std::vector<IndexedDBKey> keys;
676
677  keys.push_back(IndexedDBKey(-10, WebIDBKey::NumberType));
678  keys.push_back(IndexedDBKey(0, WebIDBKey::NumberType));
679  keys.push_back(IndexedDBKey(3.14, WebIDBKey::NumberType));
680
681  keys.push_back(IndexedDBKey(0, WebIDBKey::DateType));
682  keys.push_back(IndexedDBKey(100, WebIDBKey::DateType));
683  keys.push_back(IndexedDBKey(100000, WebIDBKey::DateType));
684
685  keys.push_back(IndexedDBKey(ASCIIToUTF16("")));
686  keys.push_back(IndexedDBKey(ASCIIToUTF16("a")));
687  keys.push_back(IndexedDBKey(ASCIIToUTF16("b")));
688  keys.push_back(IndexedDBKey(ASCIIToUTF16("baaa")));
689  keys.push_back(IndexedDBKey(ASCIIToUTF16("baab")));
690  keys.push_back(IndexedDBKey(ASCIIToUTF16("c")));
691
692  keys.push_back(CreateArrayIDBKey());
693  keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKey::NumberType)));
694  keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKey::NumberType),
695                                   IndexedDBKey(3.14, WebIDBKey::NumberType)));
696  keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKey::DateType)));
697  keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKey::DateType),
698                                   IndexedDBKey(0, WebIDBKey::DateType)));
699  keys.push_back(CreateArrayIDBKey(IndexedDBKey(ASCIIToUTF16(""))));
700  keys.push_back(CreateArrayIDBKey(IndexedDBKey(ASCIIToUTF16("")),
701                                   IndexedDBKey(ASCIIToUTF16("a"))));
702  keys.push_back(CreateArrayIDBKey(CreateArrayIDBKey()));
703  keys.push_back(CreateArrayIDBKey(CreateArrayIDBKey(), CreateArrayIDBKey()));
704  keys.push_back(CreateArrayIDBKey(CreateArrayIDBKey(CreateArrayIDBKey())));
705  keys.push_back(CreateArrayIDBKey(
706      CreateArrayIDBKey(CreateArrayIDBKey(CreateArrayIDBKey()))));
707
708  for (size_t i = 0; i < keys.size() - 1; ++i) {
709    const IndexedDBKey& key_a = keys[i];
710    const IndexedDBKey& key_b = keys[i + 1];
711
712    EXPECT_TRUE(key_a.IsLessThan(key_b));
713
714    std::vector<char> encoded_a;
715    EncodeIDBKey(key_a, &encoded_a);
716    EXPECT_TRUE(encoded_a.size());
717    std::vector<char> encoded_b;
718    EncodeIDBKey(key_b, &encoded_b);
719    EXPECT_TRUE(encoded_b.size());
720
721    std::vector<char> extracted_a;
722    std::vector<char> extracted_b;
723    StringPiece slice;
724
725    slice = StringPiece(&*encoded_a.begin(), encoded_a.size());
726    EXPECT_TRUE(ExtractEncodedIDBKey(&slice, &extracted_a));
727    EXPECT_TRUE(slice.empty());
728    EXPECT_EQ(encoded_a, extracted_a);
729
730    slice = StringPiece(&*encoded_b.begin(), encoded_b.size());
731    EXPECT_TRUE(ExtractEncodedIDBKey(&slice, &extracted_b));
732    EXPECT_TRUE(slice.empty());
733    EXPECT_EQ(encoded_b, extracted_b);
734
735    EXPECT_LT(CompareKeys(extracted_a, extracted_b), 0);
736    EXPECT_GT(CompareKeys(extracted_b, extracted_a), 0);
737    EXPECT_EQ(CompareKeys(extracted_a, extracted_a), 0);
738    EXPECT_EQ(CompareKeys(extracted_b, extracted_b), 0);
739
740    slice = StringPiece(&*encoded_a.begin(), encoded_a.size() - 1);
741    EXPECT_FALSE(ExtractEncodedIDBKey(&slice, &extracted_a));
742  }
743}
744
745TEST(IndexedDBLevelDBCodingTest, ComparisonTest) {
746  std::vector<std::vector<char> > keys;
747  keys.push_back(SchemaVersionKey::Encode());
748  keys.push_back(MaxDatabaseIdKey::Encode());
749  keys.push_back(DatabaseFreeListKey::Encode(0));
750  keys.push_back(DatabaseFreeListKey::EncodeMaxKey());
751  keys.push_back(DatabaseNameKey::Encode("", ASCIIToUTF16("")));
752  keys.push_back(DatabaseNameKey::Encode("", ASCIIToUTF16("a")));
753  keys.push_back(DatabaseNameKey::Encode("a", ASCIIToUTF16("a")));
754  keys.push_back(
755      DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::ORIGIN_NAME));
756  keys.push_back(
757      DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::DATABASE_NAME));
758  keys.push_back(
759      DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::USER_VERSION));
760  keys.push_back(
761      DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID));
762  keys.push_back(
763      DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::USER_INT_VERSION));
764  keys.push_back(
765      ObjectStoreMetaDataKey::Encode(1, 1, ObjectStoreMetaDataKey::NAME));
766  keys.push_back(
767      ObjectStoreMetaDataKey::Encode(1, 1, ObjectStoreMetaDataKey::KEY_PATH));
768  keys.push_back(ObjectStoreMetaDataKey::Encode(
769      1, 1, ObjectStoreMetaDataKey::AUTO_INCREMENT));
770  keys.push_back(
771      ObjectStoreMetaDataKey::Encode(1, 1, ObjectStoreMetaDataKey::EVICTABLE));
772  keys.push_back(ObjectStoreMetaDataKey::Encode(
773      1, 1, ObjectStoreMetaDataKey::LAST_VERSION));
774  keys.push_back(ObjectStoreMetaDataKey::Encode(
775      1, 1, ObjectStoreMetaDataKey::MAX_INDEX_ID));
776  keys.push_back(ObjectStoreMetaDataKey::Encode(
777      1, 1, ObjectStoreMetaDataKey::HAS_KEY_PATH));
778  keys.push_back(ObjectStoreMetaDataKey::Encode(
779      1, 1, ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER));
780  keys.push_back(ObjectStoreMetaDataKey::EncodeMaxKey(1, 1));
781  keys.push_back(ObjectStoreMetaDataKey::EncodeMaxKey(1, 2));
782  keys.push_back(ObjectStoreMetaDataKey::EncodeMaxKey(1));
783  keys.push_back(IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::NAME));
784  keys.push_back(IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::UNIQUE));
785  keys.push_back(
786      IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::KEY_PATH));
787  keys.push_back(
788      IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::MULTI_ENTRY));
789  keys.push_back(IndexMetaDataKey::Encode(1, 1, 31, 0));
790  keys.push_back(IndexMetaDataKey::Encode(1, 1, 31, 1));
791  keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 1, 31));
792  keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 1, 32));
793  keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 1));
794  keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 2));
795  keys.push_back(ObjectStoreFreeListKey::Encode(1, 1));
796  keys.push_back(ObjectStoreFreeListKey::EncodeMaxKey(1));
797  keys.push_back(IndexFreeListKey::Encode(1, 1, kMinimumIndexId));
798  keys.push_back(IndexFreeListKey::EncodeMaxKey(1, 1));
799  keys.push_back(IndexFreeListKey::Encode(1, 2, kMinimumIndexId));
800  keys.push_back(IndexFreeListKey::EncodeMaxKey(1, 2));
801  keys.push_back(ObjectStoreNamesKey::Encode(1, ASCIIToUTF16("")));
802  keys.push_back(ObjectStoreNamesKey::Encode(1, ASCIIToUTF16("a")));
803  keys.push_back(IndexNamesKey::Encode(1, 1, ASCIIToUTF16("")));
804  keys.push_back(IndexNamesKey::Encode(1, 1, ASCIIToUTF16("a")));
805  keys.push_back(IndexNamesKey::Encode(1, 2, ASCIIToUTF16("a")));
806  keys.push_back(ObjectStoreDataKey::Encode(1, 1, MinIDBKey()));
807  keys.push_back(ObjectStoreDataKey::Encode(1, 1, MaxIDBKey()));
808  keys.push_back(ExistsEntryKey::Encode(1, 1, MinIDBKey()));
809  keys.push_back(ExistsEntryKey::Encode(1, 1, MaxIDBKey()));
810  keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MinIDBKey(), 0));
811  keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MinIDBKey(), 1));
812  keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MaxIDBKey(), 0));
813  keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MaxIDBKey(), 1));
814  keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MinIDBKey(), 0));
815  keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MinIDBKey(), 1));
816  keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MaxIDBKey(), 0));
817  keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MaxIDBKey(), 1));
818  keys.push_back(IndexDataKey::Encode(1, 1, 31, MinIDBKey(), MinIDBKey(), 0));
819  keys.push_back(IndexDataKey::Encode(1, 2, 30, MinIDBKey(), MinIDBKey(), 0));
820  keys.push_back(
821      IndexDataKey::EncodeMaxKey(1, 2, std::numeric_limits<int32>::max() - 1));
822
823  for (size_t i = 0; i < keys.size(); ++i) {
824    const LevelDBSlice key_a(keys[i]);
825    EXPECT_EQ(Compare(key_a, key_a, false), 0);
826
827    for (size_t j = i + 1; j < keys.size(); ++j) {
828      const LevelDBSlice key_b(keys[j]);
829      EXPECT_LT(Compare(key_a, key_b, false), 0);
830      EXPECT_GT(Compare(key_b, key_a, false), 0);
831    }
832  }
833}
834
835TEST(IndexedDBLevelDBCodingTest, EncodeVarIntVSEncodeByteTest) {
836  std::vector<unsigned char> test_cases;
837  test_cases.push_back(0);
838  test_cases.push_back(1);
839  test_cases.push_back(127);
840
841  for (size_t i = 0; i < test_cases.size(); ++i) {
842    unsigned char n = test_cases[i];
843
844    std::vector<char> vA = WrappedEncodeByte(n);
845    std::vector<char> vB = WrappedEncodeVarInt(static_cast<int64>(n));
846
847    EXPECT_EQ(vA.size(), vB.size());
848    EXPECT_EQ(*vA.begin(), *vB.begin());
849  }
850}
851
852}  // namespace
853
854}  // namespace content
855