2011-12-16 16:40:47 -08:00
|
|
|
<!--
|
|
|
|
Any copyright is dedicated to the Public Domain.
|
|
|
|
http://creativecommons.org/publicdomain/zero/1.0/
|
|
|
|
-->
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<title>Indexed Database Property Test</title>
|
|
|
|
|
|
|
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
|
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
|
|
|
|
2012-01-03 08:44:34 -08:00
|
|
|
<script type="text/javascript;version=1.7">
|
|
|
|
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 = window.location.pathname;
|
|
|
|
const RW = IDBTransaction.READ_WRITE
|
|
|
|
let c1 = 1;
|
|
|
|
let c2 = 1;
|
|
|
|
|
2012-06-29 09:48:35 -07:00
|
|
|
let openRequest = indexedDB.open(dbname, 1);
|
2012-01-03 08:44:34 -08:00
|
|
|
openRequest.onerror = errorHandler;
|
|
|
|
openRequest.onupgradeneeded = grabEventAndContinueHandler;
|
|
|
|
openRequest.onsuccess = unexpectedSuccessHandler;
|
|
|
|
let event = yield;
|
|
|
|
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;
|
|
|
|
yield;
|
|
|
|
|
|
|
|
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;
|
|
|
|
yield;
|
|
|
|
|
|
|
|
store2.get(IDBKeyRange.lowerBound(c2)).onsuccess = grabEventAndContinueHandler;
|
|
|
|
event = yield;
|
|
|
|
is(event.target.result, undefined, "no such value" + test);
|
|
|
|
|
|
|
|
// Close version_change transaction
|
|
|
|
openRequest.onsuccess = grabEventAndContinueHandler;
|
|
|
|
event = yield;
|
|
|
|
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; yield;
|
|
|
|
|
|
|
|
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; yield;
|
|
|
|
|
|
|
|
trans = db.transaction("store1", RW);
|
|
|
|
trans.objectStore("store1").add({ explicit: 5 }, 150).onsuccess =
|
|
|
|
genCheck(150, { explicit: 5 }, "fifth" + test);
|
|
|
|
yield;
|
|
|
|
trans.objectStore("store1").add({ explicit: 6 }).onsuccess =
|
|
|
|
genCheck(c1++, { explicit: 6 }, "sixth" + test);
|
|
|
|
yield;
|
|
|
|
|
|
|
|
trans = db.transaction("store1", RW);
|
|
|
|
trans.objectStore("store1").add({ explicit: 7 }, "key").onsuccess =
|
|
|
|
genCheck("key", { explicit: 7 }, "seventh" + test);
|
|
|
|
yield;
|
|
|
|
trans.objectStore("store1").add({ explicit: 8 }).onsuccess =
|
|
|
|
genCheck(c1++, { explicit: 8 }, "eighth" + test);
|
|
|
|
yield;
|
|
|
|
|
|
|
|
trans = db.transaction("store1", RW);
|
|
|
|
trans.objectStore("store1").add({ explicit: 7 }, [100000]).onsuccess =
|
|
|
|
genCheck([100000], { explicit: 7 }, "seventh" + test);
|
|
|
|
yield;
|
|
|
|
trans.objectStore("store1").add({ explicit: 8 }).onsuccess =
|
|
|
|
genCheck(c1++, { explicit: 8 }, "eighth" + test);
|
|
|
|
yield;
|
|
|
|
|
|
|
|
trans = db.transaction("store1", RW);
|
|
|
|
trans.objectStore("store1").add({ explicit: 9 }, -100000).onsuccess =
|
|
|
|
genCheck(-100000, { explicit: 9 }, "ninth" + test);
|
|
|
|
yield;
|
|
|
|
trans.objectStore("store1").add({ explicit: 10 }).onsuccess =
|
|
|
|
genCheck(c1++, { explicit: 10 }, "tenth" + test);
|
|
|
|
yield;
|
|
|
|
|
|
|
|
|
|
|
|
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; yield;
|
|
|
|
|
|
|
|
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; yield;
|
|
|
|
|
|
|
|
trans = db.transaction("store2", RW);
|
|
|
|
trans.objectStore("store2").add({ explicit: 5, id: 150 }).onsuccess =
|
|
|
|
genCheck(150, { explicit: 5, id: 150 }, "fifth store2" + test);
|
|
|
|
yield;
|
|
|
|
trans.objectStore("store2").add({ explicit: 6 }).onsuccess =
|
|
|
|
genCheck(c2, { explicit: 6, id: c2 }, "sixth store2" + test);
|
|
|
|
c2++;
|
|
|
|
yield;
|
|
|
|
|
|
|
|
trans = db.transaction("store2", RW);
|
|
|
|
trans.objectStore("store2").add({ explicit: 7, id: "key" }).onsuccess =
|
|
|
|
genCheck("key", { explicit: 7, id: "key" }, "seventh store2" + test);
|
|
|
|
yield;
|
|
|
|
trans.objectStore("store2").add({ explicit: 8 }).onsuccess =
|
|
|
|
genCheck(c2, { explicit: 8, id: c2 }, "eighth store2" + test);
|
|
|
|
c2++;
|
|
|
|
yield;
|
|
|
|
|
|
|
|
trans = db.transaction("store2", RW);
|
|
|
|
trans.objectStore("store2").add({ explicit: 7, id: [100000] }).onsuccess =
|
|
|
|
genCheck([100000], { explicit: 7, id: [100000] }, "seventh store2" + test);
|
|
|
|
yield;
|
|
|
|
trans.objectStore("store2").add({ explicit: 8 }).onsuccess =
|
|
|
|
genCheck(c2, { explicit: 8, id: c2 }, "eighth store2" + test);
|
|
|
|
c2++;
|
|
|
|
yield;
|
|
|
|
|
|
|
|
trans = db.transaction("store2", RW);
|
|
|
|
trans.objectStore("store2").add({ explicit: 9, id: -100000 }).onsuccess =
|
|
|
|
genCheck(-100000, { explicit: 9, id: -100000 }, "ninth store2" + test);
|
|
|
|
yield;
|
|
|
|
trans.objectStore("store2").add({ explicit: 10 }).onsuccess =
|
|
|
|
genCheck(c2, { explicit: 10, id: c2 }, "tenth store2" + test);
|
|
|
|
c2++;
|
|
|
|
yield;
|
|
|
|
|
|
|
|
|
|
|
|
// Test separate transactions doesn't generate overlapping numbers
|
|
|
|
test = " for test non-overlapping counts";
|
|
|
|
trans = db.transaction("store1", RW);
|
|
|
|
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: trans });
|
|
|
|
c1 += 2;
|
|
|
|
yield; yield;
|
|
|
|
|
|
|
|
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: trans });
|
|
|
|
c2 += 2;
|
|
|
|
yield; yield;
|
|
|
|
|
|
|
|
// 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 }).onerror =
|
2012-06-25 12:15:17 -07:00
|
|
|
new ExpectError("ConstraintError", true);
|
2012-01-03 08:44:34 -08:00
|
|
|
trans.objectStore("store1").add({ error: 2 }).onsuccess =
|
|
|
|
genCheck(c1++, { error: 2 }, "first" + test);
|
|
|
|
yield; yield;
|
|
|
|
|
|
|
|
trans.objectStore("store2").add({ error: 3, unique: 1 }).onerror =
|
2012-06-25 12:15:17 -07:00
|
|
|
new ExpectError("ConstraintError", true);
|
2012-01-03 08:44:34 -08:00
|
|
|
trans.objectStore("store2").add({ error: 4 }).onsuccess =
|
|
|
|
genCheck(c2, { error: 4, id: c2 }, "second" + test);
|
|
|
|
c2++;
|
|
|
|
yield; yield;
|
|
|
|
|
|
|
|
trans.objectStore("store1").add({ error: 5, unique: 1 }, 100000).onerror =
|
2012-06-25 12:15:17 -07:00
|
|
|
new ExpectError("ConstraintError", true);
|
2012-01-03 08:44:34 -08:00
|
|
|
trans.objectStore("store1").add({ error: 6 }).onsuccess =
|
|
|
|
genCheck(c1++, { error: 6 }, "third" + test);
|
|
|
|
yield; yield;
|
|
|
|
|
|
|
|
trans.objectStore("store2").add({ error: 7, unique: 1, id: 100000 }).onerror =
|
2012-06-25 12:15:17 -07:00
|
|
|
new ExpectError("ConstraintError", true);
|
2012-01-03 08:44:34 -08:00
|
|
|
trans.objectStore("store2").add({ error: 8 }).onsuccess =
|
|
|
|
genCheck(c2, { error: 8, id: c2 }, "fourth" + test);
|
|
|
|
c2++;
|
|
|
|
yield; yield;
|
|
|
|
|
|
|
|
// 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; yield;
|
|
|
|
|
|
|
|
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; yield;
|
|
|
|
|
|
|
|
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; yield;
|
|
|
|
|
|
|
|
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; yield;
|
|
|
|
|
|
|
|
// 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; yield;
|
|
|
|
|
|
|
|
trans.objectStore("store1").delete(c1 - 1).onsuccess =
|
|
|
|
grabEventAndContinueHandler;
|
|
|
|
trans.objectStore("store2").delete(c2 - 1).onsuccess =
|
|
|
|
grabEventAndContinueHandler;
|
|
|
|
yield; yield;
|
|
|
|
|
|
|
|
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; yield;
|
|
|
|
|
|
|
|
trans.objectStore("store1").delete(c1 - 1).onsuccess =
|
|
|
|
grabEventAndContinueHandler;
|
|
|
|
trans.objectStore("store2").delete(c2 - 1).onsuccess =
|
|
|
|
grabEventAndContinueHandler;
|
|
|
|
yield; yield;
|
|
|
|
|
|
|
|
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; yield;
|
|
|
|
|
|
|
|
// 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; yield;
|
|
|
|
|
|
|
|
trans.objectStore("store1").clear().onsuccess =
|
|
|
|
grabEventAndContinueHandler;
|
|
|
|
trans.objectStore("store2").clear().onsuccess =
|
|
|
|
grabEventAndContinueHandler;
|
|
|
|
yield; yield;
|
|
|
|
|
|
|
|
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; yield;
|
|
|
|
|
|
|
|
trans.objectStore("store1").clear().onsuccess =
|
|
|
|
grabEventAndContinueHandler;
|
|
|
|
trans.objectStore("store2").clear().onsuccess =
|
|
|
|
grabEventAndContinueHandler;
|
|
|
|
yield; yield;
|
|
|
|
|
|
|
|
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; yield;
|
|
|
|
|
|
|
|
|
|
|
|
// 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; yield;
|
|
|
|
db.close();
|
|
|
|
|
|
|
|
SpecialPowers.gc();
|
|
|
|
|
2012-06-29 09:48:35 -07:00
|
|
|
openRequest = indexedDB.open(dbname, 2);
|
2012-01-03 08:44:34 -08:00
|
|
|
openRequest.onerror = errorHandler;
|
|
|
|
openRequest.onupgradeneeded = grabEventAndContinueHandler;
|
|
|
|
openRequest.onsuccess = unexpectedSuccessHandler;
|
|
|
|
event = yield;
|
|
|
|
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; yield;
|
|
|
|
|
|
|
|
openRequest.onsuccess = grabEventAndContinueHandler;
|
|
|
|
yield;
|
|
|
|
|
|
|
|
finishTest();
|
|
|
|
yield;
|
|
|
|
}
|
|
|
|
</script>
|
2011-12-16 16:40:47 -08:00
|
|
|
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
|
|
|
</head>
|
|
|
|
|
|
|
|
<body onload="runTest();"></body>
|
|
|
|
|
|
|
|
</html>
|