michael@0: /** michael@0: * Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ michael@0: */ michael@0: michael@0: let testGenerator = testSteps(); michael@0: michael@0: function testSteps() { michael@0: const dbName = this.window ? michael@0: window.location.pathname : michael@0: "test_objectStore_openKeyCursor"; michael@0: const dbVersion = 1; michael@0: const objectStoreName = "foo"; michael@0: const keyCount = 100; michael@0: michael@0: let request = indexedDB.open(dbName, dbVersion); michael@0: request.onerror = errorHandler; michael@0: request.onupgradeneeded = grabEventAndContinueHandler; michael@0: request.onsuccess = unexpectedSuccessHandler; michael@0: michael@0: let event = yield undefined; michael@0: michael@0: info("Creating database"); michael@0: michael@0: let db = event.target.result; michael@0: let objectStore = db.createObjectStore(objectStoreName); michael@0: for (let i = 0; i < keyCount; i++) { michael@0: objectStore.add(true, i); michael@0: } michael@0: michael@0: request.onupgradeneeded = unexpectedSuccessHandler; michael@0: request.onsuccess = grabEventAndContinueHandler; michael@0: michael@0: event = yield undefined; michael@0: michael@0: db = event.target.result; michael@0: objectStore = db.transaction(objectStoreName, "readwrite") michael@0: .objectStore(objectStoreName); michael@0: michael@0: info("Getting all keys"); michael@0: objectStore.getAllKeys().onsuccess = grabEventAndContinueHandler; michael@0: event = yield undefined; michael@0: michael@0: const allKeys = event.target.result; michael@0: michael@0: ok(Array.isArray(allKeys), "Got an array result"); michael@0: is(allKeys.length, keyCount, "Got correct array length"); michael@0: michael@0: info("Opening normal key cursor"); michael@0: michael@0: let seenKeys = []; michael@0: objectStore.openKeyCursor().onsuccess = event => { michael@0: let cursor = event.target.result; michael@0: if (!cursor) { michael@0: continueToNextStepSync(); michael@0: return; michael@0: } michael@0: michael@0: is(cursor.source, objectStore, "Correct source"); michael@0: is(cursor.direction, "next", "Correct direction"); michael@0: michael@0: let exception = null; michael@0: try { michael@0: cursor.update(10); michael@0: } catch(e) { michael@0: exception = e; michael@0: } michael@0: ok(!!exception, "update() throws for key cursor"); michael@0: michael@0: exception = null; michael@0: try { michael@0: cursor.delete(); michael@0: } catch(e) { michael@0: exception = e; michael@0: } michael@0: ok(!!exception, "delete() throws for key cursor"); michael@0: michael@0: is(cursor.key, cursor.primaryKey, "key and primaryKey match"); michael@0: ok(!("value" in cursor), "No 'value' property on key cursor"); michael@0: michael@0: seenKeys.push(cursor.key); michael@0: cursor.continue(); michael@0: }; michael@0: yield undefined; michael@0: michael@0: is(seenKeys.length, allKeys.length, "Saw the right number of keys"); michael@0: michael@0: let match = true; michael@0: for (let i = 0; i < seenKeys.length; i++) { michael@0: if (seenKeys[i] !== allKeys[i]) { michael@0: match = false; michael@0: break; michael@0: } michael@0: } michael@0: ok(match, "All keys matched"); michael@0: michael@0: info("Opening key cursor with keyRange"); michael@0: michael@0: let keyRange = IDBKeyRange.bound(10, 20, false, true); michael@0: michael@0: seenKeys = []; michael@0: objectStore.openKeyCursor(keyRange).onsuccess = event => { michael@0: let cursor = event.target.result; michael@0: if (!cursor) { michael@0: continueToNextStepSync(); michael@0: return; michael@0: } michael@0: michael@0: is(cursor.source, objectStore, "Correct source"); michael@0: is(cursor.direction, "next", "Correct direction"); michael@0: michael@0: let exception = null; michael@0: try { michael@0: cursor.update(10); michael@0: } catch(e) { michael@0: exception = e; michael@0: } michael@0: ok(!!exception, "update() throws for key cursor"); michael@0: michael@0: exception = null; michael@0: try { michael@0: cursor.delete(); michael@0: } catch(e) { michael@0: exception = e; michael@0: } michael@0: ok(!!exception, "delete() throws for key cursor"); michael@0: michael@0: is(cursor.key, cursor.primaryKey, "key and primaryKey match"); michael@0: ok(!("value" in cursor), "No 'value' property on key cursor"); michael@0: michael@0: seenKeys.push(cursor.key); michael@0: cursor.continue(); michael@0: }; michael@0: yield undefined; michael@0: michael@0: is(seenKeys.length, 10, "Saw the right number of keys"); michael@0: michael@0: match = true; michael@0: for (let i = 0; i < seenKeys.length; i++) { michael@0: if (seenKeys[i] !== allKeys[i + 10]) { michael@0: match = false; michael@0: break; michael@0: } michael@0: } michael@0: ok(match, "All keys matched"); michael@0: michael@0: info("Opening key cursor with unmatched keyRange"); michael@0: michael@0: keyRange = IDBKeyRange.bound(10000, 200000); michael@0: michael@0: seenKeys = []; michael@0: objectStore.openKeyCursor(keyRange).onsuccess = event => { michael@0: let cursor = event.target.result; michael@0: if (!cursor) { michael@0: continueToNextStepSync(); michael@0: return; michael@0: } michael@0: michael@0: ok(false, "Shouldn't have any keys here"); michael@0: cursor.continue(); michael@0: }; michael@0: yield undefined; michael@0: michael@0: is(seenKeys.length, 0, "Saw the right number of keys"); michael@0: michael@0: info("Opening reverse key cursor"); michael@0: michael@0: seenKeys = []; michael@0: objectStore.openKeyCursor(null, "prev").onsuccess = event => { michael@0: let cursor = event.target.result; michael@0: if (!cursor) { michael@0: continueToNextStepSync(); michael@0: return; michael@0: } michael@0: michael@0: is(cursor.source, objectStore, "Correct source"); michael@0: is(cursor.direction, "prev", "Correct direction"); michael@0: michael@0: let exception = null; michael@0: try { michael@0: cursor.update(10); michael@0: } catch(e) { michael@0: exception = e; michael@0: } michael@0: ok(!!exception, "update() throws for key cursor"); michael@0: michael@0: exception = null; michael@0: try { michael@0: cursor.delete(); michael@0: } catch(e) { michael@0: exception = e; michael@0: } michael@0: ok(!!exception, "delete() throws for key cursor"); michael@0: michael@0: is(cursor.key, cursor.primaryKey, "key and primaryKey match"); michael@0: ok(!("value" in cursor), "No 'value' property on key cursor"); michael@0: michael@0: seenKeys.push(cursor.key); michael@0: cursor.continue(); michael@0: }; michael@0: yield undefined; michael@0: michael@0: is(seenKeys.length, allKeys.length, "Saw the right number of keys"); michael@0: michael@0: seenKeys.reverse(); michael@0: michael@0: match = true; michael@0: for (let i = 0; i < seenKeys.length; i++) { michael@0: if (seenKeys[i] !== allKeys[i]) { michael@0: match = false; michael@0: break; michael@0: } michael@0: } michael@0: ok(match, "All keys matched"); michael@0: michael@0: info("Opening reverse key cursor with key range"); michael@0: michael@0: keyRange = IDBKeyRange.bound(10, 20, false, true); michael@0: michael@0: seenKeys = []; michael@0: objectStore.openKeyCursor(keyRange, "prev").onsuccess = event => { michael@0: let cursor = event.target.result; michael@0: if (!cursor) { michael@0: continueToNextStepSync(); michael@0: return; michael@0: } michael@0: michael@0: is(cursor.source, objectStore, "Correct source"); michael@0: is(cursor.direction, "prev", "Correct direction"); michael@0: michael@0: let exception = null; michael@0: try { michael@0: cursor.update(10); michael@0: } catch(e) { michael@0: exception = e; michael@0: } michael@0: ok(!!exception, "update() throws for key cursor"); michael@0: michael@0: exception = null; michael@0: try { michael@0: cursor.delete(); michael@0: } catch(e) { michael@0: exception = e; michael@0: } michael@0: ok(!!exception, "delete() throws for key cursor"); michael@0: michael@0: is(cursor.key, cursor.primaryKey, "key and primaryKey match"); michael@0: ok(!("value" in cursor), "No 'value' property on key cursor"); michael@0: michael@0: seenKeys.push(cursor.key); michael@0: cursor.continue(); michael@0: }; michael@0: yield undefined; michael@0: michael@0: is(seenKeys.length, 10, "Saw the right number of keys"); michael@0: michael@0: seenKeys.reverse(); michael@0: michael@0: match = true; michael@0: for (let i = 0; i < 10; i++) { michael@0: if (seenKeys[i] !== allKeys[i + 10]) { michael@0: match = false; michael@0: break; michael@0: } michael@0: } michael@0: ok(match, "All keys matched"); michael@0: michael@0: info("Opening reverse key cursor with unmatched key range"); michael@0: michael@0: keyRange = IDBKeyRange.bound(10000, 200000); michael@0: michael@0: seenKeys = []; michael@0: objectStore.openKeyCursor(keyRange, "prev").onsuccess = event => { michael@0: let cursor = event.target.result; michael@0: if (!cursor) { michael@0: continueToNextStepSync(); michael@0: return; michael@0: } michael@0: michael@0: ok(false, "Shouldn't have any keys here"); michael@0: cursor.continue(); michael@0: }; michael@0: yield undefined; michael@0: michael@0: is(seenKeys.length, 0, "Saw the right number of keys"); michael@0: michael@0: info("Opening key cursor with advance"); michael@0: michael@0: seenKeys = []; michael@0: objectStore.openKeyCursor().onsuccess = event => { michael@0: let cursor = event.target.result; michael@0: if (!cursor) { michael@0: continueToNextStepSync(); michael@0: return; michael@0: } michael@0: michael@0: is(cursor.source, objectStore, "Correct source"); michael@0: is(cursor.direction, "next", "Correct direction"); michael@0: michael@0: let exception = null; michael@0: try { michael@0: cursor.update(10); michael@0: } catch(e) { michael@0: exception = e; michael@0: } michael@0: ok(!!exception, "update() throws for key cursor"); michael@0: michael@0: exception = null; michael@0: try { michael@0: cursor.delete(); michael@0: } catch(e) { michael@0: exception = e; michael@0: } michael@0: ok(!!exception, "delete() throws for key cursor"); michael@0: michael@0: is(cursor.key, cursor.primaryKey, "key and primaryKey match"); michael@0: ok(!("value" in cursor), "No 'value' property on key cursor"); michael@0: michael@0: seenKeys.push(cursor.key); michael@0: if (seenKeys.length == 1) { michael@0: cursor.advance(10); michael@0: } else { michael@0: cursor.continue(); michael@0: } michael@0: }; michael@0: yield undefined; michael@0: michael@0: is(seenKeys.length, allKeys.length - 9, "Saw the right number of keys"); michael@0: michael@0: let match = true; michael@0: for (let i = 0, j = 0; i < seenKeys.length; i++) { michael@0: if (seenKeys[i] !== allKeys[i + j]) { michael@0: match = false; michael@0: break; michael@0: } michael@0: if (i == 0) { michael@0: j = 9; michael@0: } michael@0: } michael@0: ok(match, "All keys matched"); michael@0: michael@0: info("Opening key cursor with continue-to-key"); michael@0: michael@0: seenKeys = []; michael@0: objectStore.openKeyCursor().onsuccess = event => { michael@0: let cursor = event.target.result; michael@0: if (!cursor) { michael@0: continueToNextStepSync(); michael@0: return; michael@0: } michael@0: michael@0: is(cursor.source, objectStore, "Correct source"); michael@0: is(cursor.direction, "next", "Correct direction"); michael@0: michael@0: let exception = null; michael@0: try { michael@0: cursor.update(10); michael@0: } catch(e) { michael@0: exception = e; michael@0: } michael@0: ok(!!exception, "update() throws for key cursor"); michael@0: michael@0: exception = null; michael@0: try { michael@0: cursor.delete(); michael@0: } catch(e) { michael@0: exception = e; michael@0: } michael@0: ok(!!exception, "delete() throws for key cursor"); michael@0: michael@0: is(cursor.key, cursor.primaryKey, "key and primaryKey match"); michael@0: ok(!("value" in cursor), "No 'value' property on key cursor"); michael@0: michael@0: seenKeys.push(cursor.key); michael@0: michael@0: if (seenKeys.length == 1) { michael@0: cursor.continue(10); michael@0: } else { michael@0: cursor.continue(); michael@0: } michael@0: }; michael@0: yield undefined; michael@0: michael@0: is(seenKeys.length, allKeys.length - 9, "Saw the right number of keys"); michael@0: michael@0: let match = true; michael@0: for (let i = 0, j = 0; i < seenKeys.length; i++) { michael@0: if (seenKeys[i] !== allKeys[i + j]) { michael@0: match = false; michael@0: break; michael@0: } michael@0: if (i == 0) { michael@0: j = 9; michael@0: } michael@0: } michael@0: ok(match, "All keys matched"); michael@0: michael@0: finishTest(); michael@0: yield undefined; michael@0: }