Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / LayoutTests / storage / indexeddb / resources / cursor-advance.js
blobdff8f9e22e4f0918f635d9ecd3305925b6938ce3
1 if (this.importScripts) {
2     importScripts('../../../resources/js-test.js');
3     importScripts('shared.js');
6 description("Test IndexedDB cursor.advance().");
8 var objectStoreData = [
9     { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
10     { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
11     { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
12     { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
13     { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
14     { key: "237-23-7737", value: { name: "Pat", height: 65, weight: 100 } },
15     { key: "237-23-7738", value: { name: "Leo", height: 65, weight: 180 } },
16     { key: "237-23-7739", value: { name: "Jef", height: 65, weight: 120 } },
17     { key: "237-23-7740", value: { name: "Sam", height: 71, weight: 110 } },
18     { key: "237-23-7741", value: { name: "Bug", height: 63, weight: 100 } },
19     { key: "237-23-7742", value: { name: "Tub", height: 69, weight: 180 } },
20     { key: "237-23-7743", value: { name: "Rug", height: 77, weight: 120 } },
21     { key: "237-23-7744", value: { name: "Pug", height: 66, weight: 110 } },
24 var indexData = [
25     { name: "name", keyPath: "name", options: { unique: true } },
26     { name: "height", keyPath: "height", options: { } },
27     { name: "weight", keyPath: "weight", options: { unique: false } }
30 indexedDBTest(prepareDatabase, onOpen);
31 function prepareDatabase(evt)
33     preamble(evt);
34     db = event.target.result;
35     objectStoreName = "People";
36     objectStore = evalAndLog("objectStore = db.createObjectStore(objectStoreName);");
37     createIndexes();
40 function onOpen()
42     evalAndLog("trans = db.transaction(objectStoreName, 'readwrite')");
43     evalAndLog("objectStore = trans.objectStore(objectStoreName)");
44     populateObjectStore();
47 function populateObjectStore()
49     debug("First, add all our data to the object store.");
50     addedData = 0;
51     for (i in objectStoreData) {
52         request = evalAndLog("request = objectStore.add(objectStoreData[i].value, objectStoreData[i].key);");
53         request.onerror = unexpectedErrorCallback;
54     }
55     trans.oncomplete = testSimple;
58 function createIndexes()
60     debug("Now create the indexes.");
61     for (i in indexData) {
62       evalAndLog("objectStore.createIndex(indexData[i].name, indexData[i].keyPath, indexData[i].options);");
63     }
66 // Make a test that uses continue() to get to startPos, then passes
67 // 'count' to get to a position.
68 function makeAdvanceTest(startPos, direction, count, expectedValue, indexName)
70     result = {};
71     evalAndLog("trans = db.transaction(objectStoreName)");
72     store = evalAndLog("store = trans.objectStore(objectStoreName)");
73     if (indexName)
74         store = store.index(indexName);
76     if (direction)
77         evalAndLog("request = store.openCursor(null, " + direction + ")");
78     else
79         evalAndLog("request = store.openCursor()");
80     var currentPos = 0;
81     function continueToTest(event)
82     {
83         cursor = event.target.result;
84         if (currentPos == startPos) {
85             evalAndLog("cursor.advance(" + count + ")");
86         } else if (currentPos == startPos + 1) {
87             runTest(cursor, expectedValue);
88             result.onsuccess();
89         } else {
90             if (cursor == null)
91                 result.onsuccess();
92             else {
93                 evalAndLog("cursor.continue();");
94             }
95         }
96         currentPos++;
97     }
99     request.onsuccess = continueToTest;
100     request.onerror = function(e)
101     {
102         result.onerror(e);
103     };
105     return result;
108 function simplifyCursor(cursor)
110     var obj = {};
111     if (cursor === null) {
112         return null;
113     }
114     if ('key' in cursor) {
115         obj.key = cursor.key;
116     }
118     if ('value' in cursor) {
119         obj.value = cursor.value;
120     }
122     if ('primaryKey' in cursor) {
123         obj.primaryKey = cursor.primaryKey;
124     }
125     return obj;
128 function runTest(cursor, expectedValue)
130     expected = JSON.stringify(expectedValue);
131     shouldBeEqualToString("expected", JSON.stringify(simplifyCursor(cursor)));
135 function testSimple()
137     debug("testSimple()");
138     makeAdvanceTest(0, null, 1,
139                     {key: objectStoreData[1].key,
140                      value: objectStoreData[1].value,
141                      primaryKey: objectStoreData[1].key})
142                          .onsuccess= testContinueThenAdvance;
145 function testContinueThenAdvance()
147     debug("testContinueThenAdvance()");
148     makeAdvanceTest(3, null, 1,
149                     // Joe
150                     {key: objectStoreData[4].key,
151                      value: objectStoreData[4].value,
152                      primaryKey: objectStoreData[4].key})
153                          .onsuccess= testAdvanceMultiple;
156 function testAdvanceMultiple()
158     debug("testAdvanceMultiple()");
159     makeAdvanceTest(0, null, 3,
160                     {key: objectStoreData[3].key,
161                      value: objectStoreData[3].value,
162                      primaryKey: objectStoreData[3].key})
163                          .onsuccess = testAdvanceIndex;
166 function testAdvanceIndex()
168     debug("testAdvanceIndex()");
169     makeAdvanceTest(0, null, 3,
170                     // Jef
171                     {key: objectStoreData[7].value.name,
172                      value: objectStoreData[7].value,
173                      primaryKey: objectStoreData[7].key},
174                     "name").onsuccess = testAdvanceIndexNoDupe;
177 function testAdvanceIndexNoDupe()
179     debug("testAdvanceIndexNoDupe()");
180     makeAdvanceTest(0, "'nextunique'", 3,
181                     // Sue (weight 130 - skipping weight 100, 110, 120)
182                     {key: objectStoreData[3].value.weight,
183                      value: objectStoreData[3].value,
184                      primaryKey: objectStoreData[3].key},
185                     "weight").onsuccess = testAdvanceIndexPrev;
188 function testAdvanceIndexPrev()
190     debug("testAdvanceIndexPrev()");
191     makeAdvanceTest(0, "'prev'", 3,
192                     // Joe (weight 150 - skipping 180, 180, 180)
193                     {key: objectStoreData[4].value.weight,
194                      value: objectStoreData[4].value,
195                      primaryKey: objectStoreData[4].key},
196                     "weight").onsuccess = testAdvanceIndexPrevNoDupe;
199 function testAdvanceIndexPrevNoDupe()
201     debug("testAdvanceIndexPrevNoDupe()");
202     makeAdvanceTest(0, "'prevunique'", 3,
203                     // Bob (weight 120 - skipping weights 180, 150, 130)
204                     {key: objectStoreData[0].value.weight,
205                      value: objectStoreData[0].value,
206                      primaryKey: objectStoreData[0].key},
207                     "weight").onsuccess = testAdvanceToEnd;
210 function testAdvanceToEnd()
212     debug("testAdvanceToEnd()");
213     makeAdvanceTest(0, null, 100, null)
214         .onsuccess = testPrefetchInRange;
217 // Make sure the prefetching that exists on some platforms (chromium)
218 // doesn't mess with advance(), or vice versa.
219 function testPrefetchInRange()
221     debug("testPrefetchInRange()");
222     var kPrefetchContinueThreshold = 2;
223     evalAndLog("trans = db.transaction(objectStoreName)");
224     objectStore = evalAndLog("objectStore = trans.objectStore(objectStoreName)");
226     evalAndLog("request = objectStore.openCursor()");
228     var currentPos = 0;
229     function prefetch(evt)
230     {
231         preamble(evt);
232         cursor = event.target.result;
234         if (!cursor) {
235             testPrefetchOutOfRange();
236             return;
237         }
239         runTest(cursor, {key: objectStoreData[currentPos].key,
240                          value: objectStoreData[currentPos].value,
241                          primaryKey: objectStoreData[currentPos].key});
243         // force some prefetching,
244         if (currentPos < (kPrefetchContinueThreshold+1)) {
245             evalAndLog("cursor.continue()");
246             currentPos++;
247         } else if (currentPos == (kPrefetchContinueThreshold+1)) {
248             // stay within the prefetch range
249             evalAndLog("cursor.advance(2)");
250             currentPos += 2;
251         } else {
252             // we're just past the threshold
253             evalAndLog("cursor.continue()");
254             currentPos++;
255         }
256     }
257     request.onsuccess = prefetch;
258     request.onerror = unexpectedErrorCallback;
261 // Make sure the prefetching that exists on some platforms (chromium)
262 // doesn't mess with advance(), or vice versa.
263 function testPrefetchOutOfRange()
265     debug("testPrefetchOutOfRange()");
266     var kPrefetchContinueThreshold = 2;
267     evalAndLog("trans = db.transaction(objectStoreName)");
268     objectStore = evalAndLog("objectStore = trans.objectStore(objectStoreName)");
270     evalAndLog("request = objectStore.openCursor()");
272     var currentPos = 0;
273     function prefetch(evt)
274     {
275         preamble(evt);
276         cursor = event.target.result;
278         if (!cursor) {
279             testBadAdvance();
280             return;
281         }
283         runTest(cursor, {key: objectStoreData[currentPos].key,
284                          value: objectStoreData[currentPos].value,
285                          primaryKey: objectStoreData[currentPos].key});
287         // force some prefetching,
288         if (currentPos < (kPrefetchContinueThreshold+1)) {
289             evalAndLog("cursor.continue()");
290             currentPos++;
291         } else if (currentPos == (kPrefetchContinueThreshold+1)) {
292             // advance past the prefetch range
293             evalAndLog("cursor.advance(7)");
294             currentPos += 7;
295         } else {
296             // we're past the threshold
297             evalAndLog("cursor.continue()");
298             currentPos++;
299         }
300     }
301     request.onsuccess = prefetch;
302     request.onerror = unexpectedErrorCallback;
305 function testBadAdvance()
307     debug("testBadAdvance()");
308     evalAndLog("trans = db.transaction(objectStoreName, 'readwrite')");
309     objectStore = evalAndLog("objectStore = trans.objectStore(objectStoreName)");
311     evalAndLog("request = objectStore.openCursor()");
313     function advanceBadly(evt)
314     {
315         preamble(evt);
316         cursor = event.target.result;
318         evalAndExpectExceptionClass("cursor.advance(0)", "TypeError");
319         evalAndExpectExceptionClass("cursor.advance(-1)", "TypeError");
320         evalAndExpectExceptionClass("cursor.advance(0x100000000)", "TypeError");
321         evalAndExpectExceptionClass("cursor.advance(0x20000000000000)", "TypeError");
322         testEdges();
323     }
324     request.onsuccess = advanceBadly;
325     request.onerror = unexpectedErrorCallback;
328 function testEdges()
330     preamble();
331     evalAndLog("trans = db.transaction(objectStoreName, 'readonly')");
332     trans.onabort = unexpectedAbortCallback;
334     objectStore = evalAndLog("objectStore = trans.objectStore(objectStoreName)");
335     evalAndLog("request = objectStore.openCursor()");
336     request.onerror = unexpectedErrorCallback;
338     firstSuccess = true;
339     request.onsuccess = function onSuccess(evt) {
340         preamble(evt);
341         evalAndLog("cursor = event.target.result");
342         if (firstSuccess) {
343             shouldBeNonNull("cursor");
344             firstSuccess = false;
345             evalAndLog("cursor.advance(0xffffffff)");
346         } else {
347             shouldBeNull("cursor");
348         }
349     };
351     trans.oncomplete = testDelete;
354 function testDelete()
356     debug("testDelete()");
357     evalAndLog("trans = db.transaction(objectStoreName, 'readwrite')");
358     objectStore = evalAndLog("objectStore = trans.objectStore(objectStoreName)");
360     evalAndLog("request = objectStore.openCursor()");
362     var currentPos = 0;
363     function deleteSecond(evt)
364     {
365         preamble(evt);
366         cursor = event.target.result;
368         if (!cursor) {
369             finishJSTest();
370             return;
371         }
373         runTest(cursor, {key: objectStoreData[currentPos].key,
374                          value: objectStoreData[currentPos].value,
375                          primaryKey: objectStoreData[currentPos].key});
378         // this is in the middle of the data, so it will test validity
379         if (currentPos == 2) {
380             evalAndLog("cursor.delete()");
381             cursor.advance(4);
382             currentPos += 4;
383         } else {
384             evalAndLog("cursor.advance(1)");
385             currentPos++;
386         }
388     }
389     request.onsuccess = deleteSecond;
390     request.onerror = unexpectedErrorCallback;