Index: LayoutTests/storage/indexeddb/mozilla/resources/test_objectStore_openKeyCursor.js |
diff --git a/LayoutTests/storage/indexeddb/mozilla/resources/test_objectStore_openKeyCursor.js b/LayoutTests/storage/indexeddb/mozilla/resources/test_objectStore_openKeyCursor.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..85d938c6ece1a751c4329cc4c5cd502cd3521a50 |
--- /dev/null |
+++ b/LayoutTests/storage/indexeddb/mozilla/resources/test_objectStore_openKeyCursor.js |
@@ -0,0 +1,411 @@ |
+// Imported from: |
+// * http://mxr.mozilla.org/mozilla-central/source/dom/indexedDB/test/unit/test_objectStore_openKeyCursor.js |
+// Changes: |
+// * added 'use strict' since some ES6 features NYI w/o it |
+// * function -> function* |
+// * this.window -> window |
+// * Added deleteDatabase() step to reset storage state |
+ |
+'use strict'; |
+ |
+/** |
+ * Any copyright is dedicated to the Public Domain. |
+ * http://creativecommons.org/publicdomain/zero/1.0/ |
+ */ |
+ |
+let testGenerator = testSteps(); |
+ |
+function* testSteps() { |
+ const dbName = window ? |
+ window.location.pathname : |
+ "test_objectStore_openKeyCursor"; |
+ indexedDB.deleteDatabase(dbName); |
+ const dbVersion = 1; |
+ const objectStoreName = "foo"; |
+ const keyCount = 100; |
+ |
+ let request = indexedDB.open(dbName, dbVersion); |
+ request.onerror = errorHandler; |
+ request.onupgradeneeded = grabEventAndContinueHandler; |
+ request.onsuccess = unexpectedSuccessHandler; |
+ |
+ let event = yield undefined; |
+ |
+ info("Creating database"); |
+ |
+ let db = event.target.result; |
+ let objectStore = db.createObjectStore(objectStoreName); |
+ for (let i = 0; i < keyCount; i++) { |
+ objectStore.add(true, i); |
+ } |
+ |
+ request.onupgradeneeded = unexpectedSuccessHandler; |
+ request.onsuccess = grabEventAndContinueHandler; |
+ |
+ event = yield undefined; |
+ |
+ db = event.target.result; |
+ objectStore = db.transaction(objectStoreName, "readwrite") |
+ .objectStore(objectStoreName); |
+ |
+ info("Getting all keys"); |
+ objectStore.getAllKeys().onsuccess = grabEventAndContinueHandler; |
+ event = yield undefined; |
+ |
+ const allKeys = event.target.result; |
+ |
+ ok(Array.isArray(allKeys), "Got an array result"); |
+ is(allKeys.length, keyCount, "Got correct array length"); |
+ |
+ info("Opening normal key cursor"); |
+ |
+ let seenKeys = []; |
+ objectStore.openKeyCursor().onsuccess = event => { |
+ let cursor = event.target.result; |
+ if (!cursor) { |
+ continueToNextStepSync(); |
+ return; |
+ } |
+ |
+ is(cursor.source, objectStore, "Correct source"); |
+ is(cursor.direction, "next", "Correct direction"); |
+ |
+ let exception = null; |
+ try { |
+ cursor.update(10); |
+ } catch(e) { |
+ exception = e; |
+ } |
+ ok(!!exception, "update() throws for key cursor"); |
+ |
+ exception = null; |
+ try { |
+ cursor.delete(); |
+ } catch(e) { |
+ exception = e; |
+ } |
+ ok(!!exception, "delete() throws for key cursor"); |
+ |
+ is(cursor.key, cursor.primaryKey, "key and primaryKey match"); |
+ ok(!("value" in cursor), "No 'value' property on key cursor"); |
+ |
+ seenKeys.push(cursor.key); |
+ cursor.continue(); |
+ }; |
+ yield undefined; |
+ |
+ is(seenKeys.length, allKeys.length, "Saw the right number of keys"); |
+ |
+ let match = true; |
+ for (let i = 0; i < seenKeys.length; i++) { |
+ if (seenKeys[i] !== allKeys[i]) { |
+ match = false; |
+ break; |
+ } |
+ } |
+ ok(match, "All keys matched"); |
+ |
+ info("Opening key cursor with keyRange"); |
+ |
+ let keyRange = IDBKeyRange.bound(10, 20, false, true); |
+ |
+ seenKeys = []; |
+ objectStore.openKeyCursor(keyRange).onsuccess = event => { |
+ let cursor = event.target.result; |
+ if (!cursor) { |
+ continueToNextStepSync(); |
+ return; |
+ } |
+ |
+ is(cursor.source, objectStore, "Correct source"); |
+ is(cursor.direction, "next", "Correct direction"); |
+ |
+ let exception = null; |
+ try { |
+ cursor.update(10); |
+ } catch(e) { |
+ exception = e; |
+ } |
+ ok(!!exception, "update() throws for key cursor"); |
+ |
+ exception = null; |
+ try { |
+ cursor.delete(); |
+ } catch(e) { |
+ exception = e; |
+ } |
+ ok(!!exception, "delete() throws for key cursor"); |
+ |
+ is(cursor.key, cursor.primaryKey, "key and primaryKey match"); |
+ ok(!("value" in cursor), "No 'value' property on key cursor"); |
+ |
+ seenKeys.push(cursor.key); |
+ cursor.continue(); |
+ }; |
+ yield undefined; |
+ |
+ is(seenKeys.length, 10, "Saw the right number of keys"); |
+ |
+ match = true; |
+ for (let i = 0; i < seenKeys.length; i++) { |
+ if (seenKeys[i] !== allKeys[i + 10]) { |
+ match = false; |
+ break; |
+ } |
+ } |
+ ok(match, "All keys matched"); |
+ |
+ info("Opening key cursor with unmatched keyRange"); |
+ |
+ keyRange = IDBKeyRange.bound(10000, 200000); |
+ |
+ seenKeys = []; |
+ objectStore.openKeyCursor(keyRange).onsuccess = event => { |
+ let cursor = event.target.result; |
+ if (!cursor) { |
+ continueToNextStepSync(); |
+ return; |
+ } |
+ |
+ ok(false, "Shouldn't have any keys here"); |
+ cursor.continue(); |
+ }; |
+ yield undefined; |
+ |
+ is(seenKeys.length, 0, "Saw the right number of keys"); |
+ |
+ info("Opening reverse key cursor"); |
+ |
+ seenKeys = []; |
+ objectStore.openKeyCursor(null, "prev").onsuccess = event => { |
+ let cursor = event.target.result; |
+ if (!cursor) { |
+ continueToNextStepSync(); |
+ return; |
+ } |
+ |
+ is(cursor.source, objectStore, "Correct source"); |
+ is(cursor.direction, "prev", "Correct direction"); |
+ |
+ let exception = null; |
+ try { |
+ cursor.update(10); |
+ } catch(e) { |
+ exception = e; |
+ } |
+ ok(!!exception, "update() throws for key cursor"); |
+ |
+ exception = null; |
+ try { |
+ cursor.delete(); |
+ } catch(e) { |
+ exception = e; |
+ } |
+ ok(!!exception, "delete() throws for key cursor"); |
+ |
+ is(cursor.key, cursor.primaryKey, "key and primaryKey match"); |
+ ok(!("value" in cursor), "No 'value' property on key cursor"); |
+ |
+ seenKeys.push(cursor.key); |
+ cursor.continue(); |
+ }; |
+ yield undefined; |
+ |
+ is(seenKeys.length, allKeys.length, "Saw the right number of keys"); |
+ |
+ seenKeys.reverse(); |
+ |
+ match = true; |
+ for (let i = 0; i < seenKeys.length; i++) { |
+ if (seenKeys[i] !== allKeys[i]) { |
+ match = false; |
+ break; |
+ } |
+ } |
+ ok(match, "All keys matched"); |
+ |
+ info("Opening reverse key cursor with key range"); |
+ |
+ keyRange = IDBKeyRange.bound(10, 20, false, true); |
+ |
+ seenKeys = []; |
+ objectStore.openKeyCursor(keyRange, "prev").onsuccess = event => { |
+ let cursor = event.target.result; |
+ if (!cursor) { |
+ continueToNextStepSync(); |
+ return; |
+ } |
+ |
+ is(cursor.source, objectStore, "Correct source"); |
+ is(cursor.direction, "prev", "Correct direction"); |
+ |
+ let exception = null; |
+ try { |
+ cursor.update(10); |
+ } catch(e) { |
+ exception = e; |
+ } |
+ ok(!!exception, "update() throws for key cursor"); |
+ |
+ exception = null; |
+ try { |
+ cursor.delete(); |
+ } catch(e) { |
+ exception = e; |
+ } |
+ ok(!!exception, "delete() throws for key cursor"); |
+ |
+ is(cursor.key, cursor.primaryKey, "key and primaryKey match"); |
+ ok(!("value" in cursor), "No 'value' property on key cursor"); |
+ |
+ seenKeys.push(cursor.key); |
+ cursor.continue(); |
+ }; |
+ yield undefined; |
+ |
+ is(seenKeys.length, 10, "Saw the right number of keys"); |
+ |
+ seenKeys.reverse(); |
+ |
+ match = true; |
+ for (let i = 0; i < 10; i++) { |
+ if (seenKeys[i] !== allKeys[i + 10]) { |
+ match = false; |
+ break; |
+ } |
+ } |
+ ok(match, "All keys matched"); |
+ |
+ info("Opening reverse key cursor with unmatched key range"); |
+ |
+ keyRange = IDBKeyRange.bound(10000, 200000); |
+ |
+ seenKeys = []; |
+ objectStore.openKeyCursor(keyRange, "prev").onsuccess = event => { |
+ let cursor = event.target.result; |
+ if (!cursor) { |
+ continueToNextStepSync(); |
+ return; |
+ } |
+ |
+ ok(false, "Shouldn't have any keys here"); |
+ cursor.continue(); |
+ }; |
+ yield undefined; |
+ |
+ is(seenKeys.length, 0, "Saw the right number of keys"); |
+ |
+ info("Opening key cursor with advance"); |
+ |
+ seenKeys = []; |
+ objectStore.openKeyCursor().onsuccess = event => { |
+ let cursor = event.target.result; |
+ if (!cursor) { |
+ continueToNextStepSync(); |
+ return; |
+ } |
+ |
+ is(cursor.source, objectStore, "Correct source"); |
+ is(cursor.direction, "next", "Correct direction"); |
+ |
+ let exception = null; |
+ try { |
+ cursor.update(10); |
+ } catch(e) { |
+ exception = e; |
+ } |
+ ok(!!exception, "update() throws for key cursor"); |
+ |
+ exception = null; |
+ try { |
+ cursor.delete(); |
+ } catch(e) { |
+ exception = e; |
+ } |
+ ok(!!exception, "delete() throws for key cursor"); |
+ |
+ is(cursor.key, cursor.primaryKey, "key and primaryKey match"); |
+ ok(!("value" in cursor), "No 'value' property on key cursor"); |
+ |
+ seenKeys.push(cursor.key); |
+ if (seenKeys.length == 1) { |
+ cursor.advance(10); |
+ } else { |
+ cursor.continue(); |
+ } |
+ }; |
+ yield undefined; |
+ |
+ is(seenKeys.length, allKeys.length - 9, "Saw the right number of keys"); |
+ |
+ match = true; |
+ for (let i = 0, j = 0; i < seenKeys.length; i++) { |
+ if (seenKeys[i] !== allKeys[i + j]) { |
+ match = false; |
+ break; |
+ } |
+ if (i == 0) { |
+ j = 9; |
+ } |
+ } |
+ ok(match, "All keys matched"); |
+ |
+ info("Opening key cursor with continue-to-key"); |
+ |
+ seenKeys = []; |
+ objectStore.openKeyCursor().onsuccess = event => { |
+ let cursor = event.target.result; |
+ if (!cursor) { |
+ continueToNextStepSync(); |
+ return; |
+ } |
+ |
+ is(cursor.source, objectStore, "Correct source"); |
+ is(cursor.direction, "next", "Correct direction"); |
+ |
+ let exception = null; |
+ try { |
+ cursor.update(10); |
+ } catch(e) { |
+ exception = e; |
+ } |
+ ok(!!exception, "update() throws for key cursor"); |
+ |
+ exception = null; |
+ try { |
+ cursor.delete(); |
+ } catch(e) { |
+ exception = e; |
+ } |
+ ok(!!exception, "delete() throws for key cursor"); |
+ |
+ is(cursor.key, cursor.primaryKey, "key and primaryKey match"); |
+ ok(!("value" in cursor), "No 'value' property on key cursor"); |
+ |
+ seenKeys.push(cursor.key); |
+ |
+ if (seenKeys.length == 1) { |
+ cursor.continue(10); |
+ } else { |
+ cursor.continue(); |
+ } |
+ }; |
+ yield undefined; |
+ |
+ is(seenKeys.length, allKeys.length - 9, "Saw the right number of keys"); |
+ |
+ match = true; |
+ for (let i = 0, j = 0; i < seenKeys.length; i++) { |
+ if (seenKeys[i] !== allKeys[i + j]) { |
+ match = false; |
+ break; |
+ } |
+ if (i == 0) { |
+ j = 9; |
+ } |
+ } |
+ ok(match, "All keys matched"); |
+ |
+ finishTest(); |
+ yield undefined; |
+} |