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.rbegin() + 1, res); | |
73 EXPECT_EQ(n, res); | |
74 EXPECT_EQ(&*v.rbegin() + 1, 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.rbegin() + 1)); | |
154 } | |
155 { | |
156 std::vector<char> encoded; | |
157 encoded.push_back(0); | |
158 EXPECT_FALSE(DecodeBool(&*encoded.begin(), &*encoded.rbegin() + 1)); | |
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.rbegin() + 1)); | |
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.rbegin() + 1, res); | |
216 EXPECT_EQ(n, res); | |
217 EXPECT_EQ(&*v.rbegin() + 1, p); | |
218 | |
219 p = DecodeVarInt(&*v.begin(), &*v.rbegin(), 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.rbegin() + 1)); | |
246 | |
247 v = EncodeString(ASCIIToUTF16("a")); | |
248 EXPECT_EQ(ASCIIToUTF16("a"), DecodeString(&*v.begin(), &*v.rbegin() + 1)); | |
249 | |
250 v = EncodeString(ASCIIToUTF16("foo")); | |
251 EXPECT_EQ(ASCIIToUTF16("foo"), DecodeString(&*v.begin(), &*v.rbegin() + 1)); | |
252 | |
253 v = EncodeString(string16(test_string_a)); | |
254 EXPECT_EQ(string16(test_string_a), | |
255 DecodeString(&*v.begin(), &*v.rbegin() + 1)); | |
256 | |
257 v = EncodeString(string16(test_string_b)); | |
258 EXPECT_EQ(string16(test_string_b), | |
259 DecodeString(&*v.begin(), &*v.rbegin() + 1)); | |
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.rbegin() + 1, res); | |
298 EXPECT_EQ(s, res); | |
299 EXPECT_EQ(&*v.rbegin() + 1, p); | |
300 | |
301 EXPECT_EQ(0, DecodeStringWithLength(&*v.begin(), &*v.rbegin(), res)); | |
302 EXPECT_EQ(0, DecodeStringWithLength(&*v.begin(), &*v.begin(), res)); | |
303 } | |
304 } | |
305 | |
306 static int CompareStrings(const char* p, | |
307 const char* limit_p, | |
308 const char* q, | |
309 const char* limit_q) { | |
310 bool ok; | |
311 int result = CompareEncodedStringsWithLength(p, limit_p, q, limit_q, ok); | |
312 EXPECT_TRUE(ok); | |
313 EXPECT_EQ(p, limit_p); | |
314 EXPECT_EQ(q, limit_q); | |
315 return result; | |
316 } | |
317 | |
318 TEST(IndexedDBLevelDBCodingTest, CompareEncodedStringsWithLength) { | |
319 const char16 test_string_a[] = {0x1000, 0x1000, '\0'}; | |
320 const char16 test_string_b[] = {0x1000, 0x1000, 0x1000, '\0'}; | |
321 const char16 test_string_c[] = {0x1000, 0x1000, 0x1001, '\0'}; | |
322 const char16 test_string_d[] = {0x1001, 0x1000, 0x1000, '\0'}; | |
323 const char16 test_string_e[] = {0xd834, 0xdd1e, '\0'}; | |
324 const char16 test_string_f[] = {0xfffd, '\0'}; | |
325 | |
326 std::vector<string16> test_cases; | |
327 test_cases.push_back(ASCIIToUTF16("")); | |
328 test_cases.push_back(ASCIIToUTF16("a")); | |
329 test_cases.push_back(ASCIIToUTF16("b")); | |
330 test_cases.push_back(ASCIIToUTF16("baaa")); | |
331 test_cases.push_back(ASCIIToUTF16("baab")); | |
332 test_cases.push_back(ASCIIToUTF16("c")); | |
333 test_cases.push_back(string16(test_string_a)); | |
334 test_cases.push_back(string16(test_string_b)); | |
335 test_cases.push_back(string16(test_string_c)); | |
336 test_cases.push_back(string16(test_string_d)); | |
337 test_cases.push_back(string16(test_string_e)); | |
338 test_cases.push_back(string16(test_string_f)); | |
339 | |
340 for (size_t i = 0; i < test_cases.size() - 1; ++i) { | |
341 string16 a = test_cases[i]; | |
342 string16 b = test_cases[i + 1]; | |
343 | |
344 EXPECT_LT(a.compare(b), 0); | |
345 EXPECT_GT(b.compare(a), 0); | |
346 EXPECT_EQ(a.compare(a), 0); | |
347 EXPECT_EQ(b.compare(b), 0); | |
348 | |
349 std::vector<char> encoded_a = EncodeStringWithLength(a); | |
350 EXPECT_TRUE(encoded_a.size()); | |
351 std::vector<char> encoded_b = EncodeStringWithLength(b); | |
352 EXPECT_TRUE(encoded_a.size()); | |
353 | |
354 const char* p = &*encoded_a.begin(); | |
355 const char* limit_p = &*encoded_a.rbegin() + 1; | |
356 const char* q = &*encoded_b.begin(); | |
357 const char* limit_q = &*encoded_b.rbegin() + 1; | |
358 | |
359 EXPECT_LT(CompareStrings(p, limit_p, q, limit_q), 0); | |
360 EXPECT_GT(CompareStrings(q, limit_q, p, limit_p), 0); | |
361 EXPECT_EQ(CompareStrings(p, limit_p, p, limit_p), 0); | |
362 EXPECT_EQ(CompareStrings(q, limit_q, q, limit_q), 0); | |
363 } | |
364 } | |
365 | |
366 TEST(IndexedDBLevelDBCodingTest, EncodeDouble) { | |
367 EXPECT_EQ(static_cast<size_t>(8), EncodeDouble(0).size()); | |
368 EXPECT_EQ(static_cast<size_t>(8), EncodeDouble(3.14).size()); | |
369 } | |
370 | |
371 TEST(IndexedDBLevelDBCodingTest, DecodeDouble) { | |
372 std::vector<char> v; | |
373 const char* p; | |
374 double d; | |
375 | |
376 v = EncodeDouble(3.14); | |
377 p = DecodeDouble(&*v.begin(), &*v.rbegin() + 1, &d); | |
378 EXPECT_EQ(3.14, d); | |
379 EXPECT_EQ(&*v.rbegin() + 1, p); | |
380 | |
381 v = EncodeDouble(-3.14); | |
382 p = DecodeDouble(&*v.begin(), &*v.rbegin() + 1, &d); | |
383 EXPECT_EQ(-3.14, d); | |
384 EXPECT_EQ(&*v.rbegin() + 1, p); | |
385 | |
386 v = EncodeDouble(3.14); | |
387 p = DecodeDouble(&*v.begin(), &*v.rbegin(), &d); | |
388 EXPECT_EQ(0, p); | |
389 } | |
390 | |
391 TEST(IndexedDBLevelDBCodingTest, EncodeDecodeIDBKey) { | |
392 IndexedDBKey expected_key; | |
393 scoped_ptr<IndexedDBKey> decoded_key; | |
394 std::vector<char> v; | |
395 const char* p; | |
396 | |
397 expected_key = IndexedDBKey(1234, WebIDBKey::NumberType); | |
398 v = EncodeIDBKey(expected_key); | |
399 p = DecodeIDBKey(&*v.begin(), &*v.rbegin() + 1, &decoded_key); | |
400 EXPECT_TRUE(decoded_key->IsEqual(expected_key)); | |
401 EXPECT_EQ(&*v.rbegin() + 1, p); | |
402 EXPECT_EQ(0, DecodeIDBKey(&*v.begin(), &*v.rbegin(), &decoded_key)); | |
403 | |
404 expected_key = IndexedDBKey(ASCIIToUTF16("Hello World!")); | |
405 v = EncodeIDBKey(expected_key); | |
406 p = DecodeIDBKey(&*v.begin(), &*v.rbegin() + 1, &decoded_key); | |
407 EXPECT_TRUE(decoded_key->IsEqual(expected_key)); | |
408 EXPECT_EQ(&*v.rbegin() + 1, p); | |
409 EXPECT_EQ(0, DecodeIDBKey(&*v.begin(), &*v.rbegin(), &decoded_key)); | |
410 | |
411 expected_key = IndexedDBKey(IndexedDBKey::KeyArray()); | |
412 v = EncodeIDBKey(expected_key); | |
413 p = DecodeIDBKey(&*v.begin(), &*v.rbegin() + 1, &decoded_key); | |
414 EXPECT_TRUE(decoded_key->IsEqual(expected_key)); | |
415 EXPECT_EQ(&*v.rbegin() + 1, p); | |
416 EXPECT_EQ(0, DecodeIDBKey(&*v.begin(), &*v.rbegin(), &decoded_key)); | |
417 | |
418 expected_key = IndexedDBKey(7890, WebIDBKey::DateType); | |
419 v = EncodeIDBKey(expected_key); | |
420 p = DecodeIDBKey(&*v.begin(), &*v.rbegin() + 1, &decoded_key); | |
421 EXPECT_TRUE(decoded_key->IsEqual(expected_key)); | |
422 EXPECT_EQ(&*v.rbegin() + 1, p); | |
423 EXPECT_EQ(0, DecodeIDBKey(&*v.begin(), &*v.rbegin(), &decoded_key)); | |
424 | |
425 IndexedDBKey::KeyArray array; | |
426 array.push_back(IndexedDBKey(1234, WebIDBKey::NumberType)); | |
427 array.push_back(IndexedDBKey(ASCIIToUTF16("Hello World!"))); | |
428 array.push_back(IndexedDBKey(7890, WebIDBKey::DateType)); | |
429 expected_key = IndexedDBKey(array); | |
430 v = EncodeIDBKey(expected_key); | |
431 p = DecodeIDBKey(&*v.begin(), &*v.rbegin() + 1, &decoded_key); | |
432 EXPECT_TRUE(decoded_key->IsEqual(expected_key)); | |
433 EXPECT_EQ(&*v.rbegin() + 1, p); | |
434 EXPECT_EQ(0, DecodeIDBKey(&*v.begin(), &*v.rbegin(), &decoded_key)); | |
435 } | |
436 | |
437 TEST(IndexedDBLevelDBCodingTest, EncodeIDBKeyPath) { | |
438 const unsigned char kIDBKeyPathTypeCodedByte1 = 0; | |
439 const unsigned char kIDBKeyPathTypeCodedByte2 = 0; | |
440 { | |
441 IndexedDBKeyPath key_path; | |
442 EXPECT_EQ(key_path.type(), WebIDBKeyPath::NullType); | |
443 std::vector<char> v = EncodeIDBKeyPath(key_path); | |
444 EXPECT_EQ(v.size(), 3U); | |
445 EXPECT_EQ(v[0], kIDBKeyPathTypeCodedByte1); | |
446 EXPECT_EQ(v[1], kIDBKeyPathTypeCodedByte2); | |
447 EXPECT_EQ(v[2], WebIDBKeyPath::NullType); | |
448 } | |
449 | |
450 { | |
451 std::vector<string16> test_cases; | |
452 test_cases.push_back(string16()); | |
453 test_cases.push_back(ASCIIToUTF16("foo")); | |
454 test_cases.push_back(ASCIIToUTF16("foo.bar")); | |
455 | |
456 for (size_t i = 0; i < test_cases.size(); ++i) { | |
457 IndexedDBKeyPath key_path = IndexedDBKeyPath(test_cases[i]); | |
458 std::vector<char> v = EncodeIDBKeyPath(key_path); | |
459 EXPECT_EQ(v.size(), EncodeStringWithLength(test_cases[i]).size() + 3); | |
460 const char* p = &*v.begin(); | |
461 const char* limit = &*v.rbegin() + 1; | |
462 EXPECT_EQ(*p++, kIDBKeyPathTypeCodedByte1); | |
463 EXPECT_EQ(*p++, kIDBKeyPathTypeCodedByte2); | |
464 EXPECT_EQ(*p++, WebIDBKeyPath::StringType); | |
465 string16 string; | |
466 p = DecodeStringWithLength(p, limit, string); | |
467 EXPECT_EQ(string, test_cases[i]); | |
468 EXPECT_EQ(p, limit); | |
469 } | |
470 } | |
471 | |
472 { | |
473 std::vector<string16> test_case; | |
474 test_case.push_back(string16()); | |
475 test_case.push_back(ASCIIToUTF16("foo")); | |
476 test_case.push_back(ASCIIToUTF16("foo.bar")); | |
477 | |
478 IndexedDBKeyPath key_path(test_case); | |
479 EXPECT_EQ(key_path.type(), WebIDBKeyPath::ArrayType); | |
480 std::vector<char> v = EncodeIDBKeyPath(key_path); | |
481 const char* p = &*v.begin(); | |
482 const char* limit = &*v.rbegin() + 1; | |
483 EXPECT_EQ(*p++, kIDBKeyPathTypeCodedByte1); | |
484 EXPECT_EQ(*p++, kIDBKeyPathTypeCodedByte2); | |
485 EXPECT_EQ(*p++, WebIDBKeyPath::ArrayType); | |
486 int64 count; | |
487 p = DecodeVarInt(p, limit, count); | |
488 EXPECT_EQ(count, static_cast<int64>(test_case.size())); | |
489 for (size_t i = 0; i < static_cast<size_t>(count); ++i) { | |
490 string16 string; | |
491 p = DecodeStringWithLength(p, limit, string); | |
492 EXPECT_EQ(string, test_case[i]); | |
493 } | |
494 EXPECT_EQ(p, limit); | |
495 } | |
496 } | |
497 | |
498 TEST(IndexedDBLevelDBCodingTest, DecodeIDBKeyPath) { | |
499 const unsigned char kIDBKeyPathTypeCodedByte1 = 0; | |
500 const unsigned char kIDBKeyPathTypeCodedByte2 = 0; | |
501 { | |
502 // Legacy encoding of string key paths. | |
503 std::vector<string16> test_cases; | |
504 test_cases.push_back(string16()); | |
505 test_cases.push_back(ASCIIToUTF16("foo")); | |
506 test_cases.push_back(ASCIIToUTF16("foo.bar")); | |
507 | |
508 for (size_t i = 0; i < test_cases.size(); ++i) { | |
509 std::vector<char> v = EncodeString(test_cases[i]); | |
510 IndexedDBKeyPath key_path = | |
511 DecodeIDBKeyPath(&*v.begin(), &*v.rbegin() + 1); | |
512 EXPECT_EQ(key_path.type(), WebIDBKeyPath::StringType); | |
513 EXPECT_EQ(test_cases[i], key_path.string()); | |
514 } | |
515 } | |
516 { | |
517 std::vector<char> v; | |
518 v.push_back(kIDBKeyPathTypeCodedByte1); | |
519 v.push_back(kIDBKeyPathTypeCodedByte2); | |
520 v.push_back(WebIDBKeyPath::NullType); | |
521 IndexedDBKeyPath key_path = DecodeIDBKeyPath(&*v.begin(), &*v.rbegin() + 1); | |
522 EXPECT_EQ(key_path.type(), WebIDBKeyPath::NullType); | |
523 EXPECT_TRUE(key_path.IsNull()); | |
524 } | |
525 { | |
526 std::vector<string16> test_cases; | |
527 test_cases.push_back(string16()); | |
528 test_cases.push_back(ASCIIToUTF16("foo")); | |
529 test_cases.push_back(ASCIIToUTF16("foo.bar")); | |
530 | |
531 for (size_t i = 0; i < test_cases.size(); ++i) { | |
532 std::vector<char> v; | |
533 v.push_back(kIDBKeyPathTypeCodedByte1); | |
534 v.push_back(kIDBKeyPathTypeCodedByte2); | |
535 v.push_back(WebIDBKeyPath::StringType); | |
536 std::vector<char> test_case = EncodeStringWithLength(test_cases[i]); | |
537 v.insert(v.end(), test_case.begin(), test_case.end()); | |
538 IndexedDBKeyPath key_path = | |
539 DecodeIDBKeyPath(&*v.begin(), &*v.rbegin() + 1); | |
540 EXPECT_EQ(key_path.type(), WebIDBKeyPath::StringType); | |
541 EXPECT_EQ(test_cases[i], key_path.string()); | |
542 } | |
543 } | |
544 { | |
545 std::vector<string16> test_case; | |
546 test_case.push_back(string16()); | |
547 test_case.push_back(ASCIIToUTF16("foo")); | |
548 test_case.push_back(ASCIIToUTF16("foo.bar")); | |
549 | |
550 std::vector<char> v; | |
551 v.push_back(kIDBKeyPathTypeCodedByte1); | |
552 v.push_back(kIDBKeyPathTypeCodedByte2); | |
553 v.push_back(WebIDBKeyPath::ArrayType); | |
554 std::vector<char> int_value = EncodeVarInt(test_case.size()); | |
555 v.insert(v.end(), int_value.begin(), int_value.end()); | |
556 for (size_t i = 0; i < test_case.size(); ++i) { | |
557 std::vector<char> test_case_value = EncodeStringWithLength(test_case[i]); | |
558 v.insert(v.end(), test_case_value.begin(), test_case_value.end()); | |
559 } | |
560 IndexedDBKeyPath key_path = DecodeIDBKeyPath(&*v.begin(), &*v.rbegin() + 1); | |
561 EXPECT_EQ(key_path.type(), WebIDBKeyPath::ArrayType); | |
562 EXPECT_EQ(key_path.array().size(), test_case.size()); | |
563 for (size_t i = 0; i < test_case.size(); ++i) | |
564 EXPECT_EQ(key_path.array()[i], test_case[i]); | |
565 } | |
566 } | |
567 | |
568 TEST(IndexedDBLevelDBCodingTest, ExtractAndCompareIDBKeys) { | |
569 std::vector<IndexedDBKey> keys; | |
570 | |
571 keys.push_back(IndexedDBKey(-10, WebIDBKey::NumberType)); | |
572 keys.push_back(IndexedDBKey(0, WebIDBKey::NumberType)); | |
573 keys.push_back(IndexedDBKey(3.14, WebIDBKey::NumberType)); | |
574 | |
575 keys.push_back(IndexedDBKey(0, WebIDBKey::DateType)); | |
576 keys.push_back(IndexedDBKey(100, WebIDBKey::DateType)); | |
577 keys.push_back(IndexedDBKey(100000, WebIDBKey::DateType)); | |
578 | |
579 keys.push_back(IndexedDBKey(ASCIIToUTF16(""))); | |
580 keys.push_back(IndexedDBKey(ASCIIToUTF16("a"))); | |
581 keys.push_back(IndexedDBKey(ASCIIToUTF16("b"))); | |
582 keys.push_back(IndexedDBKey(ASCIIToUTF16("baaa"))); | |
583 keys.push_back(IndexedDBKey(ASCIIToUTF16("baab"))); | |
584 keys.push_back(IndexedDBKey(ASCIIToUTF16("c"))); | |
585 | |
586 keys.push_back(CreateArrayIDBKey()); | |
587 keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKey::NumberType))); | |
588 keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKey::NumberType), | |
589 IndexedDBKey(3.14, WebIDBKey::NumberType))); | |
590 keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKey::DateType))); | |
591 keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKey::DateType), | |
592 IndexedDBKey(0, WebIDBKey::DateType))); | |
593 keys.push_back(CreateArrayIDBKey(IndexedDBKey(ASCIIToUTF16("")))); | |
594 keys.push_back(CreateArrayIDBKey(IndexedDBKey(ASCIIToUTF16("")), | |
595 IndexedDBKey(ASCIIToUTF16("a")))); | |
596 keys.push_back(CreateArrayIDBKey(CreateArrayIDBKey())); | |
597 keys.push_back(CreateArrayIDBKey(CreateArrayIDBKey(), CreateArrayIDBKey())); | |
598 keys.push_back(CreateArrayIDBKey(CreateArrayIDBKey(CreateArrayIDBKey()))); | |
599 keys.push_back(CreateArrayIDBKey( | |
600 CreateArrayIDBKey(CreateArrayIDBKey(CreateArrayIDBKey())))); | |
601 | |
602 for (size_t i = 0; i < keys.size() - 1; ++i) { | |
603 const IndexedDBKey& key_a = keys[i]; | |
604 const IndexedDBKey& key_b = keys[i + 1]; | |
605 | |
606 EXPECT_TRUE(key_a.IsLessThan(key_b)); | |
607 | |
608 std::vector<char> encoded_a = EncodeIDBKey(key_a); | |
609 EXPECT_TRUE(encoded_a.size()); | |
610 std::vector<char> encoded_b = EncodeIDBKey(key_b); | |
611 EXPECT_TRUE(encoded_b.size()); | |
612 | |
613 std::vector<char> extracted_a; | |
614 std::vector<char> extracted_b; | |
615 | |
616 const char* p = ExtractEncodedIDBKey( | |
617 &*encoded_a.begin(), &*encoded_a.rbegin() + 1, &extracted_a); | |
618 EXPECT_EQ(&*encoded_a.rbegin() + 1, p); | |
619 EXPECT_EQ(encoded_a, extracted_a); | |
620 | |
621 const char* q = ExtractEncodedIDBKey( | |
622 &*encoded_b.begin(), &*encoded_b.rbegin() + 1, &extracted_b); | |
623 EXPECT_EQ(&*encoded_b.rbegin() + 1, q); | |
624 EXPECT_EQ(encoded_b, extracted_b); | |
625 | |
626 EXPECT_LT(CompareKeys(extracted_a, extracted_b), 0); | |
627 EXPECT_GT(CompareKeys(extracted_b, extracted_a), 0); | |
628 EXPECT_EQ(CompareKeys(extracted_a, extracted_a), 0); | |
629 EXPECT_EQ(CompareKeys(extracted_b, extracted_b), 0); | |
630 | |
631 EXPECT_EQ(0, | |
632 ExtractEncodedIDBKey( | |
633 &*encoded_a.begin(), &*encoded_a.rbegin(), &extracted_a)); | |
634 } | |
635 } | |
636 | |
637 TEST(IndexedDBLevelDBCodingTest, ComparisonTest) { | |
638 std::vector<std::vector<char> > keys; | |
639 keys.push_back(SchemaVersionKey::Encode()); | |
640 keys.push_back(MaxDatabaseIdKey::Encode()); | |
641 keys.push_back(DatabaseFreeListKey::Encode(0)); | |
642 keys.push_back(DatabaseFreeListKey::EncodeMaxKey()); | |
643 keys.push_back(DatabaseNameKey::Encode(ASCIIToUTF16(""), ASCIIToUTF16(""))); | |
644 keys.push_back(DatabaseNameKey::Encode(ASCIIToUTF16(""), ASCIIToUTF16("a"))); | |
645 keys.push_back(DatabaseNameKey::Encode(ASCIIToUTF16("a"), ASCIIToUTF16("a"))); | |
646 keys.push_back( | |
647 DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::ORIGIN_NAME)); | |
648 keys.push_back( | |
649 DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::DATABASE_NAME)); | |
650 keys.push_back( | |
651 DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::USER_VERSION)); | |
652 keys.push_back( | |
653 DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID)); | |
654 keys.push_back( | |
655 DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::USER_INT_VERSION)); | |
656 keys.push_back( | |
657 ObjectStoreMetaDataKey::Encode(1, 1, ObjectStoreMetaDataKey::NAME)); | |
658 keys.push_back( | |
659 ObjectStoreMetaDataKey::Encode(1, 1, ObjectStoreMetaDataKey::KEY_PATH)); | |
660 keys.push_back(ObjectStoreMetaDataKey::Encode( | |
661 1, 1, ObjectStoreMetaDataKey::AUTO_INCREMENT)); | |
662 keys.push_back( | |
663 ObjectStoreMetaDataKey::Encode(1, 1, ObjectStoreMetaDataKey::EVICTABLE)); | |
664 keys.push_back(ObjectStoreMetaDataKey::Encode( | |
665 1, 1, ObjectStoreMetaDataKey::LAST_VERSION)); | |
666 keys.push_back(ObjectStoreMetaDataKey::Encode( | |
667 1, 1, ObjectStoreMetaDataKey::MAX_INDEX_ID)); | |
668 keys.push_back(ObjectStoreMetaDataKey::Encode( | |
669 1, 1, ObjectStoreMetaDataKey::HAS_KEY_PATH)); | |
670 keys.push_back(ObjectStoreMetaDataKey::Encode( | |
671 1, 1, ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER)); | |
672 keys.push_back(ObjectStoreMetaDataKey::EncodeMaxKey(1, 1)); | |
673 keys.push_back(ObjectStoreMetaDataKey::EncodeMaxKey(1, 2)); | |
674 keys.push_back(ObjectStoreMetaDataKey::EncodeMaxKey(1)); | |
675 keys.push_back(IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::NAME)); | |
676 keys.push_back(IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::UNIQUE)); | |
677 keys.push_back( | |
678 IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::KEY_PATH)); | |
679 keys.push_back( | |
680 IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::MULTI_ENTRY)); | |
681 keys.push_back(IndexMetaDataKey::Encode(1, 1, 31, 0)); | |
682 keys.push_back(IndexMetaDataKey::Encode(1, 1, 31, 1)); | |
683 keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 1, 31)); | |
684 keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 1, 32)); | |
685 keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 1)); | |
686 keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 2)); | |
687 keys.push_back(ObjectStoreFreeListKey::Encode(1, 1)); | |
688 keys.push_back(ObjectStoreFreeListKey::EncodeMaxKey(1)); | |
689 keys.push_back(IndexFreeListKey::Encode(1, 1, kMinimumIndexId)); | |
690 keys.push_back(IndexFreeListKey::EncodeMaxKey(1, 1)); | |
691 keys.push_back(IndexFreeListKey::Encode(1, 2, kMinimumIndexId)); | |
692 keys.push_back(IndexFreeListKey::EncodeMaxKey(1, 2)); | |
693 keys.push_back(ObjectStoreNamesKey::Encode(1, ASCIIToUTF16(""))); | |
694 keys.push_back(ObjectStoreNamesKey::Encode(1, ASCIIToUTF16("a"))); | |
695 keys.push_back(IndexNamesKey::Encode(1, 1, ASCIIToUTF16(""))); | |
696 keys.push_back(IndexNamesKey::Encode(1, 1, ASCIIToUTF16("a"))); | |
697 keys.push_back(IndexNamesKey::Encode(1, 2, ASCIIToUTF16("a"))); | |
698 keys.push_back(ObjectStoreDataKey::Encode(1, 1, MinIDBKey())); | |
699 keys.push_back(ObjectStoreDataKey::Encode(1, 1, MaxIDBKey())); | |
700 keys.push_back(ExistsEntryKey::Encode(1, 1, MinIDBKey())); | |
701 keys.push_back(ExistsEntryKey::Encode(1, 1, MaxIDBKey())); | |
702 keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MinIDBKey(), 0)); | |
703 keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MinIDBKey(), 1)); | |
704 keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MaxIDBKey(), 0)); | |
705 keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MaxIDBKey(), 1)); | |
706 keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MinIDBKey(), 0)); | |
707 keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MinIDBKey(), 1)); | |
708 keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MaxIDBKey(), 0)); | |
709 keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MaxIDBKey(), 1)); | |
710 keys.push_back(IndexDataKey::Encode(1, 1, 31, MinIDBKey(), MinIDBKey(), 0)); | |
711 keys.push_back(IndexDataKey::Encode(1, 2, 30, MinIDBKey(), MinIDBKey(), 0)); | |
712 keys.push_back( | |
713 IndexDataKey::EncodeMaxKey(1, 2, std::numeric_limits<int32>::max() - 1)); | |
714 | |
715 for (size_t i = 0; i < keys.size(); ++i) { | |
716 const LevelDBSlice key_a(keys[i]); | |
717 EXPECT_EQ(Compare(key_a, key_a), 0); | |
718 | |
719 for (size_t j = i + 1; j < keys.size(); ++j) { | |
720 const LevelDBSlice key_b(keys[j]); | |
721 EXPECT_LT(Compare(key_a, key_b), 0); | |
722 EXPECT_GT(Compare(key_b, key_a), 0); | |
723 } | |
724 } | |
725 } | |
726 | |
727 TEST(IndexedDBLevelDBCodingTest, EncodeVarIntVSEncodeByteTest) { | |
728 std::vector<unsigned char> test_cases; | |
729 test_cases.push_back(0); | |
730 test_cases.push_back(1); | |
731 test_cases.push_back(127); | |
732 | |
733 for (size_t i = 0; i < test_cases.size(); ++i) { | |
734 unsigned char n = test_cases[i]; | |
735 | |
736 std::vector<char> vA = EncodeByte(n); | |
737 std::vector<char> vB = EncodeVarInt(static_cast<int64>(n)); | |
738 | |
739 EXPECT_EQ(vA.size(), vB.size()); | |
740 EXPECT_EQ(*vA.begin(), *vB.begin()); | |
741 } | |
742 } | |
743 | |
744 } // namespace | |
745 | |
746 } // namespace content | |
OLD | NEW |