summaryrefslogtreecommitdiffstats
path: root/dom/indexedDB/test/unit/test_autoIncrement.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/indexedDB/test/unit/test_autoIncrement.js')
-rw-r--r--dom/indexedDB/test/unit/test_autoIncrement.js588
1 files changed, 588 insertions, 0 deletions
diff --git a/dom/indexedDB/test/unit/test_autoIncrement.js b/dom/indexedDB/test/unit/test_autoIncrement.js
new file mode 100644
index 0000000000..6f502deaf0
--- /dev/null
+++ b/dom/indexedDB/test/unit/test_autoIncrement.js
@@ -0,0 +1,588 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+/* exported testGenerator, disableWorkerTest */
+var disableWorkerTest = "Need to implement a gc() function for worker tests";
+
+if (!this.window) {
+ this.runTest = function () {
+ todo(false, "Test disabled in xpcshell test suite for now");
+ finishTest();
+ };
+}
+
+var testGenerator = testSteps();
+
+function genCheck(key, value, test, options) {
+ return function (event) {
+ is(
+ JSON.stringify(event.target.result),
+ JSON.stringify(key),
+ "correct returned key in " + test
+ );
+ if (options && options.store) {
+ is(event.target.source, options.store, "correct store in " + test);
+ }
+ if (options && options.trans) {
+ is(
+ event.target.transaction,
+ options.trans,
+ "correct transaction in " + test
+ );
+ }
+
+ event.target.source.get(key).onsuccess = function (event) {
+ is(
+ JSON.stringify(event.target.result),
+ JSON.stringify(value),
+ "correct stored value in " + test
+ );
+ continueToNextStepSync();
+ };
+ };
+}
+
+function* testSteps() {
+ const dbname = this.window ? window.location.pathname : "Splendid Test";
+ const RW = "readwrite";
+ let c1 = 1;
+ let c2 = 1;
+
+ let openRequest = indexedDB.open(dbname, 1);
+ openRequest.onerror = errorHandler;
+ openRequest.onupgradeneeded = grabEventAndContinueHandler;
+ openRequest.onsuccess = unexpectedSuccessHandler;
+ let event = yield undefined;
+ let db = event.target.result;
+ let trans = event.target.transaction;
+
+ // Create test stores
+ let store1 = db.createObjectStore("store1", { autoIncrement: true });
+ let store2 = db.createObjectStore("store2", {
+ autoIncrement: true,
+ keyPath: "id",
+ });
+ let store3 = db.createObjectStore("store3", { autoIncrement: false });
+ is(store1.autoIncrement, true, "store1 .autoIncrement");
+ is(store2.autoIncrement, true, "store2 .autoIncrement");
+ is(store3.autoIncrement, false, "store3 .autoIncrement");
+
+ store1.createIndex("unique1", "unique", { unique: true });
+ store2.createIndex("unique1", "unique", { unique: true });
+
+ // Test simple inserts
+ let test = " for test simple insert";
+ store1.add({ foo: "value1" }).onsuccess = genCheck(
+ c1++,
+ { foo: "value1" },
+ "first" + test
+ );
+ store1.add({ foo: "value2" }).onsuccess = genCheck(
+ c1++,
+ { foo: "value2" },
+ "second" + test
+ );
+
+ yield undefined;
+ yield undefined;
+
+ store2.put({ bar: "value1" }).onsuccess = genCheck(
+ c2,
+ { bar: "value1", id: c2 },
+ "first in store2" + test,
+ { store: store2 }
+ );
+ c2++;
+ store1.put({ foo: "value3" }).onsuccess = genCheck(
+ c1++,
+ { foo: "value3" },
+ "third" + test,
+ { store: store1 }
+ );
+
+ yield undefined;
+ yield undefined;
+
+ store2.get(IDBKeyRange.lowerBound(c2)).onsuccess =
+ grabEventAndContinueHandler;
+ event = yield undefined;
+ is(event.target.result, undefined, "no such value" + test);
+
+ // Close version_change transaction
+ openRequest.onsuccess = grabEventAndContinueHandler;
+ event = yield undefined;
+
+ is(event.target, openRequest, "succeeded to open" + test);
+ is(event.type, "success", "succeeded to open" + test);
+
+ // Test inserting explicit keys
+ test = " for test explicit keys";
+ trans = db.transaction("store1", RW);
+ trans.objectStore("store1").add({ explicit: 1 }, 100).onsuccess = genCheck(
+ 100,
+ { explicit: 1 },
+ "first" + test
+ );
+ c1 = 101;
+ trans = db.transaction("store1", RW);
+ trans.objectStore("store1").add({ explicit: 2 }).onsuccess = genCheck(
+ c1++,
+ { explicit: 2 },
+ "second" + test
+ );
+ yield undefined;
+ yield undefined;
+
+ trans = db.transaction("store1", RW);
+ trans.objectStore("store1").add({ explicit: 3 }, 200).onsuccess = genCheck(
+ 200,
+ { explicit: 3 },
+ "third" + test
+ );
+ c1 = 201;
+ trans.objectStore("store1").add({ explicit: 4 }).onsuccess = genCheck(
+ c1++,
+ { explicit: 4 },
+ "fourth" + test
+ );
+ yield undefined;
+ yield undefined;
+
+ trans = db.transaction("store1", RW);
+ trans.objectStore("store1").add({ explicit: 5 }, 150).onsuccess = genCheck(
+ 150,
+ { explicit: 5 },
+ "fifth" + test
+ );
+ yield undefined;
+ trans.objectStore("store1").add({ explicit: 6 }).onsuccess = genCheck(
+ c1++,
+ { explicit: 6 },
+ "sixth" + test
+ );
+ yield undefined;
+
+ trans = db.transaction("store1", RW);
+ trans.objectStore("store1").add({ explicit: 7 }, "key").onsuccess = genCheck(
+ "key",
+ { explicit: 7 },
+ "seventh" + test
+ );
+ yield undefined;
+ trans.objectStore("store1").add({ explicit: 8 }).onsuccess = genCheck(
+ c1++,
+ { explicit: 8 },
+ "eighth" + test
+ );
+ yield undefined;
+
+ trans = db.transaction("store1", RW);
+ trans.objectStore("store1").add({ explicit: 7 }, [100000]).onsuccess =
+ genCheck([100000], { explicit: 7 }, "seventh" + test);
+ yield undefined;
+ trans.objectStore("store1").add({ explicit: 8 }).onsuccess = genCheck(
+ c1++,
+ { explicit: 8 },
+ "eighth" + test
+ );
+ yield undefined;
+
+ trans = db.transaction("store1", RW);
+ trans.objectStore("store1").add({ explicit: 9 }, -100000).onsuccess =
+ genCheck(-100000, { explicit: 9 }, "ninth" + test);
+ yield undefined;
+ trans.objectStore("store1").add({ explicit: 10 }).onsuccess = genCheck(
+ c1++,
+ { explicit: 10 },
+ "tenth" + test
+ );
+ yield undefined;
+
+ trans = db.transaction("store2", RW);
+ trans.objectStore("store2").add({ explicit2: 1, id: 300 }).onsuccess =
+ genCheck(300, { explicit2: 1, id: 300 }, "first store2" + test);
+ c2 = 301;
+ trans = db.transaction("store2", RW);
+ trans.objectStore("store2").add({ explicit2: 2 }).onsuccess = genCheck(
+ c2,
+ { explicit2: 2, id: c2 },
+ "second store2" + test
+ );
+ c2++;
+ yield undefined;
+ yield undefined;
+
+ trans = db.transaction("store2", RW);
+ trans.objectStore("store2").add({ explicit2: 3, id: 400 }).onsuccess =
+ genCheck(400, { explicit2: 3, id: 400 }, "third store2" + test);
+ c2 = 401;
+ trans.objectStore("store2").add({ explicit2: 4 }).onsuccess = genCheck(
+ c2,
+ { explicit2: 4, id: c2 },
+ "fourth store2" + test
+ );
+ c2++;
+ yield undefined;
+ yield undefined;
+
+ trans = db.transaction("store2", RW);
+ trans.objectStore("store2").add({ explicit: 5, id: 150 }).onsuccess =
+ genCheck(150, { explicit: 5, id: 150 }, "fifth store2" + test);
+ yield undefined;
+ trans.objectStore("store2").add({ explicit: 6 }).onsuccess = genCheck(
+ c2,
+ { explicit: 6, id: c2 },
+ "sixth store2" + test
+ );
+ c2++;
+ yield undefined;
+
+ trans = db.transaction("store2", RW);
+ trans.objectStore("store2").add({ explicit: 7, id: "key" }).onsuccess =
+ genCheck("key", { explicit: 7, id: "key" }, "seventh store2" + test);
+ yield undefined;
+ trans.objectStore("store2").add({ explicit: 8 }).onsuccess = genCheck(
+ c2,
+ { explicit: 8, id: c2 },
+ "eighth store2" + test
+ );
+ c2++;
+ yield undefined;
+
+ trans = db.transaction("store2", RW);
+ trans.objectStore("store2").add({ explicit: 7, id: [100000] }).onsuccess =
+ genCheck([100000], { explicit: 7, id: [100000] }, "seventh store2" + test);
+ yield undefined;
+ trans.objectStore("store2").add({ explicit: 8 }).onsuccess = genCheck(
+ c2,
+ { explicit: 8, id: c2 },
+ "eighth store2" + test
+ );
+ c2++;
+ yield undefined;
+
+ trans = db.transaction("store2", RW);
+ trans.objectStore("store2").add({ explicit: 9, id: -100000 }).onsuccess =
+ genCheck(-100000, { explicit: 9, id: -100000 }, "ninth store2" + test);
+ yield undefined;
+ trans.objectStore("store2").add({ explicit: 10 }).onsuccess = genCheck(
+ c2,
+ { explicit: 10, id: c2 },
+ "tenth store2" + test
+ );
+ c2++;
+ yield undefined;
+
+ // Test separate transactions doesn't generate overlapping numbers
+ test = " for test non-overlapping counts";
+ trans = db.transaction("store1", RW);
+ let trans2 = db.transaction("store1", RW);
+ trans2.objectStore("store1").put({ over: 2 }).onsuccess = genCheck(
+ c1 + 1,
+ { over: 2 },
+ "first" + test,
+ { trans: trans2 }
+ );
+ trans.objectStore("store1").put({ over: 1 }).onsuccess = genCheck(
+ c1,
+ { over: 1 },
+ "second" + test,
+ { trans }
+ );
+ c1 += 2;
+ yield undefined;
+ yield undefined;
+
+ trans = db.transaction("store2", RW);
+ trans2 = db.transaction("store2", RW);
+ trans2.objectStore("store2").put({ over: 2 }).onsuccess = genCheck(
+ c2 + 1,
+ { over: 2, id: c2 + 1 },
+ "third" + test,
+ { trans: trans2 }
+ );
+ trans.objectStore("store2").put({ over: 1 }).onsuccess = genCheck(
+ c2,
+ { over: 1, id: c2 },
+ "fourth" + test,
+ { trans }
+ );
+ c2 += 2;
+ yield undefined;
+ yield undefined;
+
+ // Test that error inserts doesn't increase generator
+ test = " for test error inserts";
+ trans = db.transaction(["store1", "store2"], RW);
+ trans.objectStore("store1").add({ unique: 1 }, -1);
+ trans.objectStore("store2").add({ unique: 1, id: "unique" });
+
+ trans
+ .objectStore("store1")
+ .add({ error: 1, unique: 1 })
+ .addEventListener("error", new ExpectError("ConstraintError", true));
+ trans.objectStore("store1").add({ error: 2 }).onsuccess = genCheck(
+ c1++,
+ { error: 2 },
+ "first" + test
+ );
+ yield undefined;
+ yield undefined;
+
+ trans
+ .objectStore("store2")
+ .add({ error: 3, unique: 1 })
+ .addEventListener("error", new ExpectError("ConstraintError", true));
+ trans.objectStore("store2").add({ error: 4 }).onsuccess = genCheck(
+ c2,
+ { error: 4, id: c2 },
+ "second" + test
+ );
+ c2++;
+ yield undefined;
+ yield undefined;
+
+ trans
+ .objectStore("store1")
+ .add({ error: 5, unique: 1 }, 100000)
+ .addEventListener("error", new ExpectError("ConstraintError", true));
+ trans.objectStore("store1").add({ error: 6 }).onsuccess = genCheck(
+ c1++,
+ { error: 6 },
+ "third" + test
+ );
+ yield undefined;
+ yield undefined;
+
+ trans
+ .objectStore("store2")
+ .add({ error: 7, unique: 1, id: 100000 })
+ .addEventListener("error", new ExpectError("ConstraintError", true));
+ trans.objectStore("store2").add({ error: 8 }).onsuccess = genCheck(
+ c2,
+ { error: 8, id: c2 },
+ "fourth" + test
+ );
+ c2++;
+ yield undefined;
+ yield undefined;
+
+ // Test that aborts doesn't increase generator
+ test = " for test aborted transaction";
+ trans = db.transaction(["store1", "store2"], RW);
+ trans.objectStore("store1").add({ abort: 1 }).onsuccess = genCheck(
+ c1,
+ { abort: 1 },
+ "first" + test
+ );
+ trans.objectStore("store2").put({ abort: 2 }).onsuccess = genCheck(
+ c2,
+ { abort: 2, id: c2 },
+ "second" + test
+ );
+ yield undefined;
+ yield undefined;
+
+ trans.objectStore("store1").add({ abort: 3 }, 500).onsuccess = genCheck(
+ 500,
+ { abort: 3 },
+ "third" + test
+ );
+ trans.objectStore("store2").put({ abort: 4, id: 600 }).onsuccess = genCheck(
+ 600,
+ { abort: 4, id: 600 },
+ "fourth" + test
+ );
+ yield undefined;
+ yield undefined;
+
+ trans.objectStore("store1").add({ abort: 5 }).onsuccess = genCheck(
+ 501,
+ { abort: 5 },
+ "fifth" + test
+ );
+ trans.objectStore("store2").put({ abort: 6 }).onsuccess = genCheck(
+ 601,
+ { abort: 6, id: 601 },
+ "sixth" + test
+ );
+ yield undefined;
+ yield undefined;
+
+ trans.abort();
+ trans.onabort = grabEventAndContinueHandler;
+ event = yield;
+ is(event.type, "abort", "transaction aborted");
+ is(event.target, trans, "correct transaction aborted");
+
+ trans = db.transaction(["store1", "store2"], RW);
+ trans.objectStore("store1").add({ abort: 1 }).onsuccess = genCheck(
+ c1++,
+ { abort: 1 },
+ "re-first" + test
+ );
+ trans.objectStore("store2").put({ abort: 2 }).onsuccess = genCheck(
+ c2,
+ { abort: 2, id: c2 },
+ "re-second" + test
+ );
+ c2++;
+ yield undefined;
+ yield undefined;
+
+ // Test that delete doesn't decrease generator
+ test = " for test delete items";
+ trans = db.transaction(["store1", "store2"], RW);
+ trans.objectStore("store1").add({ delete: 1 }).onsuccess = genCheck(
+ c1++,
+ { delete: 1 },
+ "first" + test
+ );
+ trans.objectStore("store2").put({ delete: 2 }).onsuccess = genCheck(
+ c2,
+ { delete: 2, id: c2 },
+ "second" + test
+ );
+ c2++;
+ yield undefined;
+ yield undefined;
+
+ trans.objectStore("store1").delete(c1 - 1).onsuccess =
+ grabEventAndContinueHandler;
+ trans.objectStore("store2").delete(c2 - 1).onsuccess =
+ grabEventAndContinueHandler;
+ yield undefined;
+ yield undefined;
+
+ trans.objectStore("store1").add({ delete: 3 }).onsuccess = genCheck(
+ c1++,
+ { delete: 3 },
+ "first" + test
+ );
+ trans.objectStore("store2").put({ delete: 4 }).onsuccess = genCheck(
+ c2,
+ { delete: 4, id: c2 },
+ "second" + test
+ );
+ c2++;
+ yield undefined;
+ yield undefined;
+
+ trans.objectStore("store1").delete(c1 - 1).onsuccess =
+ grabEventAndContinueHandler;
+ trans.objectStore("store2").delete(c2 - 1).onsuccess =
+ grabEventAndContinueHandler;
+ yield undefined;
+ yield undefined;
+
+ trans = db.transaction(["store1", "store2"], RW);
+ trans.objectStore("store1").add({ delete: 5 }).onsuccess = genCheck(
+ c1++,
+ { delete: 5 },
+ "first" + test
+ );
+ trans.objectStore("store2").put({ delete: 6 }).onsuccess = genCheck(
+ c2,
+ { delete: 6, id: c2 },
+ "second" + test
+ );
+ c2++;
+ yield undefined;
+ yield undefined;
+
+ // Test that clears doesn't decrease generator
+ test = " for test clear stores";
+ trans = db.transaction(["store1", "store2"], RW);
+ trans.objectStore("store1").add({ clear: 1 }).onsuccess = genCheck(
+ c1++,
+ { clear: 1 },
+ "first" + test
+ );
+ trans.objectStore("store2").put({ clear: 2 }).onsuccess = genCheck(
+ c2,
+ { clear: 2, id: c2 },
+ "second" + test
+ );
+ c2++;
+ yield undefined;
+ yield undefined;
+
+ trans.objectStore("store1").clear().onsuccess = grabEventAndContinueHandler;
+ trans.objectStore("store2").clear().onsuccess = grabEventAndContinueHandler;
+ yield undefined;
+ yield undefined;
+
+ trans.objectStore("store1").add({ clear: 3 }).onsuccess = genCheck(
+ c1++,
+ { clear: 3 },
+ "third" + test
+ );
+ trans.objectStore("store2").put({ clear: 4 }).onsuccess = genCheck(
+ c2,
+ { clear: 4, id: c2 },
+ "forth" + test
+ );
+ c2++;
+ yield undefined;
+ yield undefined;
+
+ trans.objectStore("store1").clear().onsuccess = grabEventAndContinueHandler;
+ trans.objectStore("store2").clear().onsuccess = grabEventAndContinueHandler;
+ yield undefined;
+ yield undefined;
+
+ trans = db.transaction(["store1", "store2"], RW);
+ trans.objectStore("store1").add({ clear: 5 }).onsuccess = genCheck(
+ c1++,
+ { clear: 5 },
+ "fifth" + test
+ );
+ trans.objectStore("store2").put({ clear: 6 }).onsuccess = genCheck(
+ c2,
+ { clear: 6, id: c2 },
+ "sixth" + test
+ );
+ c2++;
+ yield undefined;
+ yield undefined;
+
+ // Test that close/reopen doesn't decrease generator
+ test = " for test clear stores";
+ trans = db.transaction(["store1", "store2"], RW);
+ trans.objectStore("store1").clear().onsuccess = grabEventAndContinueHandler;
+ trans.objectStore("store2").clear().onsuccess = grabEventAndContinueHandler;
+ yield undefined;
+ yield undefined;
+ db.close();
+
+ gc();
+
+ openRequest = indexedDB.open(dbname, 2);
+ openRequest.onerror = errorHandler;
+ openRequest.onupgradeneeded = grabEventAndContinueHandler;
+ openRequest.onsuccess = unexpectedSuccessHandler;
+ event = yield undefined;
+ db = event.target.result;
+ trans = event.target.transaction;
+
+ trans.objectStore("store1").add({ reopen: 1 }).onsuccess = genCheck(
+ c1++,
+ { reopen: 1 },
+ "first" + test
+ );
+ trans.objectStore("store2").put({ reopen: 2 }).onsuccess = genCheck(
+ c2,
+ { reopen: 2, id: c2 },
+ "second" + test
+ );
+ c2++;
+ yield undefined;
+ yield undefined;
+
+ openRequest.onsuccess = grabEventAndContinueHandler;
+ yield undefined;
+
+ finishTest();
+}