Chromium Code Reviews| Index: chrome/test/data/indexeddb/cursor_prefetch.js |
| diff --git a/chrome/test/data/indexeddb/cursor_prefetch.js b/chrome/test/data/indexeddb/cursor_prefetch.js |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..bcda0aa2e31bf6f9821df7e3b22f69f65b3c1845 |
| --- /dev/null |
| +++ b/chrome/test/data/indexeddb/cursor_prefetch.js |
| @@ -0,0 +1,384 @@ |
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +var kPrefetchThreshold = 2; |
|
jsbell
2011/11/28 20:29:16
Include a comment that this must match the value i
hans
2011/11/29 14:44:34
Done.
|
| +var kMinPrefetchAmount = 5; |
| +var kNumberOfItems = 100; |
|
jsbell
2011/11/28 20:29:16
Since this is == kMaxPrefetchAmount in renderer_we
hans
2011/11/29 14:44:34
Done. Bumping to 200.
|
| + |
| +function test() { |
| + request = webkitIndexedDB.open('cursor-prefetch'); |
|
jsbell
2011/11/28 20:29:16
Can you add the indexedDB = indexedDB || webkitInd
hans
2011/11/29 14:44:34
Done.
|
| + request.onsuccess = openSuccess; |
| + request.onerror = unexpectedErrorCallback; |
| +} |
| + |
| +function openSuccess() { |
| + window.db = event.target.result; |
| + |
| + request = db.setVersion('new version'); |
| + request.onsuccess = setVersionSuccess; |
| + request.onerror = unexpectedErrorCallback; |
| +} |
| + |
| +function setVersionSuccess() { |
| + debug("setVersionSuccess():"); |
| + window.trans = event.target.result; |
| + shouldBeTrue("trans !== null"); |
| + trans.onabort = unexpectedAbortCallback; |
| + trans.oncomplete = fillObjectStore; |
| + |
| + deleteAllObjectStores(db); |
| + var store = db.createObjectStore('store'); |
| + store.createIndex('index', ''); |
| +} |
| + |
| +function fillObjectStore() { |
| + debug("fillObjectStore()"); |
| + var trans = db.transaction(['store'], webkitIDBTransaction.READ_WRITE); |
| + trans.onabort = unexpectedAbortCallback; |
| + trans.oncomplete = firstTest; |
| + |
| + var store = trans.objectStore('store'); |
| + debug("Storing " + kNumberOfItems + " object in the object store."); |
| + for (var i = 0; i < kNumberOfItems; ++i) { |
| + var req = store.put(i, i); |
| + req.onerror = unexpectedErrorCallback; |
| + } |
| + |
| + // Let the transaction finish. |
| +} |
| + |
| +function firstTest() { |
| + debug("firstTest()"); |
| + |
| + // Test iterating straight through the object store. |
| + |
| + var trans = db.transaction(['store'], webkitIDBTransaction.READ_WRITE); |
| + trans.onabort = unexpectedAbortCallback; |
| + trans.oncomplete = secondTest; |
| + |
| + var store = trans.objectStore('store'); |
| + var cursorReq = store.openCursor(); |
| + cursorReq.onerror = unexpectedErrorCallback; |
| + |
| + count = 0; |
| + cursorReq.onsuccess = function() { |
| + cursor = event.target.result; |
| + if (cursor === null) { |
| + shouldBe("count", "kNumberOfItems"); |
| + return; // Let the transaction finish. |
| + } |
| + |
| + if (cursor.key !== count) |
| + shouldBe("cursor.key", "count"); |
| + if (cursor.value !== count) |
| + shouldBe("cursor.value", "count"); |
| + |
| + ++count; |
| + |
| + cursor.continue(); |
| + } |
| +} |
| + |
| +function secondTest() { |
| + debug("secondTest()"); |
| + |
| + // Test iterating through the object store, intermixed with |
| + // continue calls to specific keys. |
| + |
| + var trans = db.transaction(['store'], webkitIDBTransaction.READ_WRITE); |
| + trans.onabort = unexpectedAbortCallback; |
| + trans.oncomplete = thirdTest; |
| + |
| + var store = trans.objectStore('store'); |
| + var cursorReq = store.openCursor(); |
| + cursorReq.onerror = unexpectedErrorCallback; |
| + |
| + var jumpTable = [{from: 5, to: 17}, |
| + {from: 25, to: 30}, |
| + {from: 31, to: 35}, |
| + {from: 70, to: 80}, |
| + {from: 98, to: 99}]; |
| + |
| + count = 0; |
| + expectedKey = 0; |
| + |
| + cursorReq.onsuccess = function() { |
| + cursor = event.target.result; |
| + if (cursor === null) { |
| + debug("Finished iterating after " + count + " steps."); |
| + return; // Let the transaction finish. |
| + } |
| + |
| + if (cursor.key !== expectedKey) |
| + shouldBe("cursor.key", "expectedKey"); |
| + if (cursor.value !== expectedKey) |
| + shouldBe("cursor.value", "expectedKey"); |
| + |
| + ++count; |
| + |
| + for (var i = 0; i < jumpTable.length; ++i) { |
| + if (jumpTable[i].from === cursor.key) { |
| + expectedKey = jumpTable[i].to; |
| + debug("Jumping from "+ cursor.key + " to " + expectedKey); |
| + cursor.continue(expectedKey); |
| + return; |
| + } |
| + } |
| + |
| + ++expectedKey; |
| + cursor.continue(); |
| + } |
| +} |
| + |
| +function thirdTest() { |
| + debug("thirdTest()"); |
| + |
| + // Test iterating straight through the object store in reverse. |
| + |
| + var trans = db.transaction(['store'], webkitIDBTransaction.READ_WRITE); |
| + trans.onabort = unexpectedAbortCallback; |
| + trans.oncomplete = fourthTest; |
| + |
| + var store = trans.objectStore('store'); |
| + var cursorReq = store.openCursor( |
| + webkitIDBKeyRange.upperBound(kNumberOfItems-1), webkitIDBCursor.PREV); |
| + cursorReq.onerror = unexpectedErrorCallback; |
| + |
| + count = 0; |
| + cursorReq.onsuccess = function() { |
| + cursor = event.target.result; |
| + if (cursor === null) { |
| + shouldBe("count", "kNumberOfItems"); |
| + return; // Let the transaction finish. |
| + } |
| + |
| + expectedKey = kNumberOfItems - count - 1; |
| + |
| + if (cursor.key !== expectedKey) |
| + shouldBe("cursor.key", "expectedKey"); |
| + if (cursor.value !== expectedKey) |
| + shouldBe("cursor.value", "expectedKey"); |
| + |
| + ++count; |
| + |
| + cursor.continue(); |
| + } |
| +} |
| + |
| +function fourthTest() { |
| + debug("fourthTest()"); |
| + |
| + // Test iterating, and then stopping before reaching the end. |
| + // Make sure transaction terminates anyway. |
| + |
| + var trans = db.transaction(['store'], webkitIDBTransaction.READ_WRITE); |
| + trans.onabort = unexpectedAbortCallback; |
| + trans.oncomplete = function() { |
| + debug("fourthTest() transaction completed"); |
| + fifthTest(); |
| + } |
| + |
| + var store = trans.objectStore('store'); |
| + var cursorReq = store.openCursor(); |
| + cursorReq.onerror = unexpectedErrorCallback; |
| + |
| + count = 0; |
| + cursorReq.onsuccess = function() { |
| + cursor = event.target.result; |
| + |
| + if (cursor.key !== count) |
| + shouldBe("cursor.key", "count"); |
| + if (cursor.value !== count) |
| + shouldBe("cursor.value", "count"); |
| + |
| + ++count; |
| + |
| + if (count === 25) { |
| + // Schedule some other request. |
| + var otherReq = store.get(42); |
| + otherReq.onerror = unexpectedErrorCallback; |
| + otherReq.onsuccess = function() { |
| + if (count === 25) { |
| + debug("Other request fired before continue, as expected."); |
| + } else { |
| + debug("Other request fired out-of-order!"); |
| + fail(); |
| + } |
| + } |
| + |
| + cursor.continue(); |
| + return; |
| + } |
| + |
| + if (count === 30) { |
| + // Do a continue first, then another request. |
| + cursor.continue(); |
| + |
| + var otherReq = store.get(42); |
| + otherReq.onerror = unexpectedErrorCallback; |
| + otherReq.onsuccess = function() { |
| + if (count === 31) { |
| + debug("Other request fired right after continue as expected."); |
| + } else { |
| + debug("Other request didn't fire right after continue as expected."); |
| + fail(); |
| + } |
| + } |
| + |
| + return; |
| + } |
| + |
| + if (count === 75) { |
| + return; // Sudden stop. |
| + } |
| + |
| + cursor.continue(); |
| + } |
| +} |
| + |
| +function fifthTest() { |
| + debug("fifthTest()"); |
| + |
| + // Test iterating over the pre-fetch threshold, but make sure the |
| + // cursor is positioned so that it is actually at the last element |
| + // in the range when pre-fetch fires, and make sure a null cursor |
| + // is the result as expected. |
| + |
| + var trans = db.transaction(['store'], webkitIDBTransaction.READ_WRITE); |
| + trans.onabort = unexpectedAbortCallback; |
| + trans.oncomplete = sixthTest; |
| + |
| + var store = trans.objectStore('store'); |
| + |
| + var startKey = kNumberOfItems - 1 - kPrefetchThreshold; |
| + var cursorReq = store.openCursor(webkitIDBKeyRange.lowerBound(startKey)); |
| + cursorReq.onerror = unexpectedErrorCallback; |
| + |
| + count = 0; |
| + cursorReq.onsuccess = function() { |
| + cursor = event.target.result; |
| + |
| + if (cursor === null) { |
| + debug("cursor is null"); |
| + shouldBe("count", "kPrefetchThreshold + 1"); |
| + return; |
| + } |
| + |
| + debug("count: " + count); |
| + ++count; |
| + cursor.continue(); |
| + } |
| +} |
| + |
| +function sixthTest() { |
| + debug("sixthTest()"); |
| + |
| + // Test stepping two cursors simultaneously. First cursor1 steps |
| + // for a while, then cursor2, then back to cursor1, etc. |
| + |
| + var trans = db.transaction(['store'], webkitIDBTransaction.READ_WRITE); |
| + trans.onabort = unexpectedAbortCallback; |
| + trans.oncomplete = seventhTest; |
| + var store = trans.objectStore('store'); |
| + |
| + cursor1 = null; |
| + cursor2 = null; |
| + |
| + count1 = 0; |
| + count2 = 0; |
| + |
| + var cursor1func = function() { |
| + var cursor = event.target.result; |
| + if (cursor === null) { |
| + shouldBe("count1", "kNumberOfItems"); |
| + cursor2.continue(); |
| + return; |
| + } |
| + |
| + if (cursor1 === null) { |
| + cursor1 = cursor; |
| + } |
| + |
| + if (cursor1.key !== count1) |
| + shouldBe("cursor1.key", "count1"); |
| + if (cursor1.value !== count1) |
| + shouldBe("cursor1.value", "count1"); |
| + |
| + ++count1; |
| + |
| + if (count1 % 20 === 0) { |
| + if (cursor2 !== null) { |
| + cursor2.continue(); |
| + } else { |
| + var req = store.openCursor(); |
| + req.onerror = unexpectedErrorCallback; |
| + req.onsuccess = cursor2func; |
| + } |
| + } else { |
| + cursor1.continue(); |
| + } |
| + } |
| + |
| + var cursor2func = function() { |
| + var cursor = event.target.result; |
| + if (cursor === null) { |
| + shouldBe("count2", "kNumberOfItems"); |
| + return; |
| + } |
| + |
| + if (cursor2 === null) { |
| + cursor2 = cursor; |
| + } |
| + |
| + if (cursor2.key !== count2) |
| + shouldBe("cursor2.key", "count2"); |
| + if (cursor2.value !== count2) |
| + shouldBe("cursor2.value", "count2"); |
| + |
| + ++count2; |
| + |
| + if (count2 % 20 === 0) { |
| + cursor1.continue(); |
| + } else { |
| + cursor2.continue(); |
| + } |
| + } |
| + |
| + var req = store.openCursor(); |
| + req.onerror = unexpectedErrorCallback; |
| + req.onsuccess = cursor1func; |
| +} |
| + |
| +function seventhTest() { |
| + debug("seventhTest()"); |
| + |
|
jsbell
2011/11/28 20:29:16
Add a comment about what this test is for.
hans
2011/11/29 14:44:34
Done.
|
| + var trans = db.transaction(['store'], webkitIDBTransaction.READ_WRITE); |
| + trans.onabort = unexpectedAbortCallback; |
| + trans.oncomplete = done; |
| + |
| + var store = trans.objectStore('store'); |
| + var index = store.index('index'); |
| + |
| + var cursorReq = index.openCursor(); |
| + cursorReq.onerror = unexpectedErrorCallback; |
| + count = 0; |
| + |
| + cursorReq.onsuccess = function() { |
| + cursor = event.target.result; |
| + if (cursor === null) { |
| + shouldBe("count", "kNumberOfItems"); |
| + return; |
| + } |
| + |
| + if (cursor.key !== count) |
| + shouldBe("cursor.key", "count"); |
| + if (cursor.primaryKey !== count) |
| + shouldBe("cursor.primaryKey", "count"); |
| + if (cursor.value !== count) |
| + shouldBe("cursor.value", "count"); |
| + |
| + ++count; |
| + cursor.continue(); |
| + } |
| +} |