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