mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-26 10:27:32 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
38
dom/indexedDB/test/unit/GlobalObjectsChild.js
Normal file
38
dom/indexedDB/test/unit/GlobalObjectsChild.js
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
function ok(cond, msg) {
|
||||
dump("ok(" + cond + ", \"" + msg + "\")");
|
||||
do_check_true(!!cond, Components.stack.caller);
|
||||
}
|
||||
|
||||
function finishTest()
|
||||
{
|
||||
do_execute_soon(function() {
|
||||
do_test_finished();
|
||||
});
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
const name = "Splendid Test";
|
||||
|
||||
Cu.importGlobalProperties(["indexedDB"]);
|
||||
|
||||
do_test_pending();
|
||||
|
||||
let keyRange = IDBKeyRange.only(42);
|
||||
ok(keyRange, "Got keyRange");
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = function(event) {
|
||||
ok(false, "indexedDB error, '" + event.target.error.name + "'");
|
||||
finishTest();
|
||||
}
|
||||
request.onsuccess = function(event) {
|
||||
let db = event.target.result;
|
||||
ok(db, "Got database");
|
||||
finishTest();
|
||||
}
|
||||
}
|
||||
43
dom/indexedDB/test/unit/GlobalObjectsComponent.js
Normal file
43
dom/indexedDB/test/unit/GlobalObjectsComponent.js
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.importGlobalProperties(["indexedDB"]);
|
||||
|
||||
function GlobalObjectsComponent() {
|
||||
this.wrappedJSObject = this;
|
||||
}
|
||||
|
||||
GlobalObjectsComponent.prototype =
|
||||
{
|
||||
classID: Components.ID("{949ebf50-e0da-44b9-8335-cbfd4febfdcc}"),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupports]),
|
||||
|
||||
runTest: function() {
|
||||
const name = "Splendid Test";
|
||||
|
||||
let ok = this.ok;
|
||||
let finishTest = this.finishTest;
|
||||
|
||||
let keyRange = IDBKeyRange.only(42);
|
||||
ok(keyRange, "Got keyRange");
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = function(event) {
|
||||
ok(false, "indexedDB error, '" + event.target.error.name + "'");
|
||||
finishTest();
|
||||
}
|
||||
request.onsuccess = function(event) {
|
||||
let db = event.target.result;
|
||||
ok(db, "Got database");
|
||||
finishTest();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([GlobalObjectsComponent]);
|
||||
2
dom/indexedDB/test/unit/GlobalObjectsComponent.manifest
Normal file
2
dom/indexedDB/test/unit/GlobalObjectsComponent.manifest
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
component {949ebf50-e0da-44b9-8335-cbfd4febfdcc} GlobalObjectsComponent.js
|
||||
contract @mozilla.org/dom/indexeddb/GlobalObjectsComponent;1 {949ebf50-e0da-44b9-8335-cbfd4febfdcc}
|
||||
36
dom/indexedDB/test/unit/GlobalObjectsModule.jsm
Normal file
36
dom/indexedDB/test/unit/GlobalObjectsModule.jsm
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
Components.utils.importGlobalProperties(["indexedDB"]);
|
||||
|
||||
this.EXPORTED_SYMBOLS = [
|
||||
"GlobalObjectsModule"
|
||||
];
|
||||
|
||||
this.GlobalObjectsModule = function GlobalObjectsModule() {
|
||||
}
|
||||
|
||||
GlobalObjectsModule.prototype = {
|
||||
runTest: function() {
|
||||
const name = "Splendid Test";
|
||||
|
||||
let ok = this.ok;
|
||||
let finishTest = this.finishTest;
|
||||
|
||||
let keyRange = IDBKeyRange.only(42);
|
||||
ok(keyRange, "Got keyRange");
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = function(event) {
|
||||
ok(false, "indexedDB error, '" + event.target.error.name + "'");
|
||||
finishTest();
|
||||
}
|
||||
request.onsuccess = function(event) {
|
||||
let db = event.target.result;
|
||||
ok(db, "Got database");
|
||||
finishTest();
|
||||
}
|
||||
}
|
||||
}
|
||||
22
dom/indexedDB/test/unit/GlobalObjectsSandbox.js
Normal file
22
dom/indexedDB/test/unit/GlobalObjectsSandbox.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
function runTest() {
|
||||
const name = "Splendid Test";
|
||||
|
||||
let keyRange = IDBKeyRange.only(42);
|
||||
ok(keyRange, "Got keyRange");
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = function(event) {
|
||||
ok(false, "indexedDB error, '" + event.target.error.name + "'");
|
||||
finishTest();
|
||||
}
|
||||
request.onsuccess = function(event) {
|
||||
let db = event.target.result;
|
||||
ok(db, "Got database");
|
||||
finishTest();
|
||||
}
|
||||
}
|
||||
BIN
dom/indexedDB/test/unit/bug1056939_profile.zip
Normal file
BIN
dom/indexedDB/test/unit/bug1056939_profile.zip
Normal file
Binary file not shown.
BIN
dom/indexedDB/test/unit/defaultStorageUpgrade_profile.zip
Normal file
BIN
dom/indexedDB/test/unit/defaultStorageUpgrade_profile.zip
Normal file
Binary file not shown.
BIN
dom/indexedDB/test/unit/getUsage_profile.zip
Normal file
BIN
dom/indexedDB/test/unit/getUsage_profile.zip
Normal file
Binary file not shown.
BIN
dom/indexedDB/test/unit/idbSubdirUpgrade1_profile.zip
Normal file
BIN
dom/indexedDB/test/unit/idbSubdirUpgrade1_profile.zip
Normal file
Binary file not shown.
BIN
dom/indexedDB/test/unit/idbSubdirUpgrade2_profile.zip
Normal file
BIN
dom/indexedDB/test/unit/idbSubdirUpgrade2_profile.zip
Normal file
Binary file not shown.
BIN
dom/indexedDB/test/unit/metadata2Restore_profile.zip
Normal file
BIN
dom/indexedDB/test/unit/metadata2Restore_profile.zip
Normal file
Binary file not shown.
BIN
dom/indexedDB/test/unit/metadataRestore_profile.zip
Normal file
BIN
dom/indexedDB/test/unit/metadataRestore_profile.zip
Normal file
Binary file not shown.
BIN
dom/indexedDB/test/unit/mutableFileUpgrade_profile.zip
Normal file
BIN
dom/indexedDB/test/unit/mutableFileUpgrade_profile.zip
Normal file
Binary file not shown.
BIN
dom/indexedDB/test/unit/oldDirectories_profile.zip
Normal file
BIN
dom/indexedDB/test/unit/oldDirectories_profile.zip
Normal file
Binary file not shown.
BIN
dom/indexedDB/test/unit/schema18upgrade_profile.zip
Normal file
BIN
dom/indexedDB/test/unit/schema18upgrade_profile.zip
Normal file
Binary file not shown.
BIN
dom/indexedDB/test/unit/schema21upgrade_profile.zip
Normal file
BIN
dom/indexedDB/test/unit/schema21upgrade_profile.zip
Normal file
Binary file not shown.
BIN
dom/indexedDB/test/unit/schema23upgrade_profile.zip
Normal file
BIN
dom/indexedDB/test/unit/schema23upgrade_profile.zip
Normal file
Binary file not shown.
BIN
dom/indexedDB/test/unit/snappyUpgrade_profile.zip
Normal file
BIN
dom/indexedDB/test/unit/snappyUpgrade_profile.zip
Normal file
Binary file not shown.
BIN
dom/indexedDB/test/unit/storagePersistentUpgrade_profile.zip
Normal file
BIN
dom/indexedDB/test/unit/storagePersistentUpgrade_profile.zip
Normal file
Binary file not shown.
78
dom/indexedDB/test/unit/test_abort_deleted_index.js
Normal file
78
dom/indexedDB/test/unit/test_abort_deleted_index.js
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const storeName = "test store";
|
||||
const indexName_ToBeDeleted = "test index to be deleted";
|
||||
|
||||
info("Create index in v1.");
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
let txn = event.target.transaction;
|
||||
|
||||
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
|
||||
|
||||
let objectStore = db.createObjectStore(storeName, { keyPath: "foo" });
|
||||
is(db.objectStoreNames.length, 1, "Correct objectStoreNames list");
|
||||
is(db.objectStoreNames.item(0), objectStore.name, "Correct object store name");
|
||||
|
||||
// create index to be deleted later in v2.
|
||||
objectStore.createIndex(indexName_ToBeDeleted, "foo");
|
||||
ok(objectStore.index(indexName_ToBeDeleted), "Index created.");
|
||||
|
||||
txn.oncomplete = continueToNextStepSync;
|
||||
yield undefined;
|
||||
request.onsuccess = continueToNextStep;
|
||||
yield undefined;
|
||||
db.close();
|
||||
|
||||
info("Delete index in v2.");
|
||||
request = indexedDB.open(name, 2);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
event = yield undefined;
|
||||
|
||||
db = event.target.result;
|
||||
txn = event.target.transaction;
|
||||
|
||||
objectStore = txn.objectStore(storeName);
|
||||
let index = objectStore.index(indexName_ToBeDeleted);
|
||||
ok(index, "index is valid.");
|
||||
objectStore.deleteIndex(indexName_ToBeDeleted);
|
||||
|
||||
// Aborting the transaction.
|
||||
request.onerror = expectedErrorHandler("AbortError");
|
||||
txn.abort();
|
||||
try {
|
||||
index.get('foo');
|
||||
ok(false, "TransactionInactiveError shall be thrown right after a deletion of an index is aborted.");
|
||||
} catch (e) {
|
||||
ok(e instanceof DOMException, "got a database exception");
|
||||
is(e.name, "TransactionInactiveError", "TransactionInactiveError shall be thrown right after a deletion of an index is aborted.");
|
||||
}
|
||||
|
||||
yield undefined;
|
||||
|
||||
try {
|
||||
index.get('foo');
|
||||
ok(false, "TransactionInactiveError shall be thrown after the transaction is inactive.");
|
||||
} catch (e) {
|
||||
ok(e instanceof DOMException, "got a database exception");
|
||||
is(e.name, "TransactionInactiveError", "TransactionInactiveError shall be thrown after the transaction is inactive.");
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
74
dom/indexedDB/test/unit/test_abort_deleted_objectStore.js
Normal file
74
dom/indexedDB/test/unit/test_abort_deleted_objectStore.js
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const storeName_ToBeDeleted = "test store to be deleted";
|
||||
|
||||
info("Create objectStore in v1.");
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
let txn = event.target.transaction;
|
||||
|
||||
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
|
||||
|
||||
// create objectstore to be deleted later in v2.
|
||||
db.createObjectStore(storeName_ToBeDeleted, { keyPath: "foo" });
|
||||
is(db.objectStoreNames.length, 1, "Correct objectStoreNames list");
|
||||
ok(db.objectStoreNames.contains(storeName_ToBeDeleted), "Correct name");
|
||||
|
||||
txn.oncomplete = continueToNextStepSync;
|
||||
yield undefined;
|
||||
request.onsuccess = continueToNextStep;
|
||||
yield undefined;
|
||||
db.close();
|
||||
|
||||
info("Delete objectStore in v2.");
|
||||
request = indexedDB.open(name, 2);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
event = yield undefined;
|
||||
|
||||
db = event.target.result;
|
||||
txn = event.target.transaction;
|
||||
|
||||
let objectStore = txn.objectStore(storeName_ToBeDeleted);
|
||||
ok(objectStore, "objectStore is available");
|
||||
|
||||
db.deleteObjectStore(storeName_ToBeDeleted);
|
||||
|
||||
// Aborting the transaction.
|
||||
request.onerror = expectedErrorHandler("AbortError");
|
||||
txn.abort();
|
||||
try {
|
||||
objectStore.get('foo');
|
||||
ok(false, "TransactionInactiveError shall be thrown if the transaction is inactive.");
|
||||
} catch (e) {
|
||||
ok(e instanceof DOMException, "got a database exception");
|
||||
is(e.name, "TransactionInactiveError", "correct error");
|
||||
}
|
||||
|
||||
yield undefined;
|
||||
|
||||
try {
|
||||
objectStore.get('foo');
|
||||
ok(false, "TransactionInactiveError shall be thrown if the transaction is inactive.");
|
||||
} catch (e) {
|
||||
ok(e instanceof DOMException, "got a database exception");
|
||||
is(e.name, "TransactionInactiveError", "correct error");
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
165
dom/indexedDB/test/unit/test_add_put.js
Normal file
165
dom/indexedDB/test/unit/test_add_put.js
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
let openRequest = indexedDB.open(name, 1);
|
||||
openRequest.onerror = errorHandler;
|
||||
openRequest.onupgradeneeded = grabEventAndContinueHandler;
|
||||
openRequest.onsuccess = unexpectedSuccessHandler;
|
||||
let event = yield undefined;
|
||||
let db = event.target.result;
|
||||
let trans = event.target.transaction;
|
||||
|
||||
for (let autoincrement of [true, false]) {
|
||||
for (let keypath of [false, true, "missing", "invalid"]) {
|
||||
for (let method of ["put", "add"]) {
|
||||
for (let explicit of [true, false, undefined, "invalid"]) {
|
||||
for (let existing of [true, false]) {
|
||||
let speccedNoKey = (keypath == false || keypath == "missing") &&
|
||||
!explicit;
|
||||
|
||||
// We can't do 'existing' checks if we use autogenerated key
|
||||
if (speccedNoKey && autoincrement && existing) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create store
|
||||
if (db.objectStoreNames.contains("mystore"))
|
||||
db.deleteObjectStore("mystore");
|
||||
let store = db.createObjectStore("mystore",
|
||||
{ autoIncrement: autoincrement,
|
||||
keyPath: (keypath ? "id" : null) });
|
||||
|
||||
test = " for test " + JSON.stringify({ autoincrement: autoincrement,
|
||||
keypath: keypath,
|
||||
method: method,
|
||||
explicit: explicit === undefined ? "undefined" : explicit,
|
||||
existing: existing });
|
||||
|
||||
// Insert "existing" data if needed
|
||||
if (existing) {
|
||||
if (keypath)
|
||||
store.add({ existing: "data", id: 5 }).onsuccess = grabEventAndContinueHandler;
|
||||
else
|
||||
store.add({ existing: "data" }, 5).onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
let e = yield undefined;
|
||||
is(e.type, "success", "success inserting existing" + test);
|
||||
is(e.target.result, 5, "inserted correct key" + test);
|
||||
}
|
||||
|
||||
// Set up value to be inserted
|
||||
let value = { theObj: true };
|
||||
if (keypath === true) {
|
||||
value.id = 5;
|
||||
}
|
||||
else if (keypath === "invalid") {
|
||||
value.id = /x/;
|
||||
}
|
||||
|
||||
// Which arguments are passed to function
|
||||
args = [value];
|
||||
if (explicit === true) {
|
||||
args.push(5);
|
||||
}
|
||||
else if (explicit === undefined) {
|
||||
args.push(undefined);
|
||||
}
|
||||
else if (explicit === "invalid") {
|
||||
args.push(/x/);
|
||||
}
|
||||
|
||||
let expected = expectedResult(method, keypath, explicit, autoincrement, existing);
|
||||
|
||||
let valueJSON = JSON.stringify(value);
|
||||
|
||||
ok(true, "making call" + test);
|
||||
|
||||
// Make function call for throwing functions
|
||||
if (expected === "throw") {
|
||||
try {
|
||||
store[method].apply(store, args);
|
||||
ok(false, "should have thrown" + test);
|
||||
}
|
||||
catch (ex) {
|
||||
ok(true, "did throw" + test);
|
||||
ok(ex instanceof DOMException, "Got a DOMException" + test);
|
||||
is(ex.name, "DataError", "expect a DataError" + test);
|
||||
is(ex.code, 0, "expect zero" + test);
|
||||
is(JSON.stringify(value), valueJSON, "call didn't modify value" + test);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Make non-throwing function call
|
||||
let req = store[method].apply(store, args);
|
||||
is(JSON.stringify(value), valueJSON, "call didn't modify value" + test);
|
||||
|
||||
req.onsuccess = req.onerror = grabEventAndContinueHandler;
|
||||
let e = yield undefined;
|
||||
|
||||
// Figure out what key we used
|
||||
let key = 5;
|
||||
if (autoincrement && speccedNoKey) {
|
||||
key = 1;
|
||||
}
|
||||
|
||||
// Adjust value if expected
|
||||
if (autoincrement && keypath && speccedNoKey) {
|
||||
value.id = key;
|
||||
}
|
||||
|
||||
// Check result
|
||||
if (expected === "error") {
|
||||
is(e.type, "error", "write should fail" + test);
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
continue;
|
||||
}
|
||||
|
||||
is(e.type, "success", "write should succeed" + test);
|
||||
is(e.target.result, key, "write should return correct key" + test);
|
||||
|
||||
store.get(key).onsuccess = grabEventAndContinueHandler;
|
||||
e = yield undefined;
|
||||
is(e.type, "success", "read back should succeed" + test);
|
||||
is(JSON.stringify(e.target.result),
|
||||
JSON.stringify(value),
|
||||
"read back should return correct value" + test);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function expectedResult(method, keypath, explicit, autoincrement, existing) {
|
||||
if (keypath && explicit)
|
||||
return "throw";
|
||||
if (!keypath && !explicit && !autoincrement)
|
||||
return "throw";
|
||||
if (keypath == "invalid")
|
||||
return "throw";
|
||||
if (keypath == "missing" && !autoincrement)
|
||||
return "throw";
|
||||
if (explicit == "invalid")
|
||||
return "throw";
|
||||
|
||||
if (method == "add" && existing)
|
||||
return "error";
|
||||
|
||||
return "success";
|
||||
}
|
||||
|
||||
openRequest.onsuccess = grabEventAndContinueHandler;
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
43
dom/indexedDB/test/unit/test_add_twice_failure.js
Normal file
43
dom/indexedDB/test/unit/test_add_twice_failure.js
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = request.result;
|
||||
|
||||
ok(event.target === request, "Good event target");
|
||||
|
||||
let objectStore = db.createObjectStore("foo", { keyPath: null });
|
||||
let key = 10;
|
||||
|
||||
request = objectStore.add({}, key);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(request.result, key, "Correct key");
|
||||
|
||||
request = objectStore.add({}, key);
|
||||
request.addEventListener("error", new ExpectError("ConstraintError", true));
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
yield undefined;
|
||||
|
||||
// Wait for success.
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
192
dom/indexedDB/test/unit/test_advance.js
Normal file
192
dom/indexedDB/test/unit/test_advance.js
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const dataCount = 30;
|
||||
|
||||
let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
event.target.onsuccess = continueToNextStep;
|
||||
|
||||
let objectStore = db.createObjectStore("", { keyPath: "key" });
|
||||
objectStore.createIndex("", "index");
|
||||
|
||||
for (let i = 0; i < dataCount; i++) {
|
||||
objectStore.add({ key: i, index: i });
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
function getObjectStore() {
|
||||
return db.transaction("").objectStore("");
|
||||
}
|
||||
|
||||
function getIndex() {
|
||||
return db.transaction("").objectStore("").index("");
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
|
||||
getObjectStore().openCursor().onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
count++;
|
||||
cursor.continue();
|
||||
}
|
||||
else {
|
||||
continueToNextStep();
|
||||
}
|
||||
};
|
||||
yield undefined;
|
||||
|
||||
is(count, dataCount, "Saw all data");
|
||||
|
||||
count = 0;
|
||||
|
||||
getObjectStore().openCursor().onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
is(cursor.primaryKey, count, "Got correct object");
|
||||
if (count) {
|
||||
count++;
|
||||
cursor.continue();
|
||||
}
|
||||
else {
|
||||
count = 10;
|
||||
cursor.advance(10);
|
||||
}
|
||||
}
|
||||
else {
|
||||
continueToNextStep();
|
||||
}
|
||||
};
|
||||
yield undefined;
|
||||
|
||||
is(count, dataCount, "Saw all data");
|
||||
|
||||
count = 0;
|
||||
|
||||
getIndex().openCursor().onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
is(cursor.primaryKey, count, "Got correct object");
|
||||
if (count) {
|
||||
count++;
|
||||
cursor.continue();
|
||||
}
|
||||
else {
|
||||
count = 10;
|
||||
cursor.advance(10);
|
||||
}
|
||||
}
|
||||
else {
|
||||
continueToNextStep();
|
||||
}
|
||||
};
|
||||
yield undefined;
|
||||
|
||||
is(count, dataCount, "Saw all data");
|
||||
|
||||
count = 0;
|
||||
|
||||
getIndex().openKeyCursor().onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
is(cursor.primaryKey, count, "Got correct object");
|
||||
if (count) {
|
||||
count++;
|
||||
cursor.continue();
|
||||
}
|
||||
else {
|
||||
count = 10;
|
||||
cursor.advance(10);
|
||||
}
|
||||
}
|
||||
else {
|
||||
continueToNextStep();
|
||||
}
|
||||
};
|
||||
yield undefined;
|
||||
|
||||
is(count, dataCount, "Saw all data");
|
||||
|
||||
count = 0;
|
||||
|
||||
getObjectStore().openCursor().onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
is(cursor.primaryKey, count, "Got correct object");
|
||||
if (count == 0) {
|
||||
cursor.advance(dataCount + 1);
|
||||
}
|
||||
else {
|
||||
ok(false, "Should never get here!");
|
||||
cursor.continue();
|
||||
}
|
||||
}
|
||||
else {
|
||||
continueToNextStep();
|
||||
}
|
||||
};
|
||||
yield undefined;
|
||||
|
||||
is(count, 0, "Saw all data");
|
||||
|
||||
count = dataCount - 1;
|
||||
|
||||
getObjectStore().openCursor(null, "prev").onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
is(cursor.primaryKey, count, "Got correct object");
|
||||
count--;
|
||||
if (count == dataCount - 2) {
|
||||
cursor.advance(10);
|
||||
count -= 9;
|
||||
}
|
||||
else {
|
||||
cursor.continue();
|
||||
}
|
||||
}
|
||||
else {
|
||||
continueToNextStep();
|
||||
}
|
||||
};
|
||||
yield undefined;
|
||||
|
||||
is(count, -1, "Saw all data");
|
||||
|
||||
count = dataCount - 1;
|
||||
|
||||
getObjectStore().openCursor(null, "prev").onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
is(cursor.primaryKey, count, "Got correct object");
|
||||
if (count == dataCount - 1) {
|
||||
cursor.advance(dataCount + 1);
|
||||
}
|
||||
else {
|
||||
ok(false, "Should never get here!");
|
||||
cursor.continue();
|
||||
}
|
||||
}
|
||||
else {
|
||||
continueToNextStep();
|
||||
}
|
||||
};
|
||||
yield undefined;
|
||||
|
||||
is(count, dataCount - 1, "Saw all data");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
400
dom/indexedDB/test/unit/test_autoIncrement.js
Normal file
400
dom/indexedDB/test/unit/test_autoIncrement.js
Normal file
|
|
@ -0,0 +1,400 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
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);
|
||||
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 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: 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();
|
||||
yield undefined;
|
||||
}
|
||||
56
dom/indexedDB/test/unit/test_autoIncrement_indexes.js
Normal file
56
dom/indexedDB/test/unit/test_autoIncrement_indexes.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = request.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
let objectStore = db.createObjectStore("foo", { keyPath: "id",
|
||||
autoIncrement: true });
|
||||
objectStore.createIndex("first","first");
|
||||
objectStore.createIndex("second","second");
|
||||
objectStore.createIndex("third","third");
|
||||
|
||||
let data = { first: "foo", second: "foo", third: "foo" };
|
||||
|
||||
objectStore.add(data).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 1, "Added entry");
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
objectStore = db.transaction("foo").objectStore("foo");
|
||||
let first = objectStore.index("first");
|
||||
let second = objectStore.index("second");
|
||||
let third = objectStore.index("third");
|
||||
|
||||
first.get("foo").onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is (event.target.result.id, 1, "Entry in first");
|
||||
|
||||
second.get("foo").onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is (event.target.result.id, 1, "Entry in second");
|
||||
|
||||
third.get("foo").onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is (event.target.result.id, 1, "Entry in third");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
78
dom/indexedDB/test/unit/test_blob_file_backed.js
Normal file
78
dom/indexedDB/test/unit/test_blob_file_backed.js
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var disableWorkerTest = "This test uses SpecialPowers";
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const fileData = "abcdefghijklmnopqrstuvwxyz";
|
||||
const fileType = "text/plain";
|
||||
|
||||
const databaseName =
|
||||
("window" in this) ? window.location.pathname : "Test";
|
||||
const objectStoreName = "foo";
|
||||
const objectStoreKey = "10";
|
||||
|
||||
info("Creating temp file");
|
||||
|
||||
SpecialPowers.createFiles([{data:fileData, options:{type:fileType}}], function (files) {
|
||||
testGenerator.next(files[0]);
|
||||
});
|
||||
|
||||
let file = yield undefined;
|
||||
|
||||
ok(file instanceof File, "Got a File object");
|
||||
is(file.size, fileData.length, "Correct size");
|
||||
is(file.type, fileType, "Correct type");
|
||||
|
||||
let fileReader = new FileReader();
|
||||
fileReader.onload = grabEventAndContinueHandler;
|
||||
fileReader.readAsText(file);
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(fileReader.result, fileData, "Correct data");
|
||||
|
||||
let request = indexedDB.open(databaseName, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
let objectStore = db.createObjectStore(objectStoreName);
|
||||
objectStore.put(file, objectStoreKey);
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
db = event.target.result;
|
||||
|
||||
file = null;
|
||||
|
||||
objectStore = db.transaction(objectStoreName).objectStore(objectStoreName);
|
||||
objectStore.get(objectStoreKey).onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
file = event.target.result;
|
||||
|
||||
ok(file instanceof File, "Got a File object");
|
||||
is(file.size, fileData.length, "Correct size");
|
||||
is(file.type, fileType, "Correct type");
|
||||
|
||||
fileReader = new FileReader();
|
||||
fileReader.onload = grabEventAndContinueHandler;
|
||||
fileReader.readAsText(file);
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(fileReader.result, fileData, "Correct data");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
179
dom/indexedDB/test/unit/test_blocked_order.js
Normal file
179
dom/indexedDB/test/unit/test_blocked_order.js
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const databaseName =
|
||||
("window" in this) ? window.location.pathname : "Test";
|
||||
const databaseCount = 10;
|
||||
|
||||
// Test 1: Make sure basic versionchange events work and that they don't
|
||||
// trigger blocked events.
|
||||
info("Opening " + databaseCount + " databases with version 1");
|
||||
|
||||
let databases = [];
|
||||
|
||||
for (let i = 0; i < databaseCount; i++) {
|
||||
let thisIndex = i;
|
||||
|
||||
info("Opening database " + thisIndex);
|
||||
|
||||
let request = indexedDB.open(databaseName, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onblocked = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got success event");
|
||||
|
||||
let db = request.result;
|
||||
is(db.version, 1, "Got version 1");
|
||||
|
||||
db.onversionchange = function(event) {
|
||||
info("Closing database " + thisIndex);
|
||||
db.close();
|
||||
|
||||
databases.splice(databases.indexOf(db), 1);
|
||||
};
|
||||
|
||||
databases.push(db);
|
||||
}
|
||||
|
||||
is(databases.length, databaseCount, "Created all databases with version 1");
|
||||
|
||||
info("Opening database with version 2");
|
||||
|
||||
let request = indexedDB.open(databaseName, 2);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
request.onblocked = function(event) {
|
||||
ok(false, "Should not receive a blocked event");
|
||||
};
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got success event");
|
||||
is(databases.length, 0, "All databases with version 1 were closed");
|
||||
|
||||
let db = request.result;
|
||||
is(db.version, 2, "Got version 2");
|
||||
|
||||
info("Deleting database with version 2");
|
||||
db.close();
|
||||
|
||||
request = indexedDB.deleteDatabase(databaseName);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got success event");
|
||||
|
||||
// Test 2: Make sure blocked events aren't delivered until all versionchange
|
||||
// events have been delivered.
|
||||
info("Opening " + databaseCount + " databases with version 1");
|
||||
|
||||
for (let i = 0; i < databaseCount; i++) {
|
||||
let thisIndex = i;
|
||||
|
||||
info("Opening database " + thisIndex);
|
||||
|
||||
let request = indexedDB.open(databaseName, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onblocked = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got success event");
|
||||
|
||||
let db = request.result;
|
||||
is(db.version, 1, "Got version 1");
|
||||
|
||||
db.onversionchange = function(event) {
|
||||
if (thisIndex == (databaseCount - 1)) {
|
||||
info("Closing all databases with version 1");
|
||||
|
||||
for (let j = 0; j < databases.length; j++) {
|
||||
databases[j].close();
|
||||
}
|
||||
|
||||
databases = [];
|
||||
info("Done closing all databases with version 1");
|
||||
} else {
|
||||
info("Not closing database " + thisIndex);
|
||||
}
|
||||
};
|
||||
|
||||
databases.push(db);
|
||||
}
|
||||
|
||||
is(databases.length, databaseCount, "Created all databases with version 1");
|
||||
|
||||
info("Opening database with version 2");
|
||||
|
||||
request = indexedDB.open(databaseName, 2);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
request.onblocked = function(event) {
|
||||
ok(false, "Should not receive a blocked event");
|
||||
};
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got success event");
|
||||
is(databases.length, 0, "All databases with version 1 were closed");
|
||||
|
||||
db = request.result;
|
||||
is(db.version, 2, "Got version 2");
|
||||
|
||||
info("Deleting database with version 2");
|
||||
db.close();
|
||||
|
||||
request = indexedDB.deleteDatabase(databaseName);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got success event");
|
||||
|
||||
// Test 3: A blocked database left in that state should not hang shutdown.
|
||||
info("Opening 1 database with version 1");
|
||||
|
||||
request = indexedDB.open(databaseName, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onblocked = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got success event");
|
||||
|
||||
db = request.result;
|
||||
is(db.version, 1, "Got version 1");
|
||||
|
||||
info("Opening database with version 2");
|
||||
|
||||
request = indexedDB.open(databaseName, 2);
|
||||
request.onerror = function(e) {
|
||||
e.preventDefault();
|
||||
};
|
||||
request.onsuccess = errorHandler;
|
||||
|
||||
request.onblocked = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
ok(true, "Got blocked");
|
||||
// Just allow this to remain blocked ...
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
73
dom/indexedDB/test/unit/test_bug1056939.js
Normal file
73
dom/indexedDB/test/unit/test_bug1056939.js
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const dbName1 = "upgrade_test";
|
||||
const dbName2 = "testing.foobar";
|
||||
const dbName3 = "xxxxxxx.xxxxxx";
|
||||
|
||||
clearAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
installPackagedProfile("bug1056939_profile");
|
||||
|
||||
let request = indexedDB.open(dbName1, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Correct event type");
|
||||
|
||||
request = indexedDB.open(dbName2, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got correct event type");
|
||||
|
||||
request = indexedDB.open(dbName3, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got correct event type");
|
||||
|
||||
clearAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
request = indexedDB.open(dbName3, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Got correct event type");
|
||||
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got correct event type");
|
||||
|
||||
resetAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
request = indexedDB.open(dbName3, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got correct event type");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
155
dom/indexedDB/test/unit/test_cleanup_transaction.js
Normal file
155
dom/indexedDB/test/unit/test_cleanup_transaction.js
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var disableWorkerTest = "Need a way to set temporary prefs from a worker";
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const spec = "http://foo.com";
|
||||
const name =
|
||||
this.window ? window.location.pathname : "test_quotaExceeded_recovery";
|
||||
const objectStoreName = "foo";
|
||||
|
||||
// We want 32 MB database, but there's the group limit so we need to
|
||||
// multiply by 5.
|
||||
const tempStorageLimitKB = 32 * 1024 * 5;
|
||||
|
||||
// Store in 1 MB chunks.
|
||||
const dataSize = 1024 * 1024;
|
||||
|
||||
for (let blobs of [false, true]) {
|
||||
setTemporaryStorageLimit(tempStorageLimitKB);
|
||||
|
||||
clearAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
info("Opening database");
|
||||
|
||||
let request = indexedDB.openForPrincipal(getPrincipal(spec), name);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
|
||||
yield undefined;
|
||||
|
||||
// upgradeneeded
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
info("Creating objectStore");
|
||||
|
||||
request.result.createObjectStore(objectStoreName);
|
||||
|
||||
yield undefined;
|
||||
|
||||
// success
|
||||
let db = request.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
ok(true, "Adding data until quota is reached");
|
||||
|
||||
let obj = {
|
||||
name: "foo"
|
||||
}
|
||||
|
||||
if (!blobs) {
|
||||
obj.data = getRandomView(dataSize);
|
||||
}
|
||||
|
||||
let i = 1;
|
||||
let j = 1;
|
||||
while (true) {
|
||||
if (blobs) {
|
||||
obj.data = getBlob(getView(dataSize));
|
||||
}
|
||||
|
||||
let trans = db.transaction(objectStoreName, "readwrite");
|
||||
request = trans.objectStore(objectStoreName).add(obj, i);
|
||||
request.onerror = function(event)
|
||||
{
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
trans.oncomplete = function(event) {
|
||||
i++;
|
||||
j++;
|
||||
testGenerator.send(true);
|
||||
}
|
||||
trans.onabort = function(event) {
|
||||
is(trans.error.name, "QuotaExceededError", "Reached quota limit");
|
||||
testGenerator.send(false);
|
||||
}
|
||||
|
||||
let completeFired = yield undefined;
|
||||
if (completeFired) {
|
||||
ok(true, "Got complete event");
|
||||
} else {
|
||||
ok(true, "Got abort event");
|
||||
|
||||
if (j == 1) {
|
||||
// Plain cleanup transaction (just vacuuming and checkpointing)
|
||||
// couldn't shrink database any further.
|
||||
break;
|
||||
}
|
||||
|
||||
j = 1;
|
||||
|
||||
trans = db.transaction(objectStoreName, "cleanup");
|
||||
trans.onabort = unexpectedSuccessHandler;;
|
||||
trans.oncomplete = grabEventAndContinueHandler;
|
||||
|
||||
yield undefined;
|
||||
}
|
||||
}
|
||||
|
||||
info("Reopening database");
|
||||
|
||||
db.close();
|
||||
|
||||
request = indexedDB.openForPrincipal(getPrincipal(spec), name);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
yield undefined;
|
||||
|
||||
db = request.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
info("Deleting some data")
|
||||
|
||||
let trans = db.transaction(objectStoreName, "cleanup");
|
||||
trans.objectStore(objectStoreName).delete(1);
|
||||
|
||||
trans.onabort = unexpectedSuccessHandler;;
|
||||
trans.oncomplete = grabEventAndContinueHandler;
|
||||
|
||||
yield undefined;
|
||||
|
||||
info("Adding data again")
|
||||
|
||||
trans = db.transaction(objectStoreName, "readwrite");
|
||||
trans.objectStore(objectStoreName).add(obj, 1);
|
||||
|
||||
trans.onabort = unexpectedSuccessHandler;
|
||||
trans.oncomplete = grabEventAndContinueHandler;
|
||||
|
||||
yield undefined;
|
||||
|
||||
info("Deleting database");
|
||||
|
||||
db.close();
|
||||
|
||||
request = indexedDB.deleteForPrincipal(getPrincipal(spec), name);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
97
dom/indexedDB/test/unit/test_clear.js
Normal file
97
dom/indexedDB/test/unit/test_clear.js
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const entryCount = 1000;
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = request.result;
|
||||
|
||||
event.target.onsuccess = continueToNextStep;
|
||||
|
||||
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
||||
|
||||
let firstKey;
|
||||
for (let i = 0; i < entryCount; i++) {
|
||||
request = objectStore.add({});
|
||||
request.onerror = errorHandler;
|
||||
if (!i) {
|
||||
request.onsuccess = function(event) {
|
||||
firstKey = event.target.result;
|
||||
};
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
isnot(firstKey, undefined, "got first key");
|
||||
|
||||
let seenEntryCount = 0;
|
||||
|
||||
request = db.transaction("foo").objectStore("foo").openCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
seenEntryCount++;
|
||||
cursor.continue();
|
||||
}
|
||||
else {
|
||||
continueToNextStep();
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
is(seenEntryCount, entryCount, "Correct entry count");
|
||||
|
||||
try {
|
||||
db.transaction("foo").objectStore("foo").clear();
|
||||
ok(false, "clear should throw on READ_ONLY transactions");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "clear should throw on READ_ONLY transactions");
|
||||
}
|
||||
|
||||
request = db.transaction("foo", "readwriteflush")
|
||||
.objectStore("foo")
|
||||
.clear();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(event.target.result === undefined, "Correct event.target.result");
|
||||
ok(request.result === undefined, "Correct request.result");
|
||||
ok(request === event.target, "Correct event.target");
|
||||
|
||||
request = db.transaction("foo").objectStore("foo").openCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
let cursor = request.result;
|
||||
if (cursor) {
|
||||
ok(false, "Shouldn't have any entries");
|
||||
}
|
||||
continueToNextStep();
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
request = db.transaction("foo", "readwrite")
|
||||
.objectStore("foo")
|
||||
.add({});
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
isnot(event.target.result, firstKey, "Got a different key");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
266
dom/indexedDB/test/unit/test_complex_keyPaths.js
Normal file
266
dom/indexedDB/test/unit/test_complex_keyPaths.js
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
// Test object stores
|
||||
|
||||
const name = "test_complex_keyPaths";
|
||||
const keyPaths = [
|
||||
{ keyPath: "id", value: { id: 5 }, key: 5 },
|
||||
{ keyPath: "id", value: { id: "14", iid: 12 }, key: "14" },
|
||||
{ keyPath: "id", value: { iid: "14", id: 12 }, key: 12 },
|
||||
{ keyPath: "id", value: {} },
|
||||
{ keyPath: "id", value: { id: {} } },
|
||||
{ keyPath: "id", value: { id: /x/ } },
|
||||
{ keyPath: "id", value: 2 },
|
||||
{ keyPath: "id", value: undefined },
|
||||
{ keyPath: "foo.id", value: { foo: { id: 7 } }, key: 7 },
|
||||
{ keyPath: "foo.id", value: { id: 7, foo: { id: "asdf" } }, key: "asdf" },
|
||||
{ keyPath: "foo.id", value: { foo: { id: undefined } } },
|
||||
{ keyPath: "foo.id", value: { foo: 47 } },
|
||||
{ keyPath: "foo.id", value: {} },
|
||||
{ keyPath: "", value: "foopy", key: "foopy" },
|
||||
{ keyPath: "", value: 2, key: 2 },
|
||||
{ keyPath: "", value: undefined },
|
||||
{ keyPath: "", value: { id: 12 } },
|
||||
{ keyPath: "", value: /x/ },
|
||||
{ keyPath: "foo.bar", value: { baz: 1, foo: { baz2: 2, bar: "xo" } }, key: "xo" },
|
||||
{ keyPath: "foo.bar.baz", value: { foo: { bar: { bazz: 16, baz: 17 } } }, key: 17 },
|
||||
{ keyPath: "foo..id", exception: true },
|
||||
{ keyPath: "foo.", exception: true },
|
||||
{ keyPath: "fo o", exception: true },
|
||||
{ keyPath: "foo ", exception: true },
|
||||
{ keyPath: "foo[bar]",exception: true },
|
||||
{ keyPath: "foo[1]", exception: true },
|
||||
{ keyPath: "$('id').stuff", exception: true },
|
||||
{ keyPath: "foo.2.bar", exception: true },
|
||||
{ keyPath: "foo. .bar", exception: true },
|
||||
{ keyPath: ".bar", exception: true },
|
||||
{ keyPath: [], exception: true },
|
||||
|
||||
{ keyPath: ["foo", "bar"], value: { foo: 1, bar: 2 }, key: [1, 2] },
|
||||
{ keyPath: ["foo"], value: { foo: 1, bar: 2 }, key: [1] },
|
||||
{ keyPath: ["foo", "bar", "bar"], value: { foo: 1, bar: "x" }, key: [1, "x", "x"] },
|
||||
{ keyPath: ["x", "y"], value: { x: [], y: "x" }, key: [[], "x"] },
|
||||
{ keyPath: ["x", "y"], value: { x: [[1]], y: "x" }, key: [[[1]], "x"] },
|
||||
{ keyPath: ["x", "y"], value: { x: [[1]], y: new Date(1) }, key: [[[1]], new Date(1)] },
|
||||
{ keyPath: ["x", "y"], value: { x: [[1]], y: [new Date(3)] }, key: [[[1]], [new Date(3)]] },
|
||||
{ keyPath: ["x", "y.bar"], value: { x: "hi", y: { bar: "x"} }, key: ["hi", "x"] },
|
||||
{ keyPath: ["x.y", "y.bar"], value: { x: { y: "hello" }, y: { bar: "nurse"} }, key: ["hello", "nurse"] },
|
||||
{ keyPath: ["", ""], value: 5, key: [5, 5] },
|
||||
{ keyPath: ["x", "y"], value: { x: 1 } },
|
||||
{ keyPath: ["x", "y"], value: { y: 1 } },
|
||||
{ keyPath: ["x", "y"], value: { x: 1, y: undefined } },
|
||||
{ keyPath: ["x", "y"], value: { x: null, y: 1 } },
|
||||
{ keyPath: ["x", "y.bar"], value: { x: null, y: { bar: "x"} } },
|
||||
{ keyPath: ["x", "y"], value: { x: 1, y: false } },
|
||||
{ keyPath: ["x", "y", "z"], value: { x: 1, y: false, z: "a" } },
|
||||
{ keyPath: [".x", "y", "z"], exception: true },
|
||||
{ keyPath: ["x", "y ", "z"], exception: true },
|
||||
];
|
||||
|
||||
let openRequest = indexedDB.open(name, 1);
|
||||
openRequest.onerror = errorHandler;
|
||||
openRequest.onupgradeneeded = grabEventAndContinueHandler;
|
||||
openRequest.onsuccess = unexpectedSuccessHandler;
|
||||
let event = yield undefined;
|
||||
let db = event.target.result;
|
||||
|
||||
let stores = {};
|
||||
|
||||
// Test creating object stores and inserting data
|
||||
for (let i = 0; i < keyPaths.length; i++) {
|
||||
let info = keyPaths[i];
|
||||
|
||||
let test = " for objectStore test " + JSON.stringify(info);
|
||||
let indexName = JSON.stringify(info.keyPath);
|
||||
if (!stores[indexName]) {
|
||||
try {
|
||||
let objectStore = db.createObjectStore(indexName, { keyPath: info.keyPath });
|
||||
ok(!("exception" in info), "shouldn't throw" + test);
|
||||
is(JSON.stringify(objectStore.keyPath), JSON.stringify(info.keyPath),
|
||||
"correct keyPath property" + test);
|
||||
ok(objectStore.keyPath === objectStore.keyPath,
|
||||
"object identity should be preserved");
|
||||
stores[indexName] = objectStore;
|
||||
} catch (e) {
|
||||
ok("exception" in info, "should throw" + test);
|
||||
is(e.name, "SyntaxError", "expect a SyntaxError" + test);
|
||||
ok(e instanceof DOMException, "Got a DOM Exception" + test);
|
||||
is(e.code, DOMException.SYNTAX_ERR, "expect a syntax error" + test);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let store = stores[indexName];
|
||||
|
||||
try {
|
||||
request = store.add(info.value);
|
||||
ok("key" in info, "successfully created request to insert value" + test);
|
||||
} catch (e) {
|
||||
ok(!("key" in info), "threw when attempted to insert" + test);
|
||||
ok(e instanceof DOMException, "Got a DOMException" + test);
|
||||
is(e.name, "DataError", "expect a DataError" + test);
|
||||
is(e.code, 0, "expect zero" + test);
|
||||
continue;
|
||||
}
|
||||
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
let e = yield undefined;
|
||||
is(e.type, "success", "inserted successfully" + test);
|
||||
is(e.target, request, "expected target" + test);
|
||||
ok(compareKeys(request.result, info.key), "found correct key" + test);
|
||||
is(indexedDB.cmp(request.result, info.key), 0, "returned key compares correctly" + test);
|
||||
|
||||
store.get(info.key).onsuccess = grabEventAndContinueHandler;
|
||||
e = yield undefined;
|
||||
isnot(e.target.result, undefined, "Did find entry");
|
||||
|
||||
// Check that cursor.update work as expected
|
||||
request = store.openCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
e = yield undefined;
|
||||
let cursor = e.target.result;
|
||||
request = cursor.update(info.value);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
yield undefined;
|
||||
ok(true, "Successfully updated cursor" + test);
|
||||
|
||||
// Check that cursor.update throws as expected when key is changed
|
||||
let newValue = cursor.value;
|
||||
let destProp = Array.isArray(info.keyPath) ? info.keyPath[0] : info.keyPath;
|
||||
if (destProp) {
|
||||
eval("newValue." + destProp + " = 'newKeyValue'");
|
||||
}
|
||||
else {
|
||||
newValue = 'newKeyValue';
|
||||
}
|
||||
let didThrow;
|
||||
try {
|
||||
cursor.update(newValue);
|
||||
}
|
||||
catch (ex) {
|
||||
didThrow = ex;
|
||||
}
|
||||
ok(didThrow instanceof DOMException, "Got a DOMException" + test);
|
||||
is(didThrow.name, "DataError", "expect a DataError" + test);
|
||||
is(didThrow.code, 0, "expect zero" + test);
|
||||
|
||||
// Clear object store to prepare for next test
|
||||
store.clear().onsuccess = grabEventAndContinueHandler;
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
// Attempt to create indexes and insert data
|
||||
let store = db.createObjectStore("indexStore");
|
||||
let indexes = {};
|
||||
for (let i = 0; i < keyPaths.length; i++) {
|
||||
let info = keyPaths[i];
|
||||
let test = " for index test " + JSON.stringify(info);
|
||||
let indexName = JSON.stringify(info.keyPath);
|
||||
if (!indexes[indexName]) {
|
||||
try {
|
||||
let index = store.createIndex(indexName, info.keyPath);
|
||||
ok(!("exception" in info), "shouldn't throw" + test);
|
||||
is(JSON.stringify(index.keyPath), JSON.stringify(info.keyPath),
|
||||
"index has correct keyPath property" + test);
|
||||
ok(index.keyPath === index.keyPath,
|
||||
"object identity should be preserved");
|
||||
indexes[indexName] = index;
|
||||
} catch (e) {
|
||||
ok("exception" in info, "should throw" + test);
|
||||
is(e.name, "SyntaxError", "expect a SyntaxError" + test);
|
||||
ok(e instanceof DOMException, "Got a DOM Exception" + test);
|
||||
is(e.code, DOMException.SYNTAX_ERR, "expect a syntax error" + test);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let index = indexes[indexName];
|
||||
|
||||
request = store.add(info.value, 1);
|
||||
if ("key" in info) {
|
||||
index.getKey(info.key).onsuccess = grabEventAndContinueHandler;
|
||||
e = yield undefined;
|
||||
is(e.target.result, 1, "found value when reading" + test);
|
||||
}
|
||||
else {
|
||||
index.count().onsuccess = grabEventAndContinueHandler;
|
||||
e = yield undefined;
|
||||
is(e.target.result, 0, "should be empty" + test);
|
||||
}
|
||||
|
||||
store.clear().onsuccess = grabEventAndContinueHandler;
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
// Autoincrement and complex key paths
|
||||
let aitests = [{ v: {}, k: 1, res: { foo: { id: 1 }} },
|
||||
{ v: { value: "x" }, k: 2, res: { value: "x", foo: { id: 2 }} },
|
||||
{ v: { value: "x", foo: {} }, k: 3, res: { value: "x", foo: { id: 3 }} },
|
||||
{ v: { v: "x", foo: { x: "y" } }, k: 4, res: { v: "x", foo: { x: "y", id: 4 }} },
|
||||
{ v: { value: 2, foo: { id: 10 }}, k: 10 },
|
||||
{ v: { value: 2 }, k: 11, res: { value: 2, foo: { id: 11 }} },
|
||||
{ v: true, },
|
||||
{ v: { value: 2, foo: 12 }, },
|
||||
{ v: { foo: { id: true }}, },
|
||||
{ v: { foo: { x: 5, id: {} }}, },
|
||||
{ v: undefined, },
|
||||
{ v: { foo: undefined }, },
|
||||
{ v: { foo: { id: undefined }}, },
|
||||
{ v: null, },
|
||||
{ v: { foo: null }, },
|
||||
{ v: { foo: { id: null }}, },
|
||||
];
|
||||
|
||||
store = db.createObjectStore("gen", { keyPath: "foo.id", autoIncrement: true });
|
||||
for (let i = 0; i < aitests.length; ++i) {
|
||||
let info = aitests[i];
|
||||
let test = " for autoIncrement test " + JSON.stringify(info);
|
||||
|
||||
let preValue = JSON.stringify(info.v);
|
||||
if ("k" in info) {
|
||||
store.add(info.v).onsuccess = grabEventAndContinueHandler;
|
||||
is(JSON.stringify(info.v), preValue, "put didn't modify value" + test);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
store.add(info.v);
|
||||
ok(false, "should throw" + test);
|
||||
}
|
||||
catch(e) {
|
||||
ok(true, "did throw" + test);
|
||||
ok(e instanceof DOMException, "Got a DOMException" + test);
|
||||
is(e.name, "DataError", "expect a DataError" + test);
|
||||
is(e.code, 0, "expect zero" + test);
|
||||
|
||||
is(JSON.stringify(info.v), preValue, "failing put didn't modify value" + test);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let e = yield undefined;
|
||||
is(e.target.result, info.k, "got correct return key" + test);
|
||||
|
||||
store.get(info.k).onsuccess = grabEventAndContinueHandler;
|
||||
e = yield undefined;
|
||||
is(JSON.stringify(e.target.result), JSON.stringify(info.res || info.v),
|
||||
"expected value stored" + test);
|
||||
}
|
||||
|
||||
openRequest.onsuccess = grabEventAndContinueHandler;
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
354
dom/indexedDB/test/unit/test_count.js
Normal file
354
dom/indexedDB/test/unit/test_count.js
Normal file
|
|
@ -0,0 +1,354 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const objectStoreName = "People";
|
||||
|
||||
const objectStoreData = [
|
||||
{ key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
|
||||
{ key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
|
||||
{ key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7737", value: { name: "Pat", height: 65 } },
|
||||
{ key: "237-23-7738", value: { name: "Mel", height: 66, weight: {} } },
|
||||
{ key: "237-23-7739", value: { name: "Tom", height: 62, weight: 130 } }
|
||||
];
|
||||
|
||||
const indexData = {
|
||||
name: "weight",
|
||||
keyPath: "weight",
|
||||
options: { unique: false }
|
||||
};
|
||||
|
||||
const weightSort = [1, 0, 3, 7, 4, 2];
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Got correct event type");
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
let objectStore = db.createObjectStore(objectStoreName, { });
|
||||
objectStore.createIndex(indexData.name, indexData.keyPath,
|
||||
indexData.options);
|
||||
|
||||
for (let data of objectStoreData) {
|
||||
objectStore.add(data.value, data.key);
|
||||
}
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got correct event type");
|
||||
|
||||
objectStore = db.transaction(db.objectStoreNames)
|
||||
.objectStore(objectStoreName);
|
||||
|
||||
objectStore.count().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, objectStoreData.length,
|
||||
"Correct number of object store entries for all keys");
|
||||
|
||||
objectStore.count(null).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, objectStoreData.length,
|
||||
"Correct number of object store entries for null key");
|
||||
|
||||
objectStore.count(objectStoreData[2].key).onsuccess =
|
||||
grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 1,
|
||||
"Correct number of object store entries for single existing key");
|
||||
|
||||
objectStore.count("foo").onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 0,
|
||||
"Correct number of object store entries for single non-existing key");
|
||||
|
||||
let keyRange = IDBKeyRange.only(objectStoreData[2].key);
|
||||
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 1,
|
||||
"Correct number of object store entries for existing only keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.only("foo");
|
||||
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 0,
|
||||
"Correct number of object store entries for non-existing only keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.lowerBound(objectStoreData[2].key);
|
||||
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, objectStoreData.length - 2,
|
||||
"Correct number of object store entries for lowerBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.lowerBound(objectStoreData[2].key, true);
|
||||
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, objectStoreData.length - 3,
|
||||
"Correct number of object store entries for lowerBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.lowerBound("foo");
|
||||
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 0,
|
||||
"Correct number of object store entries for lowerBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.upperBound(objectStoreData[2].key, false);
|
||||
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 3,
|
||||
"Correct number of object store entries for upperBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.upperBound(objectStoreData[2].key, true);
|
||||
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 2,
|
||||
"Correct number of object store entries for upperBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.upperBound("foo", true);
|
||||
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, objectStoreData.length,
|
||||
"Correct number of object store entries for upperBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.bound(objectStoreData[0].key,
|
||||
objectStoreData[objectStoreData.length - 1].key);
|
||||
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, objectStoreData.length,
|
||||
"Correct number of object store entries for bound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.bound(objectStoreData[0].key,
|
||||
objectStoreData[objectStoreData.length - 1].key,
|
||||
true);
|
||||
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, objectStoreData.length - 1,
|
||||
"Correct number of object store entries for bound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.bound(objectStoreData[0].key,
|
||||
objectStoreData[objectStoreData.length - 1].key,
|
||||
true, true);
|
||||
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, objectStoreData.length - 2,
|
||||
"Correct number of object store entries for bound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.bound("foo", "foopy", true, true);
|
||||
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 0,
|
||||
"Correct number of object store entries for bound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.bound(objectStoreData[0].key, "foo", true, true);
|
||||
objectStore.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, objectStoreData.length - 1,
|
||||
"Correct number of object store entries for bound keyRange");
|
||||
|
||||
let index = objectStore.index(indexData.name);
|
||||
|
||||
index.count().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, weightSort.length,
|
||||
"Correct number of index entries for no key");
|
||||
|
||||
index.count(objectStoreData[7].value.weight).onsuccess =
|
||||
grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 2,
|
||||
"Correct number of index entries for duplicate key");
|
||||
|
||||
index.count(objectStoreData[0].value.weight).onsuccess =
|
||||
grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 1,
|
||||
"Correct number of index entries for single key");
|
||||
|
||||
keyRange = IDBKeyRange.only(objectStoreData[0].value.weight);
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 1,
|
||||
"Correct number of index entries for only existing keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.only("foo");
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 0,
|
||||
"Correct number of index entries for only non-existing keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.only(objectStoreData[7].value.weight);
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 2,
|
||||
"Correct number of index entries for only duplicate keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[0]].value.weight);
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, weightSort.length,
|
||||
"Correct number of index entries for lowerBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[1]].value.weight);
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, weightSort.length - 1,
|
||||
"Correct number of index entries for lowerBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[0]].value.weight - 1);
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, weightSort.length,
|
||||
"Correct number of index entries for lowerBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[0]].value.weight,
|
||||
true);
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, weightSort.length - 1,
|
||||
"Correct number of index entries for lowerBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight);
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 1,
|
||||
"Correct number of index entries for lowerBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight,
|
||||
true);
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 0,
|
||||
"Correct number of index entries for lowerBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.lowerBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight + 1,
|
||||
true);
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 0,
|
||||
"Correct number of index entries for lowerBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.upperBound(objectStoreData[weightSort[0]].value.weight);
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 1,
|
||||
"Correct number of index entries for upperBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.upperBound(objectStoreData[weightSort[0]].value.weight,
|
||||
true);
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 0,
|
||||
"Correct number of index entries for upperBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.upperBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight);
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, weightSort.length,
|
||||
"Correct number of index entries for upperBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.upperBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight,
|
||||
true);
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, weightSort.length - 1,
|
||||
"Correct number of index entries for upperBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.upperBound(objectStoreData[weightSort[weightSort.length - 1]].value.weight,
|
||||
true);
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, weightSort.length - 1,
|
||||
"Correct number of index entries for upperBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.upperBound("foo");
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, weightSort.length,
|
||||
"Correct number of index entries for upperBound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.bound("foo", "foopy");
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 0,
|
||||
"Correct number of index entries for bound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.bound(objectStoreData[weightSort[0]].value.weight,
|
||||
objectStoreData[weightSort[weightSort.length - 1]].value.weight);
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, weightSort.length,
|
||||
"Correct number of index entries for bound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.bound(objectStoreData[weightSort[0]].value.weight,
|
||||
objectStoreData[weightSort[weightSort.length - 1]].value.weight,
|
||||
true);
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, weightSort.length - 1,
|
||||
"Correct number of index entries for bound keyRange");
|
||||
|
||||
keyRange = IDBKeyRange.bound(objectStoreData[weightSort[0]].value.weight,
|
||||
objectStoreData[weightSort[weightSort.length - 1]].value.weight,
|
||||
true, true);
|
||||
index.count(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, weightSort.length - 2,
|
||||
"Correct number of index entries for bound keyRange");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
121
dom/indexedDB/test/unit/test_create_index.js
Normal file
121
dom/indexedDB/test/unit/test_create_index.js
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const objectStoreInfo = [
|
||||
{ name: "a", options: { keyPath: "id", autoIncrement: true } },
|
||||
{ name: "b", options: { keyPath: "id", autoIncrement: false } },
|
||||
];
|
||||
const indexInfo = [
|
||||
{ name: "1", keyPath: "unique_value", options: { unique: true } },
|
||||
{ name: "2", keyPath: "value", options: { unique: false } },
|
||||
{ name: "3", keyPath: "value", options: { unique: false } },
|
||||
{ name: "", keyPath: "value", options: { unique: false } },
|
||||
{ name: null, keyPath: "value", options: { unique: false } },
|
||||
{ name: undefined, keyPath: "value", options: { unique: false } },
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
let event = yield undefined;
|
||||
let db = event.target.result;
|
||||
|
||||
for (let i = 0; i < objectStoreInfo.length; i++) {
|
||||
let info = objectStoreInfo[i];
|
||||
let objectStore = info.hasOwnProperty("options") ?
|
||||
db.createObjectStore(info.name, info.options) :
|
||||
db.createObjectStore(info.name);
|
||||
|
||||
try {
|
||||
request = objectStore.createIndex("Hola");
|
||||
ok(false, "createIndex with no keyPath should throw");
|
||||
}
|
||||
catch(e) {
|
||||
ok(true, "createIndex with no keyPath should throw");
|
||||
}
|
||||
|
||||
let ex;
|
||||
try {
|
||||
objectStore.createIndex("Hola", ["foo"], { multiEntry: true });
|
||||
}
|
||||
catch(e) {
|
||||
ex = e;
|
||||
}
|
||||
ok(ex, "createIndex with array keyPath and multiEntry should throw");
|
||||
is(ex.name, "InvalidAccessError", "should throw right exception");
|
||||
ok(ex instanceof DOMException, "should throw right exception");
|
||||
is(ex.code, DOMException.INVALID_ACCESS_ERR, "should throw right exception");
|
||||
|
||||
try {
|
||||
objectStore.createIndex("foo", "bar", 10);
|
||||
ok(false, "createIndex with bad options should throw");
|
||||
}
|
||||
catch(e) {
|
||||
ok(true, "createIndex with bad options threw");
|
||||
}
|
||||
|
||||
ok(objectStore.createIndex("foo", "bar", { foo: "" }),
|
||||
"createIndex with unknown options should not throw");
|
||||
objectStore.deleteIndex("foo");
|
||||
|
||||
// Test index creation, and that it ends up in indexNames.
|
||||
let objectStoreName = info.name;
|
||||
for (let j = 0; j < indexInfo.length; j++) {
|
||||
let info = indexInfo[j];
|
||||
let count = objectStore.indexNames.length;
|
||||
let index = info.hasOwnProperty("options") ?
|
||||
objectStore.createIndex(info.name, info.keyPath,
|
||||
info.options) :
|
||||
objectStore.createIndex(info.name, info.keyPath);
|
||||
|
||||
let name = info.name;
|
||||
if (name === null) {
|
||||
name = "null";
|
||||
}
|
||||
else if (name === undefined) {
|
||||
name = "undefined";
|
||||
}
|
||||
|
||||
is(index.name, name, "correct name");
|
||||
is(index.keyPath, info.keyPath, "correct keyPath");
|
||||
is(index.unique, info.options.unique, "correct uniqueness");
|
||||
|
||||
is(objectStore.indexNames.length, count + 1,
|
||||
"indexNames grew in size");
|
||||
let found = false;
|
||||
for (let k = 0; k < objectStore.indexNames.length; k++) {
|
||||
if (objectStore.indexNames.item(k) == name) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(found, "Name is on objectStore.indexNames");
|
||||
|
||||
ok(event.target.transaction, "event has a transaction");
|
||||
ok(event.target.transaction.db === db,
|
||||
"transaction has the right db");
|
||||
is(event.target.transaction.mode, "versionchange",
|
||||
"transaction has the correct mode");
|
||||
is(event.target.transaction.objectStoreNames.length, i + 1,
|
||||
"transaction only has one object store");
|
||||
ok(event.target.transaction.objectStoreNames.contains(objectStoreName),
|
||||
"transaction has the correct object store");
|
||||
}
|
||||
}
|
||||
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const data = { id: new Date().getTime(),
|
||||
num: parseInt(Math.random() * 1000) };
|
||||
|
||||
let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
event.target.onsuccess = continueToNextStep;
|
||||
|
||||
// Make object store, add data.
|
||||
let objectStore = db.createObjectStore("foo", { keyPath: "id" });
|
||||
objectStore.add(data);
|
||||
yield undefined;
|
||||
db.close();
|
||||
|
||||
request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 2);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
let db2 = event.target.result;
|
||||
db2.onerror = errorHandler;
|
||||
|
||||
event.target.onsuccess = continueToNextStep;
|
||||
|
||||
// Create index.
|
||||
event.target.transaction.objectStore("foo").createIndex("foo", "num");
|
||||
yield undefined;
|
||||
|
||||
// Make sure our object made it into the index.
|
||||
let seenCount = 0;
|
||||
|
||||
|
||||
db2.transaction("foo").objectStore("foo").index("foo")
|
||||
.openKeyCursor().onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, data.num, "Good key");
|
||||
is(cursor.primaryKey, data.id, "Good value");
|
||||
seenCount++;
|
||||
cursor.continue();
|
||||
}
|
||||
else {
|
||||
continueToNextStep();
|
||||
}
|
||||
};
|
||||
yield undefined;
|
||||
|
||||
is(seenCount, 1, "Saw our entry");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
123
dom/indexedDB/test/unit/test_create_locale_aware_index.js
Normal file
123
dom/indexedDB/test/unit/test_create_locale_aware_index.js
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const objectStoreInfo = [
|
||||
{ name: "a", options: { keyPath: "id", autoIncrement: true } },
|
||||
{ name: "b", options: { keyPath: "id", autoIncrement: false } },
|
||||
];
|
||||
const indexInfo = [
|
||||
{ name: "1", keyPath: "unique_value", options: { unique: true, locale: "es-ES" } },
|
||||
{ name: "2", keyPath: "unique_value", options: { unique: true, locale: null } },
|
||||
{ name: "3", keyPath: "value", options: { unique: false, locale: "es-ES" } },
|
||||
{ name: "4", keyPath: "value", options: { unique: false, locale: "es-ES" } },
|
||||
{ name: "", keyPath: "value", options: { unique: false, locale: "es-ES" } },
|
||||
{ name: null, keyPath: "value", options: { unique: false, locale: "es-ES" } },
|
||||
{ name: undefined, keyPath: "value", options: { unique: false, locale: "es-ES" } },
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
let event = yield undefined;
|
||||
let db = event.target.result;
|
||||
|
||||
for (let i = 0; i < objectStoreInfo.length; i++) {
|
||||
let info = objectStoreInfo[i];
|
||||
let objectStore = info.hasOwnProperty("options") ?
|
||||
db.createObjectStore(info.name, info.options) :
|
||||
db.createObjectStore(info.name);
|
||||
|
||||
try {
|
||||
request = objectStore.createIndex("Hola");
|
||||
ok(false, "createIndex with no keyPath should throw");
|
||||
}
|
||||
catch(e) {
|
||||
ok(true, "createIndex with no keyPath should throw");
|
||||
}
|
||||
|
||||
let ex;
|
||||
try {
|
||||
objectStore.createIndex("Hola", ["foo"], { multiEntry: true });
|
||||
}
|
||||
catch(e) {
|
||||
ex = e;
|
||||
}
|
||||
ok(ex, "createIndex with array keyPath and multiEntry should throw");
|
||||
is(ex.name, "InvalidAccessError", "should throw right exception");
|
||||
ok(ex instanceof DOMException, "should throw right exception");
|
||||
is(ex.code, DOMException.INVALID_ACCESS_ERR, "should throw right exception");
|
||||
|
||||
try {
|
||||
objectStore.createIndex("foo", "bar", 10);
|
||||
ok(false, "createIndex with bad options should throw");
|
||||
}
|
||||
catch(e) {
|
||||
ok(true, "createIndex with bad options threw");
|
||||
}
|
||||
|
||||
ok(objectStore.createIndex("foo", "bar", { foo: "" }),
|
||||
"createIndex with unknown options should not throw");
|
||||
objectStore.deleteIndex("foo");
|
||||
|
||||
// Test index creation, and that it ends up in indexNames.
|
||||
let objectStoreName = info.name;
|
||||
for (let j = 0; j < indexInfo.length; j++) {
|
||||
let info = indexInfo[j];
|
||||
let count = objectStore.indexNames.length;
|
||||
let index = info.hasOwnProperty("options") ?
|
||||
objectStore.createIndex(info.name, info.keyPath,
|
||||
info.options) :
|
||||
objectStore.createIndex(info.name, info.keyPath);
|
||||
|
||||
let name = info.name;
|
||||
if (name === null) {
|
||||
name = "null";
|
||||
}
|
||||
else if (name === undefined) {
|
||||
name = "undefined";
|
||||
}
|
||||
|
||||
is(index.name, name, "correct name");
|
||||
is(index.keyPath, info.keyPath, "correct keyPath");
|
||||
is(index.unique, info.options.unique, "correct uniqueness");
|
||||
is(index.locale, info.options.locale, "correct locale");
|
||||
|
||||
is(objectStore.indexNames.length, count + 1,
|
||||
"indexNames grew in size");
|
||||
let found = false;
|
||||
for (let k = 0; k < objectStore.indexNames.length; k++) {
|
||||
if (objectStore.indexNames.item(k) == name) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(found, "Name is on objectStore.indexNames");
|
||||
|
||||
ok(event.target.transaction, "event has a transaction");
|
||||
ok(event.target.transaction.db === db,
|
||||
"transaction has the right db");
|
||||
is(event.target.transaction.mode, "versionchange",
|
||||
"transaction has the correct mode");
|
||||
is(event.target.transaction.objectStoreNames.length, i + 1,
|
||||
"transaction only has one object store");
|
||||
ok(event.target.transaction.objectStoreNames.contains(objectStoreName),
|
||||
"transaction has the correct object store");
|
||||
}
|
||||
}
|
||||
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
134
dom/indexedDB/test/unit/test_create_objectStore.js
Normal file
134
dom/indexedDB/test/unit/test_create_objectStore.js
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const objectStoreInfo = [
|
||||
{ name: "1", options: { keyPath: null } },
|
||||
{ name: "2", options: { keyPath: null, autoIncrement: true } },
|
||||
{ name: "3", options: { keyPath: null, autoIncrement: false } },
|
||||
{ name: "4", options: { keyPath: null } },
|
||||
{ name: "5", options: { keyPath: "foo" } },
|
||||
{ name: "6" },
|
||||
{ name: "7", options: null },
|
||||
{ name: "8", options: { autoIncrement: true } },
|
||||
{ name: "9", options: { autoIncrement: false } },
|
||||
{ name: "10", options: { keyPath: "foo", autoIncrement: false } },
|
||||
{ name: "11", options: { keyPath: "foo", autoIncrement: true } },
|
||||
{ name: "" },
|
||||
{ name: null },
|
||||
{ name: undefined }
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
let count = db.objectStoreNames.length;
|
||||
is(count, 0, "correct objectStoreNames length");
|
||||
|
||||
try {
|
||||
db.createObjectStore("foo", "bar");
|
||||
ok(false, "createObjectStore with bad options should throw");
|
||||
}
|
||||
catch(e) {
|
||||
ok(true, "createObjectStore with bad options");
|
||||
}
|
||||
|
||||
ok(db.createObjectStore("foo", { foo: "" }),
|
||||
"createObjectStore with unknown options should not throw");
|
||||
db.deleteObjectStore("foo");
|
||||
|
||||
for (let index in objectStoreInfo) {
|
||||
index = parseInt(index);
|
||||
const info = objectStoreInfo[index];
|
||||
|
||||
let objectStore = info.hasOwnProperty("options") ?
|
||||
db.createObjectStore(info.name, info.options) :
|
||||
db.createObjectStore(info.name);
|
||||
|
||||
is(db.objectStoreNames.length, index + 1,
|
||||
"updated objectStoreNames list");
|
||||
|
||||
let name = info.name;
|
||||
if (name === null) {
|
||||
name = "null";
|
||||
}
|
||||
else if (name === undefined) {
|
||||
name = "undefined";
|
||||
}
|
||||
|
||||
let found = false;
|
||||
for (let i = 0; i <= index; i++) {
|
||||
if (db.objectStoreNames.item(i) == name) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
is(found, true, "objectStoreNames contains name");
|
||||
|
||||
is(objectStore.name, name, "Bad name");
|
||||
is(objectStore.keyPath, info.options && info.options.keyPath ?
|
||||
info.options.keyPath : null,
|
||||
"Bad keyPath");
|
||||
if(objectStore.indexNames.length, 0, "Bad indexNames");
|
||||
|
||||
ok(event.target.transaction, "event has a transaction");
|
||||
ok(event.target.transaction.db === db, "transaction has the right db");
|
||||
is(event.target.transaction.mode, "versionchange",
|
||||
"transaction has the correct mode");
|
||||
is(event.target.transaction.objectStoreNames.length, index + 1,
|
||||
"transaction has correct objectStoreNames list");
|
||||
found = false;
|
||||
for (let j = 0; j < event.target.transaction.objectStoreNames.length;
|
||||
j++) {
|
||||
if (event.target.transaction.objectStoreNames.item(j) == name) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
is(found, true, "transaction has correct objectStoreNames list");
|
||||
}
|
||||
|
||||
// Can't handle autoincrement and empty keypath
|
||||
let ex;
|
||||
try {
|
||||
db.createObjectStore("storefail", { keyPath: "", autoIncrement: true });
|
||||
}
|
||||
catch(e) {
|
||||
ex = e;
|
||||
}
|
||||
ok(ex, "createObjectStore with empty keyPath and autoIncrement should throw");
|
||||
is(ex.name, "InvalidAccessError", "should throw right exception");
|
||||
ok(ex instanceof DOMException, "should throw right exception");
|
||||
is(ex.code, DOMException.INVALID_ACCESS_ERR, "should throw right exception");
|
||||
|
||||
// Can't handle autoincrement and array keypath
|
||||
try {
|
||||
db.createObjectStore("storefail", { keyPath: ["a"], autoIncrement: true });
|
||||
}
|
||||
catch(e) {
|
||||
ex = e;
|
||||
}
|
||||
ok(ex, "createObjectStore with array keyPath and autoIncrement should throw");
|
||||
is(ex.name, "InvalidAccessError", "should throw right exception");
|
||||
ok(ex instanceof DOMException, "should throw right exception");
|
||||
is(ex.code, DOMException.INVALID_ACCESS_ERR, "should throw right exception");
|
||||
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
41
dom/indexedDB/test/unit/test_cursor_cycle.js
Normal file
41
dom/indexedDB/test/unit/test_cursor_cycle.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const Bob = { ss: "237-23-7732", name: "Bob" };
|
||||
|
||||
let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
event.target.onsuccess = continueToNextStep;
|
||||
|
||||
let objectStore = db.createObjectStore("foo", { keyPath: "ss" });
|
||||
objectStore.createIndex("name", "name", { unique: true });
|
||||
objectStore.add(Bob);
|
||||
yield undefined;
|
||||
|
||||
db.transaction("foo", "readwrite").objectStore("foo")
|
||||
.index("name").openCursor().onsuccess = function(event) {
|
||||
event.target.transaction.oncomplete = continueToNextStep;
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
let objectStore = event.target.transaction.objectStore("foo");
|
||||
objectStore.delete(Bob.ss)
|
||||
.onsuccess = function(event) { cursor.continue(); };
|
||||
}
|
||||
};
|
||||
yield undefined;
|
||||
finishTest();
|
||||
|
||||
objectStore = null; // Bug 943409 workaround.
|
||||
|
||||
yield undefined;
|
||||
}
|
||||
118
dom/indexedDB/test/unit/test_cursor_mutation.js
Normal file
118
dom/indexedDB/test/unit/test_cursor_mutation.js
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const objectStoreData = [
|
||||
// This one will be removed.
|
||||
{ ss: "237-23-7732", name: "Bob" },
|
||||
|
||||
// These will always be included.
|
||||
{ ss: "237-23-7733", name: "Ann" },
|
||||
{ ss: "237-23-7734", name: "Ron" },
|
||||
{ ss: "237-23-7735", name: "Sue" },
|
||||
{ ss: "237-23-7736", name: "Joe" },
|
||||
|
||||
// This one will be added.
|
||||
{ ss: "237-23-7737", name: "Pat" }
|
||||
];
|
||||
|
||||
// Post-add and post-remove data ordered by name.
|
||||
const objectStoreDataNameSort = [ 1, 4, 5, 2, 3 ];
|
||||
|
||||
let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
event.target.onsuccess = continueToNextStep;
|
||||
|
||||
let objectStore = db.createObjectStore("foo", { keyPath: "ss" });
|
||||
objectStore.createIndex("name", "name", { unique: true });
|
||||
|
||||
for (let i = 0; i < objectStoreData.length - 1; i++) {
|
||||
objectStore.add(objectStoreData[i]);
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
let count = 0;
|
||||
|
||||
let sawAdded = false;
|
||||
let sawRemoved = false;
|
||||
|
||||
db.transaction("foo").objectStore("foo").openCursor().onsuccess =
|
||||
function(event) {
|
||||
event.target.transaction.oncomplete = continueToNextStep;
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
if (cursor.value.name == objectStoreData[0].name) {
|
||||
sawRemoved = true;
|
||||
}
|
||||
if (cursor.value.name ==
|
||||
objectStoreData[objectStoreData.length - 1].name) {
|
||||
sawAdded = true;
|
||||
}
|
||||
cursor.continue();
|
||||
count++;
|
||||
}
|
||||
};
|
||||
yield undefined;
|
||||
|
||||
is(count, objectStoreData.length - 1, "Good initial count");
|
||||
is(sawAdded, false, "Didn't see item that is about to be added");
|
||||
is(sawRemoved, true, "Saw item that is about to be removed");
|
||||
|
||||
count = 0;
|
||||
sawAdded = false;
|
||||
sawRemoved = false;
|
||||
|
||||
db.transaction("foo", "readwrite").objectStore("foo")
|
||||
.index("name").openCursor().onsuccess = function(event) {
|
||||
event.target.transaction.oncomplete = continueToNextStep;
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
if (cursor.value.name == objectStoreData[0].name) {
|
||||
sawRemoved = true;
|
||||
}
|
||||
if (cursor.value.name ==
|
||||
objectStoreData[objectStoreData.length - 1].name) {
|
||||
sawAdded = true;
|
||||
}
|
||||
|
||||
is(cursor.value.name,
|
||||
objectStoreData[objectStoreDataNameSort[count++]].name,
|
||||
"Correct name");
|
||||
|
||||
if (count == 1) {
|
||||
let objectStore = event.target.transaction.objectStore("foo");
|
||||
objectStore.delete(objectStoreData[0].ss)
|
||||
.onsuccess = function(event) {
|
||||
objectStore.add(objectStoreData[objectStoreData.length - 1])
|
||||
.onsuccess =
|
||||
function(event) {
|
||||
cursor.continue();
|
||||
};
|
||||
};
|
||||
}
|
||||
else {
|
||||
cursor.continue();
|
||||
}
|
||||
}
|
||||
};
|
||||
yield undefined;
|
||||
|
||||
is(count, objectStoreData.length - 1, "Good final count");
|
||||
is(sawAdded, true, "Saw item that was added");
|
||||
is(sawRemoved, false, "Didn't see item that was removed");
|
||||
|
||||
finishTest();
|
||||
|
||||
objectStore = null; // Bug 943409 workaround.
|
||||
|
||||
yield undefined;
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const START_DATA = "hi";
|
||||
const END_DATA = "bye";
|
||||
const objectStoreInfo = [
|
||||
{ name: "1", options: { keyPath: null }, key: 1,
|
||||
entry: { data: START_DATA } },
|
||||
{ name: "2", options: { keyPath: "foo" },
|
||||
entry: { foo: 1, data: START_DATA } },
|
||||
{ name: "3", options: { keyPath: null, autoIncrement: true },
|
||||
entry: { data: START_DATA } },
|
||||
{ name: "4", options: { keyPath: "foo", autoIncrement: true },
|
||||
entry: { data: START_DATA } },
|
||||
];
|
||||
|
||||
for (let i = 0; i < objectStoreInfo.length; i++) {
|
||||
// Create our object stores.
|
||||
let info = objectStoreInfo[i];
|
||||
|
||||
ok(true, "1");
|
||||
request = indexedDB.open(name, i + 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
ok(true, "2");
|
||||
let objectStore = info.hasOwnProperty("options") ?
|
||||
db.createObjectStore(info.name, info.options) :
|
||||
db.createObjectStore(info.name);
|
||||
|
||||
// Create the indexes on 'data' on the object store.
|
||||
let index = objectStore.createIndex("data_index", "data",
|
||||
{ unique: false });
|
||||
let uniqueIndex = objectStore.createIndex("unique_data_index", "data",
|
||||
{ unique: true });
|
||||
// Populate the object store with one entry of data.
|
||||
request = info.hasOwnProperty("key") ?
|
||||
objectStore.add(info.entry, info.key) :
|
||||
objectStore.add(info.entry);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
ok(true, "3");
|
||||
|
||||
// Use a cursor to update 'data' to END_DATA.
|
||||
request = objectStore.openCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
ok(true, "4");
|
||||
|
||||
let cursor = request.result;
|
||||
let obj = cursor.value;
|
||||
obj.data = END_DATA;
|
||||
request = cursor.update(obj);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
ok(true, "5");
|
||||
|
||||
// Check both indexes to make sure that they were updated.
|
||||
request = index.get(END_DATA);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
ok(true, "6");
|
||||
ok(obj.data, event.target.result.data,
|
||||
"Non-unique index was properly updated.");
|
||||
|
||||
request = uniqueIndex.get(END_DATA);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(true, "7");
|
||||
ok(obj.data, event.target.result.data,
|
||||
"Unique index was properly updated.");
|
||||
|
||||
// Wait for success
|
||||
yield undefined;
|
||||
|
||||
db.close();
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
383
dom/indexedDB/test/unit/test_cursors.js
Normal file
383
dom/indexedDB/test/unit/test_cursors.js
Normal file
|
|
@ -0,0 +1,383 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const keys = [1, -1, 0, 10, 2000, "q", "z", "two", "b", "a"];
|
||||
const sortedKeys = [-1, 0, 1, 10, 2000, "a", "b", "q", "two", "z"];
|
||||
|
||||
is(keys.length, sortedKeys.length, "Good key setup");
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
let objectStore = db.createObjectStore("autoIncrement",
|
||||
{ autoIncrement: true });
|
||||
|
||||
request = objectStore.openCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
ok(!event.target.result, "No results");
|
||||
testGenerator.next();
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
objectStore = db.createObjectStore("autoIncrementKeyPath",
|
||||
{ keyPath: "foo",
|
||||
autoIncrement: true });
|
||||
|
||||
request = objectStore.openCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
ok(!event.target.result, "No results");
|
||||
testGenerator.next();
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
objectStore = db.createObjectStore("keyPath", { keyPath: "foo" });
|
||||
|
||||
request = objectStore.openCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
ok(!event.target.result, "No results");
|
||||
testGenerator.next();
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
objectStore = db.createObjectStore("foo");
|
||||
|
||||
request = objectStore.openCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
ok(!event.target.result, "No results");
|
||||
testGenerator.next();
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
let keyIndex = 0;
|
||||
|
||||
for (let i in keys) {
|
||||
request = objectStore.add("foo", keys[i]);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
if (++keyIndex == keys.length) {
|
||||
testGenerator.next();
|
||||
}
|
||||
};
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
keyIndex = 0;
|
||||
|
||||
request = objectStore.openCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, sortedKeys[keyIndex], "Correct key");
|
||||
is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
|
||||
is(cursor.value, "foo", "Correct value");
|
||||
|
||||
cursor.continue();
|
||||
|
||||
try {
|
||||
cursor.continue();
|
||||
ok(false, "continue twice should throw");
|
||||
}
|
||||
catch (e) {
|
||||
ok(e instanceof DOMException, "got a database exception");
|
||||
is(e.name, "InvalidStateError", "correct error");
|
||||
is(e.code, DOMException.INVALID_STATE_ERR, "correct code");
|
||||
}
|
||||
|
||||
is(cursor.key, sortedKeys[keyIndex], "Correct key");
|
||||
is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
|
||||
is(cursor.value, "foo", "Correct value");
|
||||
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
is(keyIndex, keys.length, "Saw all added items");
|
||||
|
||||
keyIndex = 4;
|
||||
|
||||
let range = IDBKeyRange.bound(2000, "q");
|
||||
request = objectStore.openCursor(range);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, sortedKeys[keyIndex], "Correct key");
|
||||
is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
|
||||
is(cursor.value, "foo", "Correct value");
|
||||
|
||||
cursor.continue();
|
||||
|
||||
is(cursor.key, sortedKeys[keyIndex], "Correct key");
|
||||
is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
|
||||
is(cursor.value, "foo", "Correct value");
|
||||
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
is(keyIndex, 8, "Saw all the expected keys");
|
||||
|
||||
keyIndex = 0;
|
||||
|
||||
request = objectStore.openCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, sortedKeys[keyIndex], "Correct key");
|
||||
is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
|
||||
is(cursor.value, "foo", "Correct value");
|
||||
|
||||
if (keyIndex) {
|
||||
cursor.continue();
|
||||
}
|
||||
else {
|
||||
cursor.continue("b");
|
||||
}
|
||||
|
||||
is(cursor.key, sortedKeys[keyIndex], "Correct key");
|
||||
is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
|
||||
is(cursor.value, "foo", "Correct value");
|
||||
|
||||
keyIndex += keyIndex ? 1: 6;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
is(keyIndex, keys.length, "Saw all the expected keys");
|
||||
|
||||
keyIndex = 0;
|
||||
|
||||
request = objectStore.openCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, sortedKeys[keyIndex], "Correct key");
|
||||
is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
|
||||
is(cursor.value, "foo", "Correct value");
|
||||
|
||||
if (keyIndex) {
|
||||
cursor.continue();
|
||||
}
|
||||
else {
|
||||
cursor.continue(10);
|
||||
}
|
||||
|
||||
is(cursor.key, sortedKeys[keyIndex], "Correct key");
|
||||
is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
|
||||
is(cursor.value, "foo", "Correct value");
|
||||
|
||||
keyIndex += keyIndex ? 1: 3;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
is(keyIndex, keys.length, "Saw all the expected keys");
|
||||
|
||||
keyIndex = 0;
|
||||
|
||||
request = objectStore.openCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, sortedKeys[keyIndex], "Correct key");
|
||||
is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
|
||||
is(cursor.value, "foo", "Correct value");
|
||||
|
||||
if (keyIndex) {
|
||||
cursor.continue();
|
||||
}
|
||||
else {
|
||||
cursor.continue("c");
|
||||
}
|
||||
|
||||
is(cursor.key, sortedKeys[keyIndex], "Correct key");
|
||||
is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
|
||||
is(cursor.value, "foo", "Correct value");
|
||||
|
||||
keyIndex += keyIndex ? 1 : 7;
|
||||
}
|
||||
else {
|
||||
ok(cursor === null, "The request result should be null.");
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
is(keyIndex, keys.length, "Saw all the expected keys");
|
||||
|
||||
keyIndex = 0;
|
||||
|
||||
request = objectStore.openCursor();
|
||||
request.onerror = errorHandler;
|
||||
let storedCursor = null;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
storedCursor = cursor;
|
||||
|
||||
is(cursor.key, sortedKeys[keyIndex], "Correct key");
|
||||
is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
|
||||
is(cursor.value, "foo", "Correct value");
|
||||
|
||||
if (keyIndex == 4) {
|
||||
request = cursor.update("bar");
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
keyIndex++;
|
||||
cursor.continue();
|
||||
};
|
||||
}
|
||||
else {
|
||||
keyIndex++;
|
||||
cursor.continue();
|
||||
}
|
||||
}
|
||||
else {
|
||||
ok(cursor === null, "The request result should be null.");
|
||||
ok(storedCursor.value === undefined, "The cursor's value should be undefined.");
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
is(keyIndex, keys.length, "Saw all the expected keys");
|
||||
|
||||
request = objectStore.get(sortedKeys[4]);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, "bar", "Update succeeded");
|
||||
|
||||
request = objectStore.put("foo", sortedKeys[4]);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
keyIndex = 0;
|
||||
|
||||
let gotRemoveEvent = false;
|
||||
let retval = false;
|
||||
|
||||
request = objectStore.openCursor(null, "next");
|
||||
request.onerror = errorHandler;
|
||||
storedCursor = null;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
storedCursor = cursor;
|
||||
|
||||
is(cursor.key, sortedKeys[keyIndex], "Correct key");
|
||||
is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
|
||||
is(cursor.value, "foo", "Correct value");
|
||||
|
||||
if (keyIndex == 4) {
|
||||
request = cursor.delete();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
ok(event.target.result === undefined, "Should be undefined");
|
||||
is(keyIndex, 5, "Got result of remove before next continue");
|
||||
gotRemoveEvent = true;
|
||||
};
|
||||
}
|
||||
|
||||
keyIndex++;
|
||||
cursor.continue();
|
||||
}
|
||||
else {
|
||||
ok(cursor === null, "The request result should be null.");
|
||||
ok(storedCursor.value === undefined, "The cursor's value should be undefined.");
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
is(keyIndex, keys.length, "Saw all the expected keys");
|
||||
is(gotRemoveEvent, true, "Saw the remove event");
|
||||
|
||||
request = objectStore.get(sortedKeys[4]);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, undefined, "Entry was deleted");
|
||||
|
||||
request = objectStore.add("foo", sortedKeys[4]);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
keyIndex = sortedKeys.length - 1;
|
||||
|
||||
request = objectStore.openCursor(null, "prev");
|
||||
request.onerror = errorHandler;
|
||||
storedCursor = null;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
storedCursor = cursor;
|
||||
|
||||
is(cursor.key, sortedKeys[keyIndex], "Correct key");
|
||||
is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
|
||||
is(cursor.value, "foo", "Correct value");
|
||||
|
||||
cursor.continue();
|
||||
|
||||
is(cursor.key, sortedKeys[keyIndex], "Correct key");
|
||||
is(cursor.primaryKey, sortedKeys[keyIndex], "Correct primary key");
|
||||
is(cursor.value, "foo", "Correct value");
|
||||
|
||||
keyIndex--;
|
||||
}
|
||||
else {
|
||||
ok(cursor === null, "The request result should be null.");
|
||||
ok(storedCursor.value === undefined, "The cursor's value should be undefined.");
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
is(keyIndex, -1, "Saw all added items");
|
||||
|
||||
// Wait for success
|
||||
yield undefined;
|
||||
|
||||
db.close();
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname :
|
||||
"test_database_close_without_onclose.js";
|
||||
|
||||
const checkpointSleepTimeSec = 10;
|
||||
|
||||
let openRequest = indexedDB.open(name, 1);
|
||||
openRequest.onerror = errorHandler;
|
||||
openRequest.onsuccess = unexpectedSuccessHandler;
|
||||
openRequest.onupgradeneeded = grabEventAndContinueHandler;
|
||||
|
||||
ok(openRequest instanceof IDBOpenDBRequest, "Expect an IDBOpenDBRequest");
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Expect an upgradeneeded event");
|
||||
ok(event instanceof IDBVersionChangeEvent, "Expect a versionchange event");
|
||||
|
||||
let db = event.target.result;
|
||||
db.createObjectStore("store");
|
||||
|
||||
openRequest.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Expect a success event");
|
||||
is(event.target, openRequest, "Event has right target");
|
||||
ok(event.target.result instanceof IDBDatabase, "Result should be a database");
|
||||
is(db.objectStoreNames.length, 1, "Expect an objectStore here");
|
||||
|
||||
db.onclose = errorHandler;
|
||||
|
||||
db.close();
|
||||
setTimeout(continueToNextStepSync, checkpointSleepTimeSec * 1000);
|
||||
yield undefined;
|
||||
|
||||
ok(true, "The close event should not be fired after closed normally!");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
245
dom/indexedDB/test/unit/test_database_onclose.js
Normal file
245
dom/indexedDB/test/unit/test_database_onclose.js
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
function testInvalidStateError(aDb, aTxn) {
|
||||
try {
|
||||
info("The db shall become invalid after closed.");
|
||||
aDb.transaction("store");
|
||||
ok(false, "InvalidStateError shall be thrown.");
|
||||
} catch (e) {
|
||||
ok(e instanceof DOMException, "got a database exception");
|
||||
is(e.name, "InvalidStateError", "correct error");
|
||||
}
|
||||
|
||||
try {
|
||||
info("The txn shall become invalid after closed.");
|
||||
aTxn.objectStore("store");
|
||||
ok(false, "InvalidStateError shall be thrown.");
|
||||
} catch (e) {
|
||||
ok(e instanceof DOMException, "got a database exception");
|
||||
is(e.name, "InvalidStateError", "correct error");
|
||||
}
|
||||
}
|
||||
|
||||
const name = this.window ? window.location.pathname :
|
||||
"test_database_onclose.js";
|
||||
|
||||
info("#1: Verifying IDBDatabase.onclose after cleared by the agent.");
|
||||
let openRequest = indexedDB.open(name, 1);
|
||||
openRequest.onerror = errorHandler;
|
||||
openRequest.onsuccess = unexpectedSuccessHandler;
|
||||
openRequest.onupgradeneeded = grabEventAndContinueHandler;
|
||||
|
||||
ok(openRequest instanceof IDBOpenDBRequest, "Expect an IDBOpenDBRequest");
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Expect an upgradeneeded event");
|
||||
ok(event instanceof IDBVersionChangeEvent, "Expect a versionchange event");
|
||||
|
||||
let db = event.target.result;
|
||||
db.createObjectStore("store");
|
||||
|
||||
openRequest.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Expect a success event");
|
||||
is(event.target, openRequest, "Event has right target");
|
||||
ok(event.target.result instanceof IDBDatabase, "Result should be a database");
|
||||
is(db.objectStoreNames.length, 1, "Expect an objectStore here");
|
||||
|
||||
let txn = db.transaction("store", "readwrite");
|
||||
let objectStore = txn.objectStore("store");
|
||||
|
||||
clearAllDatabases(continueToNextStep);
|
||||
|
||||
db.onclose = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
is(event.type, "close", "Expect a close event");
|
||||
is(event.target, db, "Correct target");
|
||||
|
||||
info("Wait for callback of clearAllDatabases().");
|
||||
yield undefined;
|
||||
|
||||
testInvalidStateError(db, txn);
|
||||
|
||||
info("#2: Verifying IDBDatabase.onclose && IDBTransaction.onerror " +
|
||||
"in *write* operation after cleared by the agent.");
|
||||
openRequest = indexedDB.open(name, 1);
|
||||
openRequest.onerror = errorHandler;
|
||||
openRequest.onsuccess = unexpectedSuccessHandler;
|
||||
openRequest.onupgradeneeded = grabEventAndContinueHandler;
|
||||
|
||||
ok(openRequest instanceof IDBOpenDBRequest, "Expect an IDBOpenDBRequest");
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Expect an upgradeneeded event");
|
||||
ok(event instanceof IDBVersionChangeEvent, "Expect a versionchange event");
|
||||
|
||||
db = event.target.result;
|
||||
db.createObjectStore("store");
|
||||
|
||||
openRequest.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Expect a success event");
|
||||
is(event.target, openRequest, "Event has right target");
|
||||
ok(event.target.result instanceof IDBDatabase, "Result should be a database");
|
||||
is(db.objectStoreNames.length, 1, "Expect an objectStore here");
|
||||
|
||||
txn = db.transaction("store", "readwrite");
|
||||
objectStore = txn.objectStore("store");
|
||||
|
||||
let objectId = 0;
|
||||
while(true) {
|
||||
let addRequest = objectStore.add({foo: "foo"}, objectId);
|
||||
addRequest.onerror = function(event) {
|
||||
info("addRequest.onerror, objectId: " + objectId);
|
||||
txn.onerror = grabEventAndContinueHandler;
|
||||
testGenerator.send(true);
|
||||
}
|
||||
addRequest.onsuccess = function() {
|
||||
testGenerator.send(false);
|
||||
}
|
||||
|
||||
if (objectId == 0) {
|
||||
clearAllDatabases(() => {
|
||||
info("clearAllDatabases is done.");
|
||||
continueToNextStep();
|
||||
});
|
||||
}
|
||||
|
||||
objectId++;
|
||||
|
||||
let aborted = yield undefined;
|
||||
if (aborted) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event = yield undefined;
|
||||
is(event.type, "error", "Got an error event");
|
||||
is(event.target.error.name, "AbortError", "Expected AbortError was thrown.");
|
||||
event.preventDefault();
|
||||
|
||||
txn.onabort = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
is(event.type, "abort", "Got an abort event");
|
||||
is(event.target.error.name, "AbortError", "Expected AbortError was thrown.");
|
||||
|
||||
db.onclose = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
is(event.type, "close", "Expect a close event");
|
||||
is(event.target, db, "Correct target");
|
||||
testInvalidStateError(db, txn);
|
||||
|
||||
info("Wait for the callback of clearAllDatabases().");
|
||||
yield undefined;
|
||||
|
||||
info("#3: Verifying IDBDatabase.onclose && IDBTransaction.onerror " +
|
||||
"in *read* operation after cleared by the agent.");
|
||||
openRequest = indexedDB.open(name, 1);
|
||||
openRequest.onerror = errorHandler;
|
||||
openRequest.onsuccess = unexpectedSuccessHandler;
|
||||
openRequest.onupgradeneeded = grabEventAndContinueHandler;
|
||||
|
||||
ok(openRequest instanceof IDBOpenDBRequest, "Expect an IDBOpenDBRequest");
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Expect an upgradeneeded event");
|
||||
ok(event instanceof IDBVersionChangeEvent, "Expect a versionchange event");
|
||||
|
||||
db = event.target.result;
|
||||
objectStore =
|
||||
db.createObjectStore("store", { keyPath: "id", autoIncrement: true });
|
||||
// The number of read records varies between 1~2000 before the db is cleared
|
||||
// during testing.
|
||||
let numberOfObjects = 3000;
|
||||
objectId = 0;
|
||||
while(true) {
|
||||
let addRequest = objectStore.add({foo: "foo"});
|
||||
addRequest.onsuccess = function() {
|
||||
objectId++;
|
||||
testGenerator.send(objectId == numberOfObjects);
|
||||
}
|
||||
addRequest.onerror = errorHandler;
|
||||
|
||||
let done = yield undefined;
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
openRequest.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Expect a success event");
|
||||
is(event.target, openRequest, "Event has right target");
|
||||
ok(event.target.result instanceof IDBDatabase, "Result should be a database");
|
||||
is(db.objectStoreNames.length, 1, "Expect an objectStore here");
|
||||
|
||||
txn = db.transaction("store");
|
||||
objectStore = txn.objectStore("store");
|
||||
|
||||
let numberOfReadObjects = 0;
|
||||
let readRequest = objectStore.openCursor();
|
||||
readRequest.onerror = function(event) {
|
||||
info("readRequest.onerror, numberOfReadObjects: " + numberOfReadObjects);
|
||||
testGenerator.send(true);
|
||||
}
|
||||
readRequest.onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
numberOfReadObjects++;
|
||||
event.target.result.continue();
|
||||
} else {
|
||||
info("Cursor is invalid, numberOfReadObjects: " + numberOfReadObjects);
|
||||
todo(false, "All records are iterated before database is cleared!");
|
||||
testGenerator.send(false);
|
||||
}
|
||||
}
|
||||
|
||||
clearAllDatabases(() => {
|
||||
info("clearAllDatabases is done.");
|
||||
continueToNextStep();
|
||||
});
|
||||
|
||||
readRequestError = yield undefined;
|
||||
if (readRequestError) {
|
||||
txn.onerror = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
is(event.type, "error", "Got an error event");
|
||||
is(event.target.error.name, "AbortError", "Expected AbortError was thrown.");
|
||||
event.preventDefault();
|
||||
|
||||
txn.onabort = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
is(event.type, "abort", "Got an abort event");
|
||||
is(event.target.error.name, "AbortError", "Expected AbortError was thrown.");
|
||||
|
||||
db.onclose = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
is(event.type, "close", "Expect a close event");
|
||||
is(event.target, db, "Correct target");
|
||||
|
||||
testInvalidStateError(db, txn);
|
||||
}
|
||||
|
||||
info("Wait for the callback of clearAllDatabases().");
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
160
dom/indexedDB/test/unit/test_defaultStorageUpgrade.js
Normal file
160
dom/indexedDB/test/unit/test_defaultStorageUpgrade.js
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const openParams = [
|
||||
// This one lives in storage/default/http+++localhost
|
||||
{ url: "http://localhost", dbName: "dbA", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/default/http+++www.mozilla.org
|
||||
{ url: "http://www.mozilla.org", dbName: "dbB", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/default/http+++www.mozilla.org+8080
|
||||
{ url: "http://www.mozilla.org:8080", dbName: "dbC", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/default/https+++www.mozilla.org
|
||||
{ url: "https://www.mozilla.org", dbName: "dbD", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/default/https+++www.mozilla.org+8080
|
||||
{ url: "https://www.mozilla.org:8080", dbName: "dbE", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/permanent/indexeddb+++fx-devtools
|
||||
{ url: "indexeddb://fx-devtools", dbName: "dbF",
|
||||
dbOptions: { version: 1, storage: "persistent" } },
|
||||
|
||||
// This one lives in storage/permanent/moz-safe-about+home
|
||||
{ url: "moz-safe-about:home", dbName: "dbG",
|
||||
dbOptions: { version: 1, storage: "persistent" } },
|
||||
|
||||
// This one lives in storage/default/file++++Users+joe+
|
||||
{ url: "file:///Users/joe/", dbName: "dbH", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/default/file++++Users+joe+index.html
|
||||
{ url: "file:///Users/joe/index.html", dbName: "dbI", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/default/file++++c++Users+joe+
|
||||
{ url: "file:///c:/Users/joe/", dbName: "dbJ", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/default/file++++c++Users+joe+index.html
|
||||
{ url: "file:///c:/Users/joe/index.html", dbName: "dbK", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/permanent/chrome
|
||||
{ dbName: "dbL", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/default/1007+t+https+++developer.cdn.mozilla.net
|
||||
{ appId: 1007, inIsolatedMozBrowser: true, url: "https://developer.cdn.mozilla.net",
|
||||
dbName: "dbN", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/default/http+++127.0.0.1
|
||||
{ url: "http://127.0.0.1", dbName: "dbO", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/default/file++++
|
||||
{ url: "file:///", dbName: "dbP", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/default/file++++c++
|
||||
{ url: "file:///c:/", dbName: "dbQ", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/default/file++++Users+joe+c+++index.html
|
||||
{ url: "file:///Users/joe/c++/index.html", dbName: "dbR", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/default/file++++Users+joe+c+++index.html
|
||||
{ url: "file:///Users/joe/c///index.html", dbName: "dbR", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/default/file++++++index.html
|
||||
{ url: "file:///+/index.html", dbName: "dbS", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/default/file++++++index.html
|
||||
{ url: "file://///index.html", dbName: "dbS", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/permanent/resource+++fx-share-addon-at-mozilla-dot-org-fx-share-addon-data
|
||||
{ url: "resource://fx-share-addon-at-mozilla-dot-org-fx-share-addon-data",
|
||||
dbName: "dbU", dbOptions: { version: 1, storage: "persistent" } },
|
||||
|
||||
// This one lives in storage/temporary/http+++localhost+81
|
||||
// The .metadata file was intentionally removed for this origin directory
|
||||
// to test restoring during upgrade.
|
||||
{ url: "http://localhost:81", dbName: "dbV",
|
||||
dbOptions: { version: 1, storage: "temporary" } },
|
||||
|
||||
// This one lives in storage/temporary/http+++localhost+82
|
||||
// The .metadata file was intentionally truncated for this origin directory
|
||||
// to test restoring during upgrade.
|
||||
{ url: "http://localhost:82", dbName: "dbW",
|
||||
dbOptions: { version: 1, storage: "temporary" } },
|
||||
|
||||
// This one lives in storage/temporary/1007+t+https+++developer.cdn.mozilla.net
|
||||
{ appId: 1007, inIsolatedMozBrowser: true, url: "https://developer.cdn.mozilla.net",
|
||||
dbName: "dbY", dbOptions: { version: 1, storage: "temporary" } },
|
||||
|
||||
// This one lives in storage/temporary/http+++localhost
|
||||
{ url: "http://localhost", dbName: "dbZ",
|
||||
dbOptions: { version: 1, storage: "temporary" } }
|
||||
];
|
||||
|
||||
let ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(SpecialPowers.Ci.nsIIOService);
|
||||
|
||||
let ssm = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(SpecialPowers.Ci.nsIScriptSecurityManager);
|
||||
|
||||
function openDatabase(params) {
|
||||
let request;
|
||||
if ("url" in params) {
|
||||
let uri = ios.newURI(params.url, null, null);
|
||||
let principal =
|
||||
ssm.createCodebasePrincipal(uri,
|
||||
{appId: params.appId || ssm.NO_APPID,
|
||||
inIsolatedMozBrowser: params.inIsolatedMozBrowser});
|
||||
if ("dbVersion" in params) {
|
||||
request = indexedDB.openForPrincipal(principal, params.dbName,
|
||||
params.dbVersion);
|
||||
} else {
|
||||
request = indexedDB.openForPrincipal(principal, params.dbName,
|
||||
params.dbOptions);
|
||||
}
|
||||
} else {
|
||||
if ("dbVersion" in params) {
|
||||
request = indexedDB.open(params.dbName, params.dbVersion);
|
||||
} else {
|
||||
request = indexedDB.open(params.dbName, params.dbOptions);
|
||||
}
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
clearAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
installPackagedProfile("defaultStorageUpgrade_profile");
|
||||
|
||||
for (let params of openParams) {
|
||||
let request = openDatabase(params);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Correct event type");
|
||||
}
|
||||
|
||||
resetAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
for (let params of openParams) {
|
||||
let request = openDatabase(params);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Correct event type");
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
106
dom/indexedDB/test/unit/test_deleteDatabase.js
Normal file
106
dom/indexedDB/test/unit/test_deleteDatabase.js
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
|
||||
ok(indexedDB.deleteDatabase, "deleteDatabase function should exist!");
|
||||
|
||||
let request = indexedDB.open(name, 10);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
|
||||
ok(request instanceof IDBOpenDBRequest, "Expect an IDBOpenDBRequest");
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Expect an upgradeneeded event");
|
||||
ok(event instanceof IDBVersionChangeEvent, "Expect a versionchange event");
|
||||
|
||||
let db = event.target.result;
|
||||
db.createObjectStore("stuff");
|
||||
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Expect a success event");
|
||||
is(event.target, request, "Event has right target");
|
||||
ok(event.target.result instanceof IDBDatabase, "Result should be a database");
|
||||
is(db.objectStoreNames.length, 1, "Expect an objectStore here");
|
||||
|
||||
request = indexedDB.open(name, 10);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
is(event.type, "success", "Expect a success event");
|
||||
is(event.target, request, "Event has right target");
|
||||
ok(event.target.result instanceof IDBDatabase, "Result should be a database");
|
||||
let db2 = event.target.result;
|
||||
is(db2.objectStoreNames.length, 1, "Expect an objectStore here");
|
||||
|
||||
var onversionchangecalled = false;
|
||||
|
||||
function closeDBs(event) {
|
||||
onversionchangecalled = true;
|
||||
ok(event instanceof IDBVersionChangeEvent, "expect a versionchange event");
|
||||
is(event.oldVersion, 10, "oldVersion should be 10");
|
||||
ok(event.newVersion === null, "newVersion should be null");
|
||||
ok(!(event.newVersion === undefined), "newVersion should be null");
|
||||
ok(!(event.newVersion === 0), "newVersion should be null");
|
||||
db.close();
|
||||
db2.close();
|
||||
db.onversionchange = unexpectedSuccessHandler;
|
||||
db2.onversionchange = unexpectedSuccessHandler;
|
||||
};
|
||||
|
||||
// The IDB spec doesn't guarantee the order that onversionchange will fire
|
||||
// on the dbs.
|
||||
db.onversionchange = closeDBs;
|
||||
db2.onversionchange = closeDBs;
|
||||
|
||||
request = indexedDB.deleteDatabase(name);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
ok(request instanceof IDBOpenDBRequest, "Expect an IDBOpenDBRequest");
|
||||
|
||||
event = yield undefined;
|
||||
ok(onversionchangecalled, "Expected versionchange events");
|
||||
is(event.type, "success", "expect a success event");
|
||||
is(event.target, request, "event has right target");
|
||||
ok(event.target.result === undefined, "event should have no result");
|
||||
|
||||
request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
is(event.target.result.version, 1, "DB has proper version");
|
||||
is(event.target.result.objectStoreNames.length, 0, "DB should have no object stores");
|
||||
|
||||
|
||||
request = indexedDB.deleteDatabase("thisDatabaseHadBetterNotExist");
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
ok(true, "deleteDatabase on a non-existent database succeeded");
|
||||
|
||||
request = indexedDB.open("thisDatabaseHadBetterNotExist");
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
ok(true, "after deleting a non-existent database, open should work");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
62
dom/indexedDB/test/unit/test_deleteDatabase_interactions.js
Normal file
62
dom/indexedDB/test/unit/test_deleteDatabase_interactions.js
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
|
||||
let request = indexedDB.open(name, 10);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
|
||||
ok(request instanceof IDBOpenDBRequest, "Expect an IDBOpenDBRequest");
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Expect an upgradeneeded event");
|
||||
ok(event instanceof IDBVersionChangeEvent, "Expect a versionchange event");
|
||||
|
||||
let db = event.target.result;
|
||||
db.createObjectStore("stuff");
|
||||
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Expect a success event");
|
||||
is(event.target, request, "Event has right target");
|
||||
ok(event.target.result instanceof IDBDatabase, "Result should be a database");
|
||||
is(db.objectStoreNames.length, 1, "Expect an objectStore here");
|
||||
|
||||
db.close();
|
||||
|
||||
request = indexedDB.deleteDatabase(name);
|
||||
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
ok(request instanceof IDBOpenDBRequest, "Expect an IDBOpenDBRequest");
|
||||
|
||||
let openRequest = indexedDB.open(name, 1);
|
||||
openRequest.onerror = errorHandler;
|
||||
openRequest.onsuccess = unexpectedSuccessHandler;
|
||||
|
||||
event = yield undefined;
|
||||
is(event.type, "success", "expect a success event");
|
||||
is(event.target, request, "event has right target");
|
||||
is(event.target.result, undefined, "event should have no result");
|
||||
|
||||
openRequest.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
is(event.target.result.version, 1, "DB has proper version");
|
||||
is(event.target.result.objectStoreNames.length, 0, "DB should have no object stores");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
83
dom/indexedDB/test/unit/test_deleteDatabase_onblocked.js
Normal file
83
dom/indexedDB/test/unit/test_deleteDatabase_onblocked.js
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const dbVersion = 10;
|
||||
|
||||
let openRequest = indexedDB.open(name, dbVersion);
|
||||
openRequest.onerror = errorHandler;
|
||||
openRequest.onblocked = errorHandler;
|
||||
openRequest.onsuccess = unexpectedSuccessHandler;
|
||||
openRequest.onupgradeneeded = grabEventAndContinueHandler;
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Expect an upgradeneeded event");
|
||||
ok(event instanceof IDBVersionChangeEvent, "Expect a versionchange event");
|
||||
|
||||
let db = event.target.result;
|
||||
db.onversionchange = errorHandler;
|
||||
db.createObjectStore("stuff");
|
||||
|
||||
openRequest.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Expect a success event");
|
||||
is(event.target, openRequest, "Event has right target");
|
||||
ok(event.target.result instanceof IDBDatabase, "Result should be a database");
|
||||
is(db.objectStoreNames.length, 1, "Expect an objectStore here");
|
||||
|
||||
db.onversionchange = grabEventAndContinueHandler;
|
||||
let deletingRequest = indexedDB.deleteDatabase(name);
|
||||
deletingRequest.onerror = errorHandler;
|
||||
deletingRequest.onsuccess = errorHandler;
|
||||
deletingRequest.onblocked = errorHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "versionchange", "Expect an versionchange event");
|
||||
is(event.target, db, "Event has right target");
|
||||
ok(event instanceof IDBVersionChangeEvent, "Expect a versionchange event");
|
||||
is(event.oldVersion, dbVersion, "Correct old version");
|
||||
is(event.newVersion, null, "Correct new version");
|
||||
|
||||
deletingRequest.onblocked = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "blocked", "Expect an blocked event");
|
||||
is(event.target, deletingRequest, "Event has right target");
|
||||
ok(event instanceof IDBVersionChangeEvent, "Expect a versionchange event");
|
||||
is(event.oldVersion, dbVersion, "Correct old version");
|
||||
is(event.newVersion, null, "Correct new version");
|
||||
|
||||
deletingRequest.onsuccess = grabEventAndContinueHandler;
|
||||
db.close();
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "expect a success event");
|
||||
is(event.target, deletingRequest, "event has right target");
|
||||
is(event.target.result, undefined, "event should have no result");
|
||||
|
||||
openRequest = indexedDB.open(name, 1);
|
||||
openRequest.onerror = errorHandler;
|
||||
openRequest.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
db = event.target.result;
|
||||
is(db.version, 1, "DB has proper version");
|
||||
is(db.objectStoreNames.length, 0, "DB should have no object stores");
|
||||
|
||||
db.close();
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const dbVersion = 10;
|
||||
|
||||
let openRequest = indexedDB.open(name, dbVersion);
|
||||
openRequest.onerror = errorHandler;
|
||||
openRequest.onblocked = errorHandler;
|
||||
openRequest.onsuccess = unexpectedSuccessHandler;
|
||||
openRequest.onupgradeneeded = grabEventAndContinueHandler;
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Expect an upgradeneeded event");
|
||||
ok(event instanceof IDBVersionChangeEvent, "Expect a versionchange event");
|
||||
|
||||
let db = event.target.result;
|
||||
db.onversionchange = errorHandler;
|
||||
db.createObjectStore("stuff");
|
||||
|
||||
let deletingRequest = indexedDB.deleteDatabase(name);
|
||||
deletingRequest.onerror = errorHandler;
|
||||
deletingRequest.onsuccess = errorHandler;
|
||||
deletingRequest.onblocked = errorHandler;
|
||||
|
||||
openRequest.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Expect a success event");
|
||||
is(event.target, openRequest, "Event has right target");
|
||||
ok(event.target.result instanceof IDBDatabase, "Result should be a database");
|
||||
is(db.objectStoreNames.length, 1, "Expect an objectStore here");
|
||||
|
||||
db.onversionchange = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "versionchange", "Expect an versionchange event");
|
||||
is(event.target, db, "Event has right target");
|
||||
ok(event instanceof IDBVersionChangeEvent, "Expect a versionchange event");
|
||||
is(event.oldVersion, dbVersion, "Correct old version");
|
||||
is(event.newVersion, null, "Correct new version");
|
||||
|
||||
deletingRequest.onblocked = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "blocked", "Expect an blocked event");
|
||||
is(event.target, deletingRequest, "Event has right target");
|
||||
ok(event instanceof IDBVersionChangeEvent, "Expect a versionchange event");
|
||||
is(event.oldVersion, dbVersion, "Correct old version");
|
||||
is(event.newVersion, null, "Correct new version");
|
||||
|
||||
deletingRequest.onsuccess = grabEventAndContinueHandler;
|
||||
db.close();
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "expect a success event");
|
||||
is(event.target, deletingRequest, "event has right target");
|
||||
is(event.target.result, undefined, "event should have no result");
|
||||
|
||||
openRequest = indexedDB.open(name, 1);
|
||||
openRequest.onerror = errorHandler;
|
||||
openRequest.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
db = event.target.result;
|
||||
is(db.version, 1, "DB has proper version");
|
||||
is(db.objectStoreNames.length, 0, "DB should have no object stores");
|
||||
|
||||
db.close();
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
36
dom/indexedDB/test/unit/test_event_source.js
Normal file
36
dom/indexedDB/test/unit/test_event_source.js
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const objectStoreName = "Objects";
|
||||
|
||||
var request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
var event = yield undefined;
|
||||
|
||||
is(event.target.source, null, "correct event.target.source");
|
||||
|
||||
var db = event.target.result;
|
||||
var objectStore = db.createObjectStore(objectStoreName,
|
||||
{ autoIncrement: true });
|
||||
request = objectStore.add({});
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(event.target.source === objectStore, "correct event.source");
|
||||
|
||||
// Wait for success
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
75
dom/indexedDB/test/unit/test_file_copy_failure.js
Normal file
75
dom/indexedDB/test/unit/test_file_copy_failure.js
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = "test_file_copy_failure.js";
|
||||
const objectStoreName = "Blobs";
|
||||
const blob = getBlob(getView(1024));
|
||||
|
||||
info("Opening database");
|
||||
|
||||
let request = indexedDB.open(name);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = continueToNextStepSync;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
yield undefined;
|
||||
|
||||
// upgradeneeded
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = continueToNextStepSync;
|
||||
|
||||
info("Creating objectStore");
|
||||
|
||||
request.result.createObjectStore(objectStoreName);
|
||||
|
||||
yield undefined;
|
||||
|
||||
// success
|
||||
let db = request.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
info("Creating orphaned file");
|
||||
|
||||
let filesDir = getChromeFilesDir();
|
||||
|
||||
let journalFile = filesDir.clone();
|
||||
journalFile.append("journals");
|
||||
journalFile.append("1");
|
||||
|
||||
let exists = journalFile.exists();
|
||||
ok(!exists, "Journal file doesn't exist");
|
||||
|
||||
journalFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("0644", 8));
|
||||
|
||||
let file = filesDir.clone();
|
||||
file.append("1");
|
||||
|
||||
exists = file.exists();
|
||||
ok(!exists, "File doesn't exist");
|
||||
|
||||
file.create(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("0644", 8));
|
||||
|
||||
info("Storing blob");
|
||||
|
||||
let trans = db.transaction(objectStoreName, "readwrite");
|
||||
|
||||
request = trans.objectStore(objectStoreName).add(blob, 1);
|
||||
request.onsuccess = continueToNextStepSync;
|
||||
|
||||
yield undefined;
|
||||
|
||||
trans.oncomplete = continueToNextStepSync;
|
||||
|
||||
yield undefined;
|
||||
|
||||
exists = journalFile.exists();
|
||||
ok(!exists, "Journal file doesn't exist");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
98
dom/indexedDB/test/unit/test_filehandle_append_read_data.js
Normal file
98
dom/indexedDB/test/unit/test_filehandle_append_read_data.js
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var disableWorkerTest = "FileHandle doesn't work in workers yet";
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
|
||||
var testString = "Lorem ipsum his ponderum delicatissimi ne, at noster dolores urbanitas pro, cibo elaboraret no his. Ea dicunt maiorum usu. Ad appareat facilisis mediocritatem eos. Tale graeci mentitum in eos, hinc insolens at nam. Graecis nominavi aliquyam eu vix. Id solet assentior sadipscing pro. Et per atqui graecis, usu quot viris repudiandae ei, mollis evertitur an nam. At nam dolor ignota, liber labore omnesque ea mei, has movet voluptaria in. Vel an impetus omittantur. Vim movet option salutandi ex, ne mei ignota corrumpit. Mucius comprehensam id per. Est ea putant maiestatis.";
|
||||
for (let i = 0; i < 5; i++) {
|
||||
testString += testString;
|
||||
}
|
||||
|
||||
var testBuffer = getRandomBuffer(100000);
|
||||
|
||||
var testBlob = new Blob([testBuffer], {type: "binary/random"});
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
request = db.createMutableFile("test.txt");
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
let mutableFile = event.target.result;
|
||||
mutableFile.onerror = errorHandler;
|
||||
|
||||
let location = 0;
|
||||
|
||||
let fileHandle = mutableFile.open("readwrite");
|
||||
is(fileHandle.location, location, "Correct location");
|
||||
|
||||
request = fileHandle.append(testString);
|
||||
ok(fileHandle.location === null, "Correct location");
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
fileHandle.location = 0;
|
||||
request = fileHandle.readAsText(testString.length);
|
||||
location += testString.length
|
||||
is(fileHandle.location, location, "Correct location");
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
let resultString = event.target.result;
|
||||
ok(resultString == testString, "Correct string data");
|
||||
|
||||
request = fileHandle.append(testBuffer);
|
||||
ok(fileHandle.location === null, "Correct location");
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
fileHandle.location = location;
|
||||
request = fileHandle.readAsArrayBuffer(testBuffer.byteLength);
|
||||
location += testBuffer.byteLength;
|
||||
is(fileHandle.location, location, "Correct location");
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
let resultBuffer = event.target.result;
|
||||
ok(compareBuffers(resultBuffer, testBuffer), "Correct array buffer data");
|
||||
|
||||
request = fileHandle.append(testBlob);
|
||||
ok(fileHandle.location === null, "Correct location");
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
fileHandle.location = location;
|
||||
request = fileHandle.readAsArrayBuffer(testBlob.size);
|
||||
location += testBlob.size;
|
||||
is(fileHandle.location, location, "Correct location");
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
resultBuffer = event.target.result;
|
||||
ok(compareBuffers(resultBuffer, testBuffer), "Correct blob data");
|
||||
|
||||
request = fileHandle.getMetadata({ size: true });
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
let result = event.target.result;
|
||||
is(result.size, location, "Correct size");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
195
dom/indexedDB/test/unit/test_getAll.js
Normal file
195
dom/indexedDB/test/unit/test_getAll.js
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
|
||||
const values = [ "a", "1", 1, "foo", 300, true, false, 4.5, null ];
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
||||
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
request = objectStore.mozGetAll();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 0, "No elements");
|
||||
|
||||
let addedCount = 0;
|
||||
|
||||
for (let i in values) {
|
||||
request = objectStore.add(values[i]);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
if (++addedCount == values.length) {
|
||||
executeSoon(function() { testGenerator.next(); });
|
||||
}
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
yield undefined;
|
||||
|
||||
request = db.transaction("foo").objectStore("foo").mozGetAll();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, values.length, "Same length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], values[i], "Same value");
|
||||
}
|
||||
|
||||
request = db.transaction("foo").objectStore("foo").mozGetAll(null, 5);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 5, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], values[i], "Same value");
|
||||
}
|
||||
|
||||
let keyRange = IDBKeyRange.bound(1, 9);
|
||||
|
||||
request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, values.length, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], values[i], "Same value");
|
||||
}
|
||||
|
||||
request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange, 0);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, values.length, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], values[i], "Same value");
|
||||
}
|
||||
|
||||
request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange, null);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, values.length, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], values[i], "Same value");
|
||||
}
|
||||
|
||||
request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange, undefined);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, values.length, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], values[i], "Same value");
|
||||
}
|
||||
|
||||
keyRange = IDBKeyRange.bound(4, 7);
|
||||
|
||||
request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 4, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], values[parseInt(i) + 3], "Same value");
|
||||
}
|
||||
|
||||
// Get should take a key range also but it doesn't return an array.
|
||||
request = db.transaction("foo").objectStore("foo").get(keyRange);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, false, "Not an array object");
|
||||
is(event.target.result, values[3], "Correct value");
|
||||
|
||||
request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange, 2);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], values[parseInt(i) + 3], "Same value");
|
||||
}
|
||||
|
||||
keyRange = IDBKeyRange.bound(4, 7);
|
||||
|
||||
request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange, 50);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 4, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], values[parseInt(i) + 3], "Same value");
|
||||
}
|
||||
|
||||
keyRange = IDBKeyRange.bound(4, 7);
|
||||
|
||||
request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange, 0);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 4, "Correct length");
|
||||
|
||||
keyRange = IDBKeyRange.bound(4, 7, true, true);
|
||||
|
||||
request = db.transaction("foo").objectStore("foo").mozGetAll(keyRange);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], values[parseInt(i) + 4], "Same value");
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
128
dom/indexedDB/test/unit/test_getUsage.js
Normal file
128
dom/indexedDB/test/unit/test_getUsage.js
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const origins = [
|
||||
{
|
||||
origin: "http://example.com",
|
||||
persisted: false,
|
||||
usage: 49152
|
||||
},
|
||||
|
||||
{
|
||||
origin: "http://localhost",
|
||||
persisted: false,
|
||||
usage: 147456
|
||||
},
|
||||
|
||||
{
|
||||
origin: "http://www.mozilla.org",
|
||||
persisted: false,
|
||||
usage: 98304
|
||||
}
|
||||
];
|
||||
|
||||
const allOrigins = [
|
||||
{
|
||||
origin: "chrome",
|
||||
persisted: false,
|
||||
usage: 147456
|
||||
},
|
||||
|
||||
{
|
||||
origin: "http://example.com",
|
||||
persisted: false,
|
||||
usage: 49152
|
||||
},
|
||||
|
||||
{
|
||||
origin: "http://localhost",
|
||||
persisted: false,
|
||||
usage: 147456
|
||||
},
|
||||
|
||||
{
|
||||
origin: "http://www.mozilla.org",
|
||||
persisted: false,
|
||||
usage: 98304
|
||||
}
|
||||
];
|
||||
|
||||
function verifyResult(result, origins) {
|
||||
ok(result instanceof Array, "Got an array object");
|
||||
ok(result.length == origins.length, "Correct number of elements");
|
||||
|
||||
info("Sorting elements");
|
||||
|
||||
result.sort(function(a, b) {
|
||||
let originA = a.origin
|
||||
let originB = b.origin
|
||||
|
||||
if (originA < originB) {
|
||||
return -1;
|
||||
}
|
||||
if (originA > originB) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
info("Verifying elements");
|
||||
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
let a = result[i];
|
||||
let b = origins[i];
|
||||
ok(a.origin == b.origin, "Origin equals");
|
||||
ok(a.persisted == b.persisted, "Persisted equals");
|
||||
ok(a.usage == b.usage, "Usage equals");
|
||||
}
|
||||
}
|
||||
|
||||
info("Clearing");
|
||||
|
||||
clearAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
info("Getting usage");
|
||||
|
||||
getUsage(grabResultAndContinueHandler, /* getAll */ true);
|
||||
let result = yield undefined;
|
||||
|
||||
info("Verifying result");
|
||||
|
||||
verifyResult(result, []);
|
||||
|
||||
info("Installing profile");
|
||||
|
||||
// The profile contains IndexedDB databases placed across the repositories.
|
||||
// The file create_db.js in the package was run locally, specifically it was
|
||||
// temporarily added to xpcshell.ini and then executed:
|
||||
// mach xpcshell-test --interactive dom/indexedDB/test/unit/create_db.js
|
||||
installPackagedProfile("getUsage_profile");
|
||||
|
||||
info("Getting usage");
|
||||
|
||||
getUsage(grabResultAndContinueHandler, /* getAll */ false);
|
||||
result = yield undefined;
|
||||
|
||||
info("Verifying result");
|
||||
|
||||
verifyResult(result, origins);
|
||||
|
||||
info("Getting usage");
|
||||
|
||||
getUsage(grabResultAndContinueHandler, /* getAll */ true);
|
||||
result = yield undefined;
|
||||
|
||||
info("Verifying result");
|
||||
|
||||
verifyResult(result, allOrigins);
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
19
dom/indexedDB/test/unit/test_globalObjects_ipc.js
Normal file
19
dom/indexedDB/test/unit/test_globalObjects_ipc.js
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
// Test for IDBKeyRange and indexedDB availability in ipcshell.
|
||||
run_test_in_child("./GlobalObjectsChild.js", function() {
|
||||
do_test_finished();
|
||||
continueToNextStep();
|
||||
});
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
60
dom/indexedDB/test/unit/test_globalObjects_other.js
Normal file
60
dom/indexedDB/test/unit/test_globalObjects_other.js
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
let ioService =
|
||||
Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||
|
||||
function getSpec(filename) {
|
||||
let file = do_get_file(filename);
|
||||
let uri = ioService.newFileURI(file);
|
||||
return uri.spec;
|
||||
}
|
||||
|
||||
// Test for IDBKeyRange and indexedDB availability in JS modules.
|
||||
Cu.import(getSpec("GlobalObjectsModule.jsm"));
|
||||
let test = new GlobalObjectsModule();
|
||||
test.ok = ok;
|
||||
test.finishTest = continueToNextStep;
|
||||
test.runTest();
|
||||
yield undefined;
|
||||
|
||||
// Test for IDBKeyRange and indexedDB availability in JS components.
|
||||
do_load_manifest("GlobalObjectsComponent.manifest");
|
||||
test = Cc["@mozilla.org/dom/indexeddb/GlobalObjectsComponent;1"].
|
||||
createInstance(Ci.nsISupports).wrappedJSObject;
|
||||
test.ok = ok;
|
||||
test.finishTest = continueToNextStep;
|
||||
test.runTest();
|
||||
yield undefined;
|
||||
|
||||
// Test for IDBKeyRange and indexedDB availability in JS sandboxes.
|
||||
let principal = Cc["@mozilla.org/systemprincipal;1"].
|
||||
createInstance(Ci.nsIPrincipal);
|
||||
let sandbox = new Cu.Sandbox(principal,
|
||||
{ wantGlobalProperties: ["indexedDB"] });
|
||||
sandbox.__SCRIPT_URI_SPEC__ = getSpec("GlobalObjectsSandbox.js");
|
||||
Cu.evalInSandbox(
|
||||
"Components.classes['@mozilla.org/moz/jssubscript-loader;1'] \
|
||||
.createInstance(Components.interfaces.mozIJSSubScriptLoader) \
|
||||
.loadSubScript(__SCRIPT_URI_SPEC__);", sandbox, "1.7");
|
||||
sandbox.ok = ok;
|
||||
sandbox.finishTest = continueToNextStep;
|
||||
Cu.evalInSandbox("runTest();", sandbox);
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
this.runTest = function() {
|
||||
do_get_profile();
|
||||
|
||||
do_test_pending();
|
||||
testGenerator.next();
|
||||
}
|
||||
26
dom/indexedDB/test/unit/test_globalObjects_xpc.js
Normal file
26
dom/indexedDB/test/unit/test_globalObjects_xpc.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = "Splendid Test";
|
||||
|
||||
// Test for IDBKeyRange and indexedDB availability in xpcshell.
|
||||
let keyRange = IDBKeyRange.only(42);
|
||||
ok(keyRange, "Got keyRange");
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
ok(db, "Got database");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
57
dom/indexedDB/test/unit/test_global_data.js
Normal file
57
dom/indexedDB/test/unit/test_global_data.js
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const objectStore = { name: "Objects",
|
||||
options: { keyPath: "id", autoIncrement: true } };
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db1 = event.target.result;
|
||||
|
||||
is(db1.objectStoreNames.length, 0, "No objectStores in db1");
|
||||
|
||||
db1.createObjectStore(objectStore.name, objectStore.options);
|
||||
|
||||
continueToNextStep();
|
||||
yield undefined;
|
||||
|
||||
request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
let db2 = event.target.result;
|
||||
|
||||
ok(db1 !== db2, "Databases are not the same object");
|
||||
|
||||
is(db1.objectStoreNames.length, 1, "1 objectStore in db1");
|
||||
is(db1.objectStoreNames.item(0), objectStore.name, "Correct name");
|
||||
|
||||
is(db2.objectStoreNames.length, 1, "1 objectStore in db2");
|
||||
is(db2.objectStoreNames.item(0), objectStore.name, "Correct name");
|
||||
|
||||
let objectStore1 = db1.transaction(objectStore.name)
|
||||
.objectStore(objectStore.name);
|
||||
is(objectStore1.name, objectStore.name, "Same name");
|
||||
is(objectStore1.keyPath, objectStore.options.keyPath, "Same keyPath");
|
||||
|
||||
let objectStore2 = db2.transaction(objectStore.name)
|
||||
.objectStore(objectStore.name);
|
||||
|
||||
ok(objectStore1 !== objectStore2, "Different objectStores");
|
||||
is(objectStore1.name, objectStore2.name, "Same name");
|
||||
is(objectStore1.keyPath, objectStore2.keyPath, "Same keyPath");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
68
dom/indexedDB/test/unit/test_idbSubdirUpgrade.js
Normal file
68
dom/indexedDB/test/unit/test_idbSubdirUpgrade.js
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const openParams = [
|
||||
// This one lives in storage/default/http+++www.mozilla.org
|
||||
{ url: "http://www.mozilla.org", dbName: "dbB", dbVersion: 1 },
|
||||
|
||||
// This one lives in storage/default/1007+t+https+++developer.cdn.mozilla.net
|
||||
{ appId: 1007, inIsolatedMozBrowser: true, url: "https://developer.cdn.mozilla.net",
|
||||
dbName: "dbN", dbVersion: 1 },
|
||||
];
|
||||
|
||||
let ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(SpecialPowers.Ci.nsIIOService);
|
||||
|
||||
let ssm = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(SpecialPowers.Ci.nsIScriptSecurityManager);
|
||||
|
||||
function openDatabase(params) {
|
||||
let uri = ios.newURI(params.url, null, null);
|
||||
let principal =
|
||||
ssm.createCodebasePrincipal(uri,
|
||||
{appId: params.appId || ssm.NO_APPID,
|
||||
inIsolatedMozBrowser: params.inIsolatedMozBrowser});
|
||||
let request = indexedDB.openForPrincipal(principal, params.dbName,
|
||||
params.dbVersion);
|
||||
return request;
|
||||
}
|
||||
|
||||
for (let i = 1; i <= 2; i++) {
|
||||
clearAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
installPackagedProfile("idbSubdirUpgrade" + i + "_profile");
|
||||
|
||||
for (let params of openParams) {
|
||||
let request = openDatabase(params);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Correct event type");
|
||||
}
|
||||
|
||||
resetAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
for (let params of openParams) {
|
||||
let request = openDatabase(params);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Correct event type");
|
||||
}
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
174
dom/indexedDB/test/unit/test_idle_maintenance.js
Normal file
174
dom/indexedDB/test/unit/test_idle_maintenance.js
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
let uri = Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService).
|
||||
newURI("https://www.example.com", null, null);
|
||||
let ssm = Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Ci.nsIScriptSecurityManager);
|
||||
let principal = ssm.createCodebasePrincipal(uri, {});
|
||||
|
||||
info("Setting permissions");
|
||||
|
||||
let permMgr =
|
||||
Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager);
|
||||
permMgr.add(uri, "indexedDB", Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
|
||||
info("Setting idle preferences to prevent real 'idle-daily' notification");
|
||||
|
||||
let prefs =
|
||||
Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
|
||||
prefs.setIntPref("idle.lastDailyNotification", (Date.now() / 1000) - 10);
|
||||
|
||||
info("Activating real idle service");
|
||||
|
||||
do_get_idle();
|
||||
|
||||
info("Creating databases");
|
||||
|
||||
let quotaManagerService = Cc["@mozilla.org/dom/quota-manager-service;1"].
|
||||
getService(Ci.nsIQuotaManagerService);
|
||||
|
||||
// Keep at least one database open.
|
||||
let req = indexedDB.open("foo-a", 1);
|
||||
req.onerror = errorHandler;
|
||||
req.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let dbA = event.target.result;
|
||||
|
||||
// Keep at least one factory operation alive by deleting a database that is
|
||||
// stil open.
|
||||
req = indexedDB.open("foo-b", 1);
|
||||
req.onerror = errorHandler;
|
||||
req.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
let dbB = event.target.result;
|
||||
|
||||
indexedDB.deleteDatabase("foo-b");
|
||||
|
||||
// Create a database which we will later try to open while maintenance is
|
||||
// performed.
|
||||
req = indexedDB.open("foo-c", 1);
|
||||
req.onerror = errorHandler;
|
||||
req.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
let dbC = event.target.result;
|
||||
dbC.close();
|
||||
|
||||
let dbCount = 0;
|
||||
|
||||
for (let persistence of ["persistent", "temporary", "default"]) {
|
||||
for (let i = 1; i <= 5; i++) {
|
||||
let dbName = "foo-" + i;
|
||||
let dbPersistence = persistence;
|
||||
let req = indexedDB.openForPrincipal(principal,
|
||||
dbName,
|
||||
{ version: 1,
|
||||
storage: dbPersistence });
|
||||
req.onerror = event => {
|
||||
if (dbPersistence != "persistent") {
|
||||
errorHandler(event);
|
||||
return;
|
||||
}
|
||||
|
||||
// Explicit persistence is currently blocked on mobile.
|
||||
info("Failed to create persistent database '" + dbPersistence + "/" +
|
||||
dbName + "', hopefully this is on mobile!");
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if (!(--dbCount)) {
|
||||
continueToNextStep();
|
||||
}
|
||||
};
|
||||
req.onupgradeneeded = event => {
|
||||
let db = event.target.result;
|
||||
let objectStore = db.createObjectStore("foo");
|
||||
|
||||
// Add lots of data...
|
||||
for (let j = 0; j < 100; j++) {
|
||||
objectStore.add("abcdefghijklmnopqrstuvwxyz0123456789", j);
|
||||
}
|
||||
|
||||
// And then clear it so that maintenance has some space to reclaim.
|
||||
objectStore.clear();
|
||||
};
|
||||
req.onsuccess = event => {
|
||||
let db = event.target.result;
|
||||
ok(db, "Created database '" + dbPersistence + "/" + dbName + "'");
|
||||
|
||||
db.close();
|
||||
|
||||
if (!(--dbCount)) {
|
||||
continueToNextStep();
|
||||
}
|
||||
};
|
||||
dbCount++;
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
info("Getting usage before maintenance");
|
||||
|
||||
let usageBeforeMaintenance;
|
||||
|
||||
quotaManagerService.getUsageForPrincipal(principal, (request) => {
|
||||
let usage = request.result.usage;
|
||||
ok(usage > 0, "Usage is non-zero");
|
||||
usageBeforeMaintenance = usage;
|
||||
continueToNextStep();
|
||||
});
|
||||
yield undefined;
|
||||
|
||||
info("Sending fake 'idle-daily' notification to QuotaManager");
|
||||
|
||||
let observer = quotaManagerService.QueryInterface(Ci.nsIObserver);
|
||||
observer.observe(null, "idle-daily", "");
|
||||
|
||||
info("Opening database while maintenance is performed");
|
||||
|
||||
req = indexedDB.open("foo-c", 1);
|
||||
req.onerror = errorHandler;
|
||||
req.onsuccess = grabEventAndContinueHandler;
|
||||
yield undefined;
|
||||
|
||||
info("Waiting for maintenance to start");
|
||||
|
||||
// This time is totally arbitrary. Most likely directory scanning will have
|
||||
// completed, QuotaManager locks will be acquired, and maintenance tasks will
|
||||
// be scheduled before this time has elapsed, so we will be testing the
|
||||
// maintenance code. However, if something is slow then this will test
|
||||
// shutting down in the middle of maintenance.
|
||||
setTimeout(continueToNextStep, 10000);
|
||||
yield undefined;
|
||||
|
||||
info("Getting usage after maintenance");
|
||||
|
||||
let usageAfterMaintenance;
|
||||
|
||||
quotaManagerService.getUsageForPrincipal(principal, (request) => {
|
||||
let usage = request.result.usage;
|
||||
ok(usage > 0, "Usage is non-zero");
|
||||
usageAfterMaintenance = usage;
|
||||
continueToNextStep();
|
||||
});
|
||||
yield undefined;
|
||||
|
||||
info("Usage before: " + usageBeforeMaintenance + ". " +
|
||||
"Usage after: " + usageAfterMaintenance);
|
||||
|
||||
ok(usageAfterMaintenance <= usageBeforeMaintenance,
|
||||
"Maintenance decreased file sizes or left them the same");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
83
dom/indexedDB/test/unit/test_index_empty_keyPath.js
Normal file
83
dom/indexedDB/test/unit/test_index_empty_keyPath.js
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
|
||||
const objectStoreData = [
|
||||
{ key: "1", value: "foo" },
|
||||
{ key: "2", value: "bar" },
|
||||
{ key: "3", value: "baz" }
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined; // upgradeneeded
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
let objectStore = db.createObjectStore("data", { keyPath: null });
|
||||
|
||||
// First, add all our data to the object store.
|
||||
let addedData = 0;
|
||||
for (let i in objectStoreData) {
|
||||
request = objectStore.add(objectStoreData[i].value,
|
||||
objectStoreData[i].key);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
if (++addedData == objectStoreData.length) {
|
||||
testGenerator.send(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
event = yield undefined; // testGenerator.send
|
||||
|
||||
// Now create the index.
|
||||
objectStore.createIndex("set", "", { unique: true });
|
||||
yield undefined; // success
|
||||
|
||||
let trans = db.transaction("data", "readwrite");
|
||||
objectStore = trans.objectStore("data");
|
||||
index = objectStore.index("set");
|
||||
|
||||
request = index.get("bar");
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, "bar", "Got correct result");
|
||||
|
||||
request = objectStore.add("foopy", 4);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
yield undefined;
|
||||
|
||||
request = index.get("foopy");
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, "foopy", "Got correct result");
|
||||
|
||||
request = objectStore.add("foopy", 5);
|
||||
request.addEventListener("error", new ExpectError("ConstraintError", true));
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
|
||||
trans.oncomplete = grabEventAndContinueHandler;
|
||||
|
||||
yield undefined;
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
191
dom/indexedDB/test/unit/test_index_getAll.js
Normal file
191
dom/indexedDB/test/unit/test_index_getAll.js
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const objectStoreName = "People";
|
||||
|
||||
const objectStoreData = [
|
||||
{ key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
|
||||
{ key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
|
||||
{ key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7737", value: { name: "Pat", height: 65 } }
|
||||
];
|
||||
|
||||
const indexData = [
|
||||
{ name: "name", keyPath: "name", options: { unique: true } },
|
||||
{ name: "height", keyPath: "height", options: { unique: false } },
|
||||
{ name: "weight", keyPath: "weight", options: { unique: false } }
|
||||
];
|
||||
|
||||
const objectStoreDataNameSort = [
|
||||
{ key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7737", value: { name: "Pat", height: 65 } },
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
|
||||
{ key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } }
|
||||
];
|
||||
|
||||
const objectStoreDataWeightSort = [
|
||||
{ key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
|
||||
{ key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
||||
];
|
||||
|
||||
const objectStoreDataHeightSort = [
|
||||
{ key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
|
||||
{ key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7737", value: { name: "Pat", height: 65 } },
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
let objectStore = db.createObjectStore(objectStoreName);
|
||||
|
||||
// First, add all our data to the object store.
|
||||
let addedData = 0;
|
||||
for (let i in objectStoreData) {
|
||||
request = objectStore.add(objectStoreData[i].value,
|
||||
objectStoreData[i].key);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
if (++addedData == objectStoreData.length) {
|
||||
testGenerator.send(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
ok(true, "1");
|
||||
|
||||
// Now create the indexes.
|
||||
for (let i in indexData) {
|
||||
objectStore.createIndex(indexData[i].name, indexData[i].keyPath,
|
||||
indexData[i].options);
|
||||
}
|
||||
|
||||
is(objectStore.indexNames.length, indexData.length, "Good index count");
|
||||
yield undefined;
|
||||
|
||||
ok(true, "2");
|
||||
objectStore = db.transaction(objectStoreName)
|
||||
.objectStore(objectStoreName);
|
||||
|
||||
request = objectStore.index("height").mozGetAllKeys(65);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
ok(true, "3");
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
|
||||
"Correct key");
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAllKeys(65, 0);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
ok(true, "3");
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
|
||||
"Correct key");
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAllKeys(65, null);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
ok(true, "3");
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
|
||||
"Correct key");
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAllKeys(65, undefined);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
ok(true, "3");
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
|
||||
"Correct key");
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAllKeys();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
ok(true, "4");
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, objectStoreDataHeightSort.length,
|
||||
"Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], objectStoreDataHeightSort[i].key, "Correct key");
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAllKeys(null, 4);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(true, "5");
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 4, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], objectStoreDataHeightSort[i].key, "Correct key");
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAllKeys(65, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(true, "6");
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 1, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
|
||||
"Correct key");
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
233
dom/indexedDB/test/unit/test_index_getAllObjects.js
Normal file
233
dom/indexedDB/test/unit/test_index_getAllObjects.js
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const objectStoreName = "People";
|
||||
|
||||
const objectStoreData = [
|
||||
{ key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
|
||||
{ key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
|
||||
{ key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7737", value: { name: "Pat", height: 65 } }
|
||||
];
|
||||
|
||||
const indexData = [
|
||||
{ name: "name", keyPath: "name", options: { unique: true } },
|
||||
{ name: "height", keyPath: "height", options: { unique: false } },
|
||||
{ name: "weight", keyPath: "weight", options: { unique: false } }
|
||||
];
|
||||
|
||||
const objectStoreDataNameSort = [
|
||||
{ key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7737", value: { name: "Pat", height: 65 } },
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
|
||||
{ key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } }
|
||||
];
|
||||
|
||||
const objectStoreDataWeightSort = [
|
||||
{ key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
|
||||
{ key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
||||
];
|
||||
|
||||
const objectStoreDataHeightSort = [
|
||||
{ key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
|
||||
{ key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7737", value: { name: "Pat", height: 65 } },
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
let objectStore = db.createObjectStore(objectStoreName, {});
|
||||
|
||||
// First, add all our data to the object store.
|
||||
let addedData = 0;
|
||||
for (let i in objectStoreData) {
|
||||
request = objectStore.add(objectStoreData[i].value,
|
||||
objectStoreData[i].key);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
if (++addedData == objectStoreData.length) {
|
||||
testGenerator.send(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
event = yield undefined;
|
||||
|
||||
// Now create the indexes.
|
||||
for (let i in indexData) {
|
||||
objectStore.createIndex(indexData[i].name, indexData[i].keyPath,
|
||||
indexData[i].options);
|
||||
}
|
||||
|
||||
is(objectStore.indexNames.length, indexData.length, "Good index count");
|
||||
yield undefined;
|
||||
|
||||
objectStore = db.transaction(objectStoreName)
|
||||
.objectStore(objectStoreName);
|
||||
|
||||
request = objectStore.index("height").mozGetAll(65);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
let result = event.target.result[i];
|
||||
let testObj = objectStoreDataHeightSort[parseInt(i) + 3].value;
|
||||
|
||||
is(result.name, testObj.name, "Correct name");
|
||||
is(result.height, testObj.height, "Correct height");
|
||||
|
||||
if (testObj.hasOwnProperty("weight")) {
|
||||
is(result.weight, testObj.weight, "Correct weight");
|
||||
}
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAll(65, 0);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
let result = event.target.result[i];
|
||||
let testObj = objectStoreDataHeightSort[parseInt(i) + 3].value;
|
||||
|
||||
is(result.name, testObj.name, "Correct name");
|
||||
is(result.height, testObj.height, "Correct height");
|
||||
|
||||
if (testObj.hasOwnProperty("weight")) {
|
||||
is(result.weight, testObj.weight, "Correct weight");
|
||||
}
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAll(65, null);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
let result = event.target.result[i];
|
||||
let testObj = objectStoreDataHeightSort[parseInt(i) + 3].value;
|
||||
|
||||
is(result.name, testObj.name, "Correct name");
|
||||
is(result.height, testObj.height, "Correct height");
|
||||
|
||||
if (testObj.hasOwnProperty("weight")) {
|
||||
is(result.weight, testObj.weight, "Correct weight");
|
||||
}
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAll(65, undefined);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
let result = event.target.result[i];
|
||||
let testObj = objectStoreDataHeightSort[parseInt(i) + 3].value;
|
||||
|
||||
is(result.name, testObj.name, "Correct name");
|
||||
is(result.height, testObj.height, "Correct height");
|
||||
|
||||
if (testObj.hasOwnProperty("weight")) {
|
||||
is(result.weight, testObj.weight, "Correct weight");
|
||||
}
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAll();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, objectStoreDataHeightSort.length,
|
||||
"Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
let result = event.target.result[i];
|
||||
let testObj = objectStoreDataHeightSort[i].value;
|
||||
|
||||
is(result.name, testObj.name, "Correct name");
|
||||
is(result.height, testObj.height, "Correct height");
|
||||
|
||||
if (testObj.hasOwnProperty("weight")) {
|
||||
is(result.weight, testObj.weight, "Correct weight");
|
||||
}
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAll(null, 4);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 4, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
let result = event.target.result[i];
|
||||
let testObj = objectStoreDataHeightSort[i].value;
|
||||
|
||||
is(result.name, testObj.name, "Correct name");
|
||||
is(result.height, testObj.height, "Correct height");
|
||||
|
||||
if (testObj.hasOwnProperty("weight")) {
|
||||
is(result.weight, testObj.weight, "Correct weight");
|
||||
}
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAll(65, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 1, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
let result = event.target.result[i];
|
||||
let testObj = objectStoreDataHeightSort[parseInt(i) + 3].value;
|
||||
|
||||
is(result.name, testObj.name, "Correct name");
|
||||
is(result.height, testObj.height, "Correct height");
|
||||
|
||||
if (testObj.hasOwnProperty("weight")) {
|
||||
is(result.weight, testObj.weight, "Correct weight");
|
||||
}
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
147
dom/indexedDB/test/unit/test_index_object_cursors.js
Normal file
147
dom/indexedDB/test/unit/test_index_object_cursors.js
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const objectStoreData = [
|
||||
{ name: "", options: { keyPath: "id", autoIncrement: true } },
|
||||
{ name: null, options: { keyPath: "ss" } },
|
||||
{ name: undefined, options: { } },
|
||||
{ name: "4", options: { autoIncrement: true } },
|
||||
];
|
||||
|
||||
const indexData = [
|
||||
{ name: "", keyPath: "name", options: { unique: true } },
|
||||
{ name: null, keyPath: "height", options: { } }
|
||||
];
|
||||
|
||||
const data = [
|
||||
{ ss: "237-23-7732", name: "Ann", height: 60 },
|
||||
{ ss: "237-23-7733", name: "Bob", height: 65 }
|
||||
];
|
||||
|
||||
let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
event.target.onsuccess = continueToNextStep;
|
||||
|
||||
for (let objectStoreIndex in objectStoreData) {
|
||||
const objectStoreInfo = objectStoreData[objectStoreIndex];
|
||||
let objectStore = db.createObjectStore(objectStoreInfo.name,
|
||||
objectStoreInfo.options);
|
||||
for (let indexIndex in indexData) {
|
||||
const indexInfo = indexData[indexIndex];
|
||||
let index = objectStore.createIndex(indexInfo.name,
|
||||
indexInfo.keyPath,
|
||||
indexInfo.options);
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
ok(true, "Initial setup");
|
||||
|
||||
for (let objectStoreIndex in objectStoreData) {
|
||||
const info = objectStoreData[objectStoreIndex];
|
||||
|
||||
for (let indexIndex in indexData) {
|
||||
const objectStoreName = objectStoreData[objectStoreIndex].name;
|
||||
const indexName = indexData[indexIndex].name;
|
||||
|
||||
let objectStore =
|
||||
db.transaction(objectStoreName, "readwrite")
|
||||
.objectStore(objectStoreName);
|
||||
ok(true, "Got objectStore " + objectStoreName);
|
||||
|
||||
for (let dataIndex in data) {
|
||||
const obj = data[dataIndex];
|
||||
let key;
|
||||
if (!info.options.keyPath && !info.options.autoIncrement) {
|
||||
key = obj.ss;
|
||||
}
|
||||
objectStore.add(obj, key);
|
||||
}
|
||||
|
||||
let index = objectStore.index(indexName);
|
||||
ok(true, "Got index " + indexName);
|
||||
|
||||
let keyIndex = 0;
|
||||
|
||||
index.openCursor().onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (!cursor) {
|
||||
continueToNextStep();
|
||||
return;
|
||||
}
|
||||
|
||||
is(cursor.key, data[keyIndex][indexData[indexIndex].keyPath],
|
||||
"Good key");
|
||||
is(cursor.value.ss, data[keyIndex].ss, "Correct ss");
|
||||
is(cursor.value.name, data[keyIndex].name, "Correct name");
|
||||
is(cursor.value.height, data[keyIndex].height, "Correct height");
|
||||
|
||||
if (!keyIndex) {
|
||||
let obj = cursor.value;
|
||||
obj.updated = true;
|
||||
|
||||
cursor.update(obj).onsuccess = function(event) {
|
||||
ok(true, "Object updated");
|
||||
cursor.continue();
|
||||
keyIndex++
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cursor.delete().onsuccess = function(event) {
|
||||
ok(true, "Object deleted");
|
||||
cursor.continue();
|
||||
keyIndex++
|
||||
}
|
||||
};
|
||||
yield undefined;
|
||||
|
||||
is(keyIndex, 2, "Saw all the items");
|
||||
|
||||
keyIndex = 0;
|
||||
|
||||
db.transaction(objectStoreName).objectStore(objectStoreName)
|
||||
.openCursor()
|
||||
.onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (!cursor) {
|
||||
continueToNextStep();
|
||||
return;
|
||||
}
|
||||
|
||||
is(cursor.value.ss, data[keyIndex].ss, "Correct ss");
|
||||
is(cursor.value.name, data[keyIndex].name, "Correct name");
|
||||
is(cursor.value.height, data[keyIndex].height, "Correct height");
|
||||
is(cursor.value.updated, true, "Correct updated flag");
|
||||
|
||||
cursor.continue();
|
||||
keyIndex++;
|
||||
};
|
||||
yield undefined;
|
||||
|
||||
is(keyIndex, 1, "Saw all the items");
|
||||
|
||||
db.transaction(objectStoreName, "readwrite")
|
||||
.objectStore(objectStoreName).clear()
|
||||
.onsuccess = continueToNextStep;
|
||||
yield undefined;
|
||||
|
||||
objectStore = index = null; // Bug 943409 workaround.
|
||||
}
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
171
dom/indexedDB/test/unit/test_index_update_delete.js
Normal file
171
dom/indexedDB/test/unit/test_index_update_delete.js
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
let name = this.window ? window.location.pathname : "Splendid Test";
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
for (let autoIncrement of [false, true]) {
|
||||
let objectStore =
|
||||
db.createObjectStore(autoIncrement, { keyPath: "id",
|
||||
autoIncrement: autoIncrement });
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
objectStore.add({ id: i, index: i });
|
||||
}
|
||||
|
||||
for (let unique of [false, true]) {
|
||||
objectStore.createIndex(unique, "index", { unique: unique });
|
||||
}
|
||||
|
||||
for (let i = 10; i < 20; i++) {
|
||||
objectStore.add({ id: i, index: i });
|
||||
}
|
||||
}
|
||||
|
||||
event = yield undefined;
|
||||
is(event.type, "success", "expect a success event");
|
||||
|
||||
for (let autoIncrement of [false, true]) {
|
||||
let objectStore = db.transaction(autoIncrement)
|
||||
.objectStore(autoIncrement);
|
||||
|
||||
objectStore.count().onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.target.result, 20, "Correct number of entries in objectStore");
|
||||
|
||||
let objectStoreCount = event.target.result;
|
||||
let indexCount = event.target.result;
|
||||
|
||||
for (let unique of [false, true]) {
|
||||
let index = db.transaction(autoIncrement, "readwrite")
|
||||
.objectStore(autoIncrement)
|
||||
.index(unique);
|
||||
|
||||
index.count().onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.target.result, indexCount,
|
||||
"Correct number of entries in index");
|
||||
|
||||
let modifiedEntry = unique ? 5 : 10;
|
||||
let keyRange = IDBKeyRange.only(modifiedEntry);
|
||||
|
||||
let sawEntry = false;
|
||||
index.openCursor(keyRange).onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
sawEntry = true;
|
||||
is(cursor.key, modifiedEntry, "Correct key");
|
||||
|
||||
cursor.value.index = unique ? 30 : 35;
|
||||
cursor.update(cursor.value).onsuccess = function(event) {
|
||||
cursor.continue();
|
||||
}
|
||||
}
|
||||
else {
|
||||
continueToNextStep();
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
is(sawEntry, true, "Saw entry for key value " + modifiedEntry);
|
||||
|
||||
// Recount index. Shouldn't change.
|
||||
index = db.transaction(autoIncrement, "readwrite")
|
||||
.objectStore(autoIncrement)
|
||||
.index(unique);
|
||||
|
||||
index.count().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, indexCount,
|
||||
"Correct number of entries in index");
|
||||
|
||||
modifiedEntry = unique ? 30 : 35;
|
||||
keyRange = IDBKeyRange.only(modifiedEntry);
|
||||
|
||||
sawEntry = false;
|
||||
index.openCursor(keyRange).onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
sawEntry = true;
|
||||
is(cursor.key, modifiedEntry, "Correct key");
|
||||
|
||||
delete cursor.value.index;
|
||||
cursor.update(cursor.value).onsuccess = function(event) {
|
||||
indexCount--;
|
||||
cursor.continue();
|
||||
}
|
||||
}
|
||||
else {
|
||||
continueToNextStep();
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
is(sawEntry, true, "Saw entry for key value " + modifiedEntry);
|
||||
|
||||
// Recount objectStore. Should be unchanged.
|
||||
objectStore = db.transaction(autoIncrement, "readwrite")
|
||||
.objectStore(autoIncrement);
|
||||
|
||||
objectStore.count().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, objectStoreCount,
|
||||
"Correct number of entries in objectStore");
|
||||
|
||||
// Recount index. Should be one item less.
|
||||
index = objectStore.index(unique);
|
||||
|
||||
index.count().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, indexCount,
|
||||
"Correct number of entries in index");
|
||||
|
||||
modifiedEntry = objectStoreCount - 1;
|
||||
|
||||
objectStore.delete(modifiedEntry).onsuccess =
|
||||
grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
objectStoreCount--;
|
||||
indexCount--;
|
||||
|
||||
objectStore.count().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, objectStoreCount,
|
||||
"Correct number of entries in objectStore");
|
||||
|
||||
index.count().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, indexCount,
|
||||
"Correct number of entries in index");
|
||||
|
||||
index = event = null; // Bug 943409 workaround.
|
||||
}
|
||||
objectStore = event = null; // Bug 943409 workaround.
|
||||
}
|
||||
|
||||
finishTest();
|
||||
event = db = request = null; // Bug 943409 workaround.
|
||||
yield undefined;
|
||||
}
|
||||
1261
dom/indexedDB/test/unit/test_indexes.js
Normal file
1261
dom/indexedDB/test/unit/test_indexes.js
Normal file
File diff suppressed because it is too large
Load diff
130
dom/indexedDB/test/unit/test_indexes_bad_values.js
Normal file
130
dom/indexedDB/test/unit/test_indexes_bad_values.js
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
|
||||
const objectStoreName = "People";
|
||||
|
||||
const objectStoreData = [
|
||||
{ key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
|
||||
{ key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
|
||||
{ key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7737", value: { name: "Pat", height: 65 } },
|
||||
{ key: "237-23-7738", value: { name: "Mel", height: 66, weight: {} } }
|
||||
];
|
||||
|
||||
const badObjectStoreData = [
|
||||
{ key: "237-23-7739", value: { name: "Rob", height: 65 } },
|
||||
{ key: "237-23-7740", value: { name: "Jen", height: 66, weight: {} } }
|
||||
];
|
||||
|
||||
const indexData = [
|
||||
{ name: "weight", keyPath: "weight", options: { unique: false } }
|
||||
];
|
||||
|
||||
const objectStoreDataWeightSort = [
|
||||
{ key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
|
||||
{ key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
let objectStore = db.createObjectStore(objectStoreName, { } );
|
||||
|
||||
let addedData = 0;
|
||||
for (let i in objectStoreData) {
|
||||
request = objectStore.add(objectStoreData[i].value,
|
||||
objectStoreData[i].key);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
if (++addedData == objectStoreData.length) {
|
||||
testGenerator.send(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
event = yield undefined;
|
||||
|
||||
for (let i in indexData) {
|
||||
objectStore.createIndex(indexData[i].name, indexData[i].keyPath,
|
||||
indexData[i].options);
|
||||
}
|
||||
|
||||
addedData = 0;
|
||||
for (let i in badObjectStoreData) {
|
||||
request = objectStore.add(badObjectStoreData[i].value,
|
||||
badObjectStoreData[i].key);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
if (++addedData == badObjectStoreData.length) {
|
||||
executeSoon(function() { testGenerator.next() });
|
||||
}
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
yield undefined;
|
||||
|
||||
objectStore = db.transaction(objectStoreName)
|
||||
.objectStore(objectStoreName);
|
||||
|
||||
let keyIndex = 0;
|
||||
|
||||
request = objectStore.index("weight").openKeyCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataWeightSort[keyIndex].value.weight,
|
||||
"Correct key");
|
||||
is(cursor.primaryKey, objectStoreDataWeightSort[keyIndex].key,
|
||||
"Correct value");
|
||||
keyIndex++;
|
||||
|
||||
cursor.continue();
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
is(keyIndex, objectStoreDataWeightSort.length, "Saw all weights");
|
||||
|
||||
keyIndex = 0;
|
||||
|
||||
request = objectStore.openCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
keyIndex++;
|
||||
cursor.continue();
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
is(keyIndex, objectStoreData.length + badObjectStoreData.length,
|
||||
"Saw all people");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
168
dom/indexedDB/test/unit/test_indexes_funny_things.js
Normal file
168
dom/indexedDB/test/unit/test_indexes_funny_things.js
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
// Blob constructor is not implemented outside of windows yet (Bug 827723).
|
||||
if (!this.window) {
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
|
||||
const objectStoreName = "Things";
|
||||
|
||||
const blob1 = new Blob(["foo", "bar"], { type: "text/plain" });
|
||||
const blob2 = new Blob(["foobazybar"], { type: "text/plain" });
|
||||
const blob3 = new Blob(["2"], { type: "bogus/" });
|
||||
const str = "The Book of Mozilla";
|
||||
str.type = blob1;
|
||||
const arr = [1, 2, 3, 4, 5];
|
||||
|
||||
const objectStoreData = [
|
||||
{ key: "1", value: blob1},
|
||||
{ key: "2", value: blob2},
|
||||
{ key: "3", value: blob3},
|
||||
{ key: "4", value: str},
|
||||
{ key: "5", value: arr},
|
||||
];
|
||||
|
||||
const indexData = [
|
||||
{ name: "type", keyPath: "type", options: { } },
|
||||
{ name: "length", keyPath: "length", options: { unique: true } }
|
||||
];
|
||||
|
||||
const objectStoreDataTypeSort = [
|
||||
{ key: "3", value: blob3},
|
||||
{ key: "1", value: blob1},
|
||||
{ key: "2", value: blob2},
|
||||
];
|
||||
|
||||
const objectStoreDataLengthSort = [
|
||||
{ key: "5", value: arr},
|
||||
{ key: "4", value: str},
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
let db = event.target.result;
|
||||
|
||||
let objectStore = db.createObjectStore(objectStoreName, { keyPath: null });
|
||||
|
||||
// First, add all our data to the object store.
|
||||
let addedData = 0;
|
||||
for (let i in objectStoreData) {
|
||||
request = objectStore.add(objectStoreData[i].value,
|
||||
objectStoreData[i].key);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
if (++addedData == objectStoreData.length) {
|
||||
testGenerator.send(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
event = yield undefined;
|
||||
// Now create the indexes.
|
||||
for (let i in indexData) {
|
||||
objectStore.createIndex(indexData[i].name, indexData[i].keyPath,
|
||||
indexData[i].options);
|
||||
}
|
||||
is(objectStore.indexNames.length, indexData.length, "Good index count");
|
||||
yield undefined;
|
||||
objectStore = db.transaction(objectStoreName)
|
||||
.objectStore(objectStoreName);
|
||||
|
||||
// Check global properties to make sure they are correct.
|
||||
is(objectStore.indexNames.length, indexData.length, "Good index count");
|
||||
for (let i in indexData) {
|
||||
let found = false;
|
||||
for (let j = 0; j < objectStore.indexNames.length; j++) {
|
||||
if (objectStore.indexNames.item(j) == indexData[i].name) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
is(found, true, "objectStore has our index");
|
||||
let index = objectStore.index(indexData[i].name);
|
||||
is(index.name, indexData[i].name, "Correct name");
|
||||
is(index.objectStore.name, objectStore.name, "Correct store name");
|
||||
is(index.keyPath, indexData[i].keyPath, "Correct keyPath");
|
||||
is(index.unique, indexData[i].options.unique ? true : false,
|
||||
"Correct unique value");
|
||||
}
|
||||
|
||||
ok(true, "Test group 1");
|
||||
|
||||
let keyIndex = 0;
|
||||
|
||||
request = objectStore.index("type").openKeyCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataTypeSort[keyIndex].value.type,
|
||||
"Correct key");
|
||||
is(cursor.primaryKey, objectStoreDataTypeSort[keyIndex].key,
|
||||
"Correct primary key");
|
||||
ok(!("value" in cursor), "No value");
|
||||
|
||||
cursor.continue();
|
||||
|
||||
is(cursor.key, objectStoreDataTypeSort[keyIndex].value.type,
|
||||
"Correct key");
|
||||
is(cursor.primaryKey, objectStoreDataTypeSort[keyIndex].key,
|
||||
"Correct value");
|
||||
ok(!("value" in cursor), "No value");
|
||||
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
is(keyIndex, objectStoreDataTypeSort.length, "Saw all the expected keys");
|
||||
|
||||
ok(true, "Test group 2");
|
||||
|
||||
keyIndex = 0;
|
||||
|
||||
request = objectStore.index("length").openKeyCursor(null, "next");
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
is(cursor.key, objectStoreDataLengthSort[keyIndex].value.length,
|
||||
"Correct key");
|
||||
is(cursor.primaryKey, objectStoreDataLengthSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
cursor.continue();
|
||||
|
||||
is(cursor.key, objectStoreDataLengthSort[keyIndex].value.length,
|
||||
"Correct key");
|
||||
is(cursor.primaryKey, objectStoreDataLengthSort[keyIndex].key,
|
||||
"Correct value");
|
||||
|
||||
keyIndex++;
|
||||
}
|
||||
else {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
is(keyIndex, objectStoreDataLengthSort.length, "Saw all the expected keys");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
64
dom/indexedDB/test/unit/test_invalid_cursor.js
Normal file
64
dom/indexedDB/test/unit/test_invalid_cursor.js
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var disableWorkerTest = "Need to implement a gc() function for worker tests";
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const dbName = ("window" in this) ? window.location.pathname : "test";
|
||||
const dbVersion = 1;
|
||||
const objectStoreName = "foo";
|
||||
const data = 0;
|
||||
|
||||
let req = indexedDB.open(dbName, dbVersion);
|
||||
req.onerror = errorHandler;
|
||||
req.onupgradeneeded = grabEventAndContinueHandler;
|
||||
req.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Got upgradeneeded event");
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
let objectStore =
|
||||
db.createObjectStore(objectStoreName, { autoIncrement: true });
|
||||
objectStore.add(data);
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got success event for open");
|
||||
|
||||
objectStore = db.transaction(objectStoreName).objectStore(objectStoreName);
|
||||
|
||||
objectStore.openCursor().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got success event for openCursor");
|
||||
|
||||
let cursor = event.target.result;
|
||||
is(cursor.value, data, "Got correct cursor value");
|
||||
|
||||
objectStore.get(cursor.key).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, data, "Got correct get value");
|
||||
|
||||
info("Collecting garbage");
|
||||
|
||||
gc();
|
||||
|
||||
info("Done collecting garbage");
|
||||
|
||||
cursor.continue();
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, null, "No more entries");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
50
dom/indexedDB/test/unit/test_invalid_version.js
Normal file
50
dom/indexedDB/test/unit/test_invalid_version.js
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
|
||||
try {
|
||||
indexedDB.open(name, 0);
|
||||
ok(false, "Should have thrown!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(e instanceof TypeError, "Got TypeError.");
|
||||
is(e.name, "TypeError", "Good error name.");
|
||||
}
|
||||
|
||||
try {
|
||||
indexedDB.open(name, -1);
|
||||
ok(false, "Should have thrown!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(e instanceof TypeError, "Got TypeError.");
|
||||
is(e.name, "TypeError", "Good error name.");
|
||||
}
|
||||
|
||||
try {
|
||||
indexedDB.open(name, { version: 0 });
|
||||
ok(false, "Should have thrown!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(e instanceof TypeError, "Got TypeError.");
|
||||
is(e.name, "TypeError", "Good error name.");
|
||||
}
|
||||
|
||||
try {
|
||||
indexedDB.open(name, { version: -1 });
|
||||
ok(false, "Should have thrown!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(e instanceof TypeError, "Got TypeError.");
|
||||
is(e.name, "TypeError", "Good error name.");
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
82
dom/indexedDB/test/unit/test_invalidate.js
Normal file
82
dom/indexedDB/test/unit/test_invalidate.js
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const databaseName =
|
||||
("window" in this) ? window.location.pathname : "Test";
|
||||
|
||||
let dbCount = 0;
|
||||
|
||||
// Test invalidating during a versionchange transaction.
|
||||
info("Opening database " + ++dbCount);
|
||||
|
||||
let request = indexedDB.open(databaseName, dbCount);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Upgrading database " + dbCount);
|
||||
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
|
||||
let objStore =
|
||||
request.result.createObjectStore("foo", { autoIncrement: true });
|
||||
objStore.createIndex("fooIndex", "fooIndex", { unique: true });
|
||||
objStore.put({ foo: 1 });
|
||||
objStore.get(1);
|
||||
objStore.count();
|
||||
objStore.openCursor();
|
||||
objStore.delete(1);
|
||||
|
||||
info("Invalidating database " + dbCount);
|
||||
|
||||
clearAllDatabases(continueToNextStepSync);
|
||||
|
||||
objStore = request.result.createObjectStore("bar");
|
||||
objStore.createIndex("barIndex", "barIndex", { multiEntry: true });
|
||||
objStore.put({ bar: 1, barIndex: [ 0, 1 ] }, 10);
|
||||
objStore.get(10);
|
||||
objStore.count();
|
||||
objStore.openCursor();
|
||||
objStore.delete(10);
|
||||
|
||||
yield undefined;
|
||||
|
||||
executeSoon(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
// Test invalidating after the complete event of a versionchange transaction.
|
||||
info("Opening database " + ++dbCount);
|
||||
|
||||
request = indexedDB.open(databaseName, dbCount);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Upgrading database " + dbCount);
|
||||
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
|
||||
request.transaction.oncomplete = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "complete",
|
||||
"Got complete event for versionchange transaction on database " + dbCount);
|
||||
|
||||
info("Invalidating database " + dbCount);
|
||||
|
||||
clearAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
executeSoon(continueToNextStepSync);
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
285
dom/indexedDB/test/unit/test_key_requirements.js
Normal file
285
dom/indexedDB/test/unit/test_key_requirements.js
Normal file
|
|
@ -0,0 +1,285 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
db.addEventListener("error", function(event) {
|
||||
event.preventDefault();
|
||||
}, false);
|
||||
|
||||
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
||||
|
||||
request = objectStore.add({});
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
let key1 = event.target.result;
|
||||
|
||||
request = objectStore.put({}, key1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, key1, "put gave the same key back");
|
||||
|
||||
let key2 = 10;
|
||||
|
||||
request = objectStore.put({}, key2);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, key2, "put gave the same key back");
|
||||
|
||||
key2 = 100;
|
||||
|
||||
request = objectStore.add({}, key2);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, key2, "put gave the same key back");
|
||||
|
||||
try {
|
||||
objectStore.put({});
|
||||
ok(true, "put with no key should not throw with autoIncrement!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(false, "put with no key threw with autoIncrement");
|
||||
}
|
||||
|
||||
try {
|
||||
objectStore.put({});
|
||||
ok(true, "put with no key should not throw with autoIncrement!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(false, "put with no key threw with autoIncrement");
|
||||
}
|
||||
|
||||
try {
|
||||
objectStore.delete();
|
||||
ok(false, "remove with no key should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "remove with no key threw");
|
||||
}
|
||||
|
||||
objectStore = db.createObjectStore("bar");
|
||||
|
||||
try {
|
||||
objectStore.add({});
|
||||
ok(false, "add with no key should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "add with no key threw");
|
||||
}
|
||||
|
||||
try {
|
||||
objectStore.put({});
|
||||
ok(false, "put with no key should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "put with no key threw");
|
||||
}
|
||||
|
||||
try {
|
||||
objectStore.put({});
|
||||
ok(false, "put with no key should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "put with no key threw");
|
||||
}
|
||||
|
||||
try {
|
||||
objectStore.delete();
|
||||
ok(false, "remove with no key should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "remove with no key threw");
|
||||
}
|
||||
|
||||
objectStore = db.createObjectStore("baz", { keyPath: "id" });
|
||||
|
||||
try {
|
||||
objectStore.add({});
|
||||
ok(false, "add with no key should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "add with no key threw");
|
||||
}
|
||||
|
||||
try {
|
||||
objectStore.add({id:5}, 5);
|
||||
ok(false, "add with inline key and passed key should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "add with inline key and passed key threw");
|
||||
}
|
||||
|
||||
try {
|
||||
objectStore.put({});
|
||||
ok(false, "put with no key should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "put with no key threw");
|
||||
}
|
||||
|
||||
try {
|
||||
objectStore.put({});
|
||||
ok(false, "put with no key should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "put with no key threw");
|
||||
}
|
||||
|
||||
try {
|
||||
objectStore.delete();
|
||||
ok(false, "remove with no key should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "remove with no key threw");
|
||||
}
|
||||
|
||||
key1 = 10;
|
||||
|
||||
request = objectStore.add({id:key1});
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, key1, "add gave back the same key");
|
||||
|
||||
request = objectStore.put({id:10});
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, key1, "put gave back the same key");
|
||||
|
||||
request = objectStore.put({id:10});
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, key1, "put gave back the same key");
|
||||
|
||||
request = objectStore.add({id:10});
|
||||
request.addEventListener("error", new ExpectError("ConstraintError", true));
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
event = yield undefined;
|
||||
|
||||
try {
|
||||
objectStore.add({}, null);
|
||||
ok(false, "add with null key should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "add with null key threw");
|
||||
}
|
||||
|
||||
try {
|
||||
objectStore.put({}, null);
|
||||
ok(false, "put with null key should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "put with null key threw");
|
||||
}
|
||||
|
||||
try {
|
||||
objectStore.put({}, null);
|
||||
ok(false, "put with null key should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "put with null key threw");
|
||||
}
|
||||
|
||||
try {
|
||||
objectStore.delete({}, null);
|
||||
ok(false, "remove with null key should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "remove with null key threw");
|
||||
}
|
||||
|
||||
objectStore = db.createObjectStore("bazing", { keyPath: "id",
|
||||
autoIncrement: true });
|
||||
|
||||
request = objectStore.add({});
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
key1 = event.target.result;
|
||||
|
||||
request = objectStore.put({id:key1});
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, key1, "put gave the same key back");
|
||||
|
||||
key2 = 10;
|
||||
|
||||
request = objectStore.put({id:key2});
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, key2, "put gave the same key back");
|
||||
|
||||
try {
|
||||
objectStore.put({});
|
||||
ok(true, "put with no key should not throw with autoIncrement!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(false, "put with no key threw with autoIncrement");
|
||||
}
|
||||
|
||||
try {
|
||||
objectStore.put({});
|
||||
ok(true, "put with no key should not throw with autoIncrement!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(false, "put with no key threw with autoIncrement");
|
||||
}
|
||||
|
||||
try {
|
||||
objectStore.delete();
|
||||
ok(false, "remove with no key should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "remove with no key threw");
|
||||
}
|
||||
|
||||
try {
|
||||
objectStore.add({id:5}, 5);
|
||||
ok(false, "add with inline key and passed key should throw!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "add with inline key and passed key threw");
|
||||
}
|
||||
|
||||
request = objectStore.delete(key2);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
// Wait for success
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
269
dom/indexedDB/test/unit/test_keys.js
Normal file
269
dom/indexedDB/test/unit/test_keys.js
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
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 store = db.createObjectStore("store");
|
||||
|
||||
// Test simple inserts
|
||||
var keys = [
|
||||
-1/0,
|
||||
-1.7e308,
|
||||
-10000,
|
||||
-2,
|
||||
-1.5,
|
||||
-1,
|
||||
-1.00001e-200,
|
||||
-1e-200,
|
||||
0,
|
||||
1e-200,
|
||||
1.00001e-200,
|
||||
1,
|
||||
2,
|
||||
10000,
|
||||
1.7e308,
|
||||
1/0,
|
||||
new Date("1750-01-02"),
|
||||
new Date("1800-12-31T12:34:56.001"),
|
||||
new Date(-1000),
|
||||
new Date(-10),
|
||||
new Date(-1),
|
||||
new Date(0),
|
||||
new Date(1),
|
||||
new Date(2),
|
||||
new Date(1000),
|
||||
new Date("1971-01-01"),
|
||||
new Date("1971-01-01T01:01:01Z"),
|
||||
new Date("1971-01-01T01:01:01.001Z"),
|
||||
new Date("1971-01-01T01:01:01.01Z"),
|
||||
new Date("1971-01-01T01:01:01.1Z"),
|
||||
new Date("1980-02-02"),
|
||||
new Date("3333-03-19T03:33:33.333"),
|
||||
"",
|
||||
"\x00",
|
||||
"\x00\x00",
|
||||
"\x00\x01",
|
||||
"\x01",
|
||||
"\x02",
|
||||
"\x03",
|
||||
"\x04",
|
||||
"\x07",
|
||||
"\x08",
|
||||
"\x0F",
|
||||
"\x10",
|
||||
"\x1F",
|
||||
"\x20",
|
||||
"01234",
|
||||
"\x3F",
|
||||
"\x40",
|
||||
"A",
|
||||
"A\x00",
|
||||
"A1",
|
||||
"ZZZZ",
|
||||
"a",
|
||||
"a\x00",
|
||||
"aa",
|
||||
"azz",
|
||||
"}",
|
||||
"\x7E",
|
||||
"\x7F",
|
||||
"\x80",
|
||||
"\xFF",
|
||||
"\u0100",
|
||||
"\u01FF",
|
||||
"\u0200",
|
||||
"\u03FF",
|
||||
"\u0400",
|
||||
"\u07FF",
|
||||
"\u0800",
|
||||
"\u0FFF",
|
||||
"\u1000",
|
||||
"\u1FFF",
|
||||
"\u2000",
|
||||
"\u3FFF",
|
||||
"\u4000",
|
||||
"\u7FFF",
|
||||
"\u8000",
|
||||
"\uD800",
|
||||
"\uD800a",
|
||||
"\uD800\uDC01",
|
||||
"\uDBFF",
|
||||
"\uDC00",
|
||||
"\uDFFF\uD800",
|
||||
"\uFFFE",
|
||||
"\uFFFF",
|
||||
"\uFFFF\x00",
|
||||
"\uFFFFZZZ",
|
||||
[],
|
||||
[-1/0],
|
||||
[-1],
|
||||
[0],
|
||||
[1],
|
||||
[1, "a"],
|
||||
[1, []],
|
||||
[1, [""]],
|
||||
[2, 3],
|
||||
[2, 3.0000000000001],
|
||||
[12, [[]]],
|
||||
[12, [[[]]]],
|
||||
[12, [[[""]]]],
|
||||
[12, [[["foo"]]]],
|
||||
[12, [[[[[3]]]]]],
|
||||
[12, [[[[[[3]]]]]]],
|
||||
[new Date(-1)],
|
||||
[new Date(1)],
|
||||
[""],
|
||||
["", [[]]],
|
||||
["", [[[]]]],
|
||||
["abc"],
|
||||
["abc", "def"],
|
||||
["abc\x00"],
|
||||
["abc\x00", "\x00\x01"],
|
||||
["abc\x00", "\x00def"],
|
||||
["abc\x00\x00def"],
|
||||
["x", [[]]],
|
||||
["x", [[[]]]],
|
||||
[[]],
|
||||
[[],"foo"],
|
||||
[[],[]],
|
||||
[[[]]],
|
||||
[[[]], []],
|
||||
[[[]], [[]]],
|
||||
[[[]], [[1]]],
|
||||
[[[]], [[[]]]],
|
||||
[[[1]]],
|
||||
[[[[]], []]],
|
||||
];
|
||||
|
||||
for (var i = 0; i < keys.length; ++i) {
|
||||
let keyI = keys[i];
|
||||
is(indexedDB.cmp(keyI, keyI), 0, i + " compared to self");
|
||||
|
||||
function doCompare(keyI) {
|
||||
for (var j = i-1; j >= i-10 && j >= 0; --j) {
|
||||
is(indexedDB.cmp(keyI, keys[j]), 1, i + " compared to " + j);
|
||||
is(indexedDB.cmp(keys[j], keyI), -1, j + " compared to " + i);
|
||||
}
|
||||
}
|
||||
|
||||
doCompare(keyI);
|
||||
store.add(i, keyI).onsuccess = function(e) {
|
||||
is(indexedDB.cmp(e.target.result, keyI), 0,
|
||||
"Returned key should cmp as equal");
|
||||
ok(compareKeys(e.target.result, keyI),
|
||||
"Returned key should actually be equal");
|
||||
};
|
||||
|
||||
// Test that -0 compares the same as 0
|
||||
if (keyI === 0) {
|
||||
doCompare(-0);
|
||||
let req = store.add(i, -0);
|
||||
req.addEventListener("error", new ExpectError("ConstraintError", true));
|
||||
req.onsuccess = unexpectedSuccessHandler;
|
||||
yield undefined;
|
||||
}
|
||||
else if (Array.isArray(keyI) && keyI.length === 1 && keyI[0] === 0) {
|
||||
doCompare([-0]);
|
||||
let req = store.add(i, [-0]);
|
||||
req.addEventListener("error", new ExpectError("ConstraintError", true));
|
||||
req.onsuccess = unexpectedSuccessHandler;
|
||||
yield undefined;
|
||||
}
|
||||
}
|
||||
|
||||
store.openCursor().onsuccess = grabEventAndContinueHandler;
|
||||
for (i = 0; i < keys.length; ++i) {
|
||||
event = yield undefined;
|
||||
let cursor = event.target.result;
|
||||
is(indexedDB.cmp(cursor.key, keys[i]), 0,
|
||||
"Read back key should cmp as equal");
|
||||
ok(compareKeys(cursor.key, keys[i]),
|
||||
"Read back key should actually be equal");
|
||||
is(cursor.value, i, "Stored with right value");
|
||||
|
||||
cursor.continue();
|
||||
}
|
||||
event = yield undefined;
|
||||
is(event.target.result, null, "no more results expected");
|
||||
|
||||
var nan = 0/0;
|
||||
var invalidKeys = [
|
||||
nan,
|
||||
undefined,
|
||||
null,
|
||||
/x/,
|
||||
{},
|
||||
new Date(NaN),
|
||||
new Date("foopy"),
|
||||
[nan],
|
||||
[undefined],
|
||||
[null],
|
||||
[/x/],
|
||||
[{}],
|
||||
[new Date(NaN)],
|
||||
[1, nan],
|
||||
[1, undefined],
|
||||
[1, null],
|
||||
[1, /x/],
|
||||
[1, {}],
|
||||
[1, [nan]],
|
||||
[1, [undefined]],
|
||||
[1, [null]],
|
||||
[1, [/x/]],
|
||||
[1, [{}]],
|
||||
];
|
||||
|
||||
for (i = 0; i < invalidKeys.length; ++i) {
|
||||
try {
|
||||
indexedDB.cmp(invalidKeys[i], 1);
|
||||
ok(false, "didn't throw");
|
||||
}
|
||||
catch(ex) {
|
||||
ok(ex instanceof DOMException, "Threw DOMException");
|
||||
is(ex.name, "DataError", "Threw right DOMException");
|
||||
is(ex.code, 0, "Threw with right code");
|
||||
}
|
||||
try {
|
||||
indexedDB.cmp(1, invalidKeys[i]);
|
||||
ok(false, "didn't throw2");
|
||||
}
|
||||
catch(ex) {
|
||||
ok(ex instanceof DOMException, "Threw DOMException2");
|
||||
is(ex.name, "DataError", "Threw right DOMException2");
|
||||
is(ex.code, 0, "Threw with right code2");
|
||||
}
|
||||
try {
|
||||
store.put(1, invalidKeys[i]);
|
||||
ok(false, "didn't throw3");
|
||||
}
|
||||
catch(ex) {
|
||||
ok(ex instanceof DOMException, "Threw DOMException3");
|
||||
is(ex.name, "DataError", "Threw right DOMException3");
|
||||
is(ex.code, 0, "Threw with right code3");
|
||||
}
|
||||
}
|
||||
|
||||
openRequest.onsuccess = grabEventAndContinueHandler;
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
191
dom/indexedDB/test/unit/test_locale_aware_index_getAll.js
Normal file
191
dom/indexedDB/test/unit/test_locale_aware_index_getAll.js
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const objectStoreName = "People";
|
||||
|
||||
const objectStoreData = [
|
||||
{ key: "237-23-7732", value: { name: "\u00E1na", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7733", value: { name: "ana", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7734", value: { name: "fabio", height: 73, weight: 180 } },
|
||||
{ key: "237-23-7735", value: { name: "\u00F3scar", height: 58, weight: 130 } },
|
||||
{ key: "237-23-7736", value: { name: "bob", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7737", value: { name: "\u00E9ason", height: 65 } }
|
||||
];
|
||||
|
||||
const indexData = [
|
||||
{ name: "name", keyPath: "name", options: { unique: true, locale: true } },
|
||||
{ name: "height", keyPath: "height", options: { unique: false, locale: true } },
|
||||
{ name: "weight", keyPath: "weight", options: { unique: false, locale: true } }
|
||||
];
|
||||
|
||||
const objectStoreDataNameSort = [
|
||||
{ key: "237-23-7733", value: { name: "ana", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7732", value: { name: "\u00E1na", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7736", value: { name: "bob", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7737", value: { name: "\u00E9ason", height: 65 } },
|
||||
{ key: "237-23-7734", value: { name: "fabio", height: 73, weight: 180 } },
|
||||
{ key: "237-23-7735", value: { name: "\u00F3scar", height: 58, weight: 130 } }
|
||||
];
|
||||
|
||||
const objectStoreDataWeightSort = [
|
||||
{ key: "237-23-7733", value: { name: "ana", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7732", value: { name: "\u00E1na", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7735", value: { name: "\u00F3scar", height: 58, weight: 130 } },
|
||||
{ key: "237-23-7736", value: { name: "bob", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7734", value: { name: "fabio", height: 73, weight: 180 } }
|
||||
];
|
||||
|
||||
const objectStoreDataHeightSort = [
|
||||
{ key: "237-23-7733", value: { name: "ana", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7735", value: { name: "\u00F3scar", height: 58, weight: 130 } },
|
||||
{ key: "237-23-7732", value: { name: "\u00E1na", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7736", value: { name: "bob", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7737", value: { name: "\u00E9ason", height: 65 } },
|
||||
{ key: "237-23-7734", value: { name: "fabio", height: 73, weight: 180 } }
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
let objectStore = db.createObjectStore(objectStoreName);
|
||||
|
||||
// First, add all our data to the object store.
|
||||
let addedData = 0;
|
||||
for (let i in objectStoreData) {
|
||||
request = objectStore.add(objectStoreData[i].value,
|
||||
objectStoreData[i].key);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
if (++addedData == objectStoreData.length) {
|
||||
testGenerator.send(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
yield undefined;
|
||||
ok(true, "1");
|
||||
|
||||
// Now create the indexes.
|
||||
for (let i in indexData) {
|
||||
objectStore.createIndex(indexData[i].name, indexData[i].keyPath,
|
||||
indexData[i].options);
|
||||
}
|
||||
|
||||
is(objectStore.indexNames.length, indexData.length, "Good index count");
|
||||
yield undefined;
|
||||
|
||||
ok(true, "2");
|
||||
objectStore = db.transaction(objectStoreName)
|
||||
.objectStore(objectStoreName);
|
||||
|
||||
request = objectStore.index("height").mozGetAllKeys(65);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
ok(true, "3");
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
|
||||
"Correct key");
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAllKeys(65, 0);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
ok(true, "3");
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
|
||||
"Correct key");
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAllKeys(65, null);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
ok(true, "3");
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
|
||||
"Correct key");
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAllKeys(65, undefined);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
ok(true, "3");
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
|
||||
"Correct key");
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAllKeys();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
ok(true, "4");
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, objectStoreDataHeightSort.length,
|
||||
"Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], objectStoreDataHeightSort[i].key, "Correct key");
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAllKeys(null, 4);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(true, "5");
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 4, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], objectStoreDataHeightSort[i].key, "Correct key");
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAllKeys(65, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(true, "6");
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 1, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
|
||||
"Correct key");
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
233
dom/indexedDB/test/unit/test_locale_aware_index_getAllObjects.js
Normal file
233
dom/indexedDB/test/unit/test_locale_aware_index_getAllObjects.js
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const objectStoreName = "People";
|
||||
|
||||
const objectStoreData = [
|
||||
{ key: "237-23-7732", value: { name: "\u00E1na", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7733", value: { name: "ana", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7734", value: { name: "fabio", height: 73, weight: 180 } },
|
||||
{ key: "237-23-7735", value: { name: "\u00F3scar", height: 58, weight: 130 } },
|
||||
{ key: "237-23-7736", value: { name: "bob", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7737", value: { name: "\u00E9ason", height: 65 } }
|
||||
];
|
||||
|
||||
const indexData = [
|
||||
{ name: "name", keyPath: "name", options: { unique: true, locale: true } },
|
||||
{ name: "height", keyPath: "height", options: { unique: false, locale: true } },
|
||||
{ name: "weight", keyPath: "weight", options: { unique: false, locale: true } }
|
||||
];
|
||||
|
||||
const objectStoreDataNameSort = [
|
||||
{ key: "237-23-7733", value: { name: "ana", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7732", value: { name: "\u00E1na", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7736", value: { name: "bob", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7737", value: { name: "\u00E9ason", height: 65 } },
|
||||
{ key: "237-23-7734", value: { name: "fabio", height: 73, weight: 180 } },
|
||||
{ key: "237-23-7735", value: { name: "\u00F3scar", height: 58, weight: 130 } }
|
||||
];
|
||||
|
||||
const objectStoreDataWeightSort = [
|
||||
{ key: "237-23-7733", value: { name: "ana", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7732", value: { name: "\u00E1na", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7735", value: { name: "\u00F3scar", height: 58, weight: 130 } },
|
||||
{ key: "237-23-7736", value: { name: "bob", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7734", value: { name: "fabio", height: 73, weight: 180 } }
|
||||
];
|
||||
|
||||
const objectStoreDataHeightSort = [
|
||||
{ key: "237-23-7733", value: { name: "ana", height: 52, weight: 110 } },
|
||||
{ key: "237-23-7735", value: { name: "\u00F3scar", height: 58, weight: 130 } },
|
||||
{ key: "237-23-7732", value: { name: "\u00E1na", height: 60, weight: 120 } },
|
||||
{ key: "237-23-7736", value: { name: "bob", height: 65, weight: 150 } },
|
||||
{ key: "237-23-7737", value: { name: "\u00E9ason", height: 65 } },
|
||||
{ key: "237-23-7734", value: { name: "fabio", height: 73, weight: 180 } }
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
let objectStore = db.createObjectStore(objectStoreName, {});
|
||||
|
||||
// First, add all our data to the object store.
|
||||
let addedData = 0;
|
||||
for (let i in objectStoreData) {
|
||||
request = objectStore.add(objectStoreData[i].value,
|
||||
objectStoreData[i].key);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
if (++addedData == objectStoreData.length) {
|
||||
testGenerator.send(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
event = yield undefined;
|
||||
|
||||
// Now create the indexes.
|
||||
for (let i in indexData) {
|
||||
objectStore.createIndex(indexData[i].name, indexData[i].keyPath,
|
||||
indexData[i].options);
|
||||
}
|
||||
|
||||
is(objectStore.indexNames.length, indexData.length, "Good index count");
|
||||
yield undefined;
|
||||
|
||||
objectStore = db.transaction(objectStoreName)
|
||||
.objectStore(objectStoreName);
|
||||
|
||||
request = objectStore.index("height").mozGetAll(65);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
let result = event.target.result[i];
|
||||
let testObj = objectStoreDataHeightSort[parseInt(i) + 3].value;
|
||||
|
||||
is(result.name, testObj.name, "Correct name");
|
||||
is(result.height, testObj.height, "Correct height");
|
||||
|
||||
if (testObj.hasOwnProperty("weight")) {
|
||||
is(result.weight, testObj.weight, "Correct weight");
|
||||
}
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAll(65, 0);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
let result = event.target.result[i];
|
||||
let testObj = objectStoreDataHeightSort[parseInt(i) + 3].value;
|
||||
|
||||
is(result.name, testObj.name, "Correct name");
|
||||
is(result.height, testObj.height, "Correct height");
|
||||
|
||||
if (testObj.hasOwnProperty("weight")) {
|
||||
is(result.weight, testObj.weight, "Correct weight");
|
||||
}
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAll(65, null);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
let result = event.target.result[i];
|
||||
let testObj = objectStoreDataHeightSort[parseInt(i) + 3].value;
|
||||
|
||||
is(result.name, testObj.name, "Correct name");
|
||||
is(result.height, testObj.height, "Correct height");
|
||||
|
||||
if (testObj.hasOwnProperty("weight")) {
|
||||
is(result.weight, testObj.weight, "Correct weight");
|
||||
}
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAll(65, undefined);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 2, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
let result = event.target.result[i];
|
||||
let testObj = objectStoreDataHeightSort[parseInt(i) + 3].value;
|
||||
|
||||
is(result.name, testObj.name, "Correct name");
|
||||
is(result.height, testObj.height, "Correct height");
|
||||
|
||||
if (testObj.hasOwnProperty("weight")) {
|
||||
is(result.weight, testObj.weight, "Correct weight");
|
||||
}
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAll();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, objectStoreDataHeightSort.length,
|
||||
"Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
let result = event.target.result[i];
|
||||
let testObj = objectStoreDataHeightSort[i].value;
|
||||
|
||||
is(result.name, testObj.name, "Correct name");
|
||||
is(result.height, testObj.height, "Correct height");
|
||||
|
||||
if (testObj.hasOwnProperty("weight")) {
|
||||
is(result.weight, testObj.weight, "Correct weight");
|
||||
}
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAll(null, 4);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 4, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
let result = event.target.result[i];
|
||||
let testObj = objectStoreDataHeightSort[i].value;
|
||||
|
||||
is(result.name, testObj.name, "Correct name");
|
||||
is(result.height, testObj.height, "Correct height");
|
||||
|
||||
if (testObj.hasOwnProperty("weight")) {
|
||||
is(result.weight, testObj.weight, "Correct weight");
|
||||
}
|
||||
}
|
||||
|
||||
request = objectStore.index("height").mozGetAll(65, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result instanceof Array, true, "Got an array object");
|
||||
is(event.target.result.length, 1, "Correct length");
|
||||
|
||||
for (let i in event.target.result) {
|
||||
let result = event.target.result[i];
|
||||
let testObj = objectStoreDataHeightSort[parseInt(i) + 3].value;
|
||||
|
||||
is(result.name, testObj.name, "Correct name");
|
||||
is(result.height, testObj.height, "Correct height");
|
||||
|
||||
if (testObj.hasOwnProperty("weight")) {
|
||||
is(result.weight, testObj.weight, "Correct weight");
|
||||
}
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
1268
dom/indexedDB/test/unit/test_locale_aware_indexes.js
Normal file
1268
dom/indexedDB/test/unit/test_locale_aware_indexes.js
Normal file
File diff suppressed because it is too large
Load diff
754
dom/indexedDB/test/unit/test_lowDiskSpace.js
Normal file
754
dom/indexedDB/test/unit/test_lowDiskSpace.js
Normal file
|
|
@ -0,0 +1,754 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
var disableWorkerTest = "This test uses SpecialPowers";
|
||||
|
||||
var self = this;
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const dbName = self.window ? window.location.pathname : "test_lowDiskSpace";
|
||||
const dbVersion = 1;
|
||||
|
||||
const objectStoreName = "foo";
|
||||
const objectStoreOptions = { keyPath: "foo" };
|
||||
|
||||
const indexName = "bar";
|
||||
const indexOptions = { unique: true };
|
||||
|
||||
const dbData = [
|
||||
{ foo: 0, bar: 0 },
|
||||
{ foo: 1, bar: 10 },
|
||||
{ foo: 2, bar: 20 },
|
||||
{ foo: 3, bar: 30 },
|
||||
{ foo: 4, bar: 40 },
|
||||
{ foo: 5, bar: 50 },
|
||||
{ foo: 6, bar: 60 },
|
||||
{ foo: 7, bar: 70 },
|
||||
{ foo: 8, bar: 80 },
|
||||
{ foo: 9, bar: 90 }
|
||||
];
|
||||
|
||||
let lowDiskMode = false;
|
||||
function setLowDiskMode(val) {
|
||||
let data = val ? "full" : "free";
|
||||
|
||||
if (val == lowDiskMode) {
|
||||
info("Low disk mode is: " + data);
|
||||
}
|
||||
else {
|
||||
info("Changing low disk mode to: " + data);
|
||||
SpecialPowers.notifyObserversInParentProcess(null, "disk-space-watcher",
|
||||
data);
|
||||
lowDiskMode = val;
|
||||
}
|
||||
}
|
||||
|
||||
{ // Make sure opening works from the beginning.
|
||||
info("Test 1");
|
||||
|
||||
setLowDiskMode(false);
|
||||
|
||||
let request = indexedDB.open(dbName, dbVersion);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Opened database without setting low disk mode");
|
||||
|
||||
let db = event.target.result;
|
||||
db.close();
|
||||
}
|
||||
|
||||
{ // Make sure delete works in low disk mode.
|
||||
info("Test 2");
|
||||
|
||||
setLowDiskMode(true);
|
||||
|
||||
let request = indexedDB.deleteDatabase(dbName);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Deleted database after setting low disk mode");
|
||||
}
|
||||
|
||||
{ // Make sure creating a db in low disk mode fails.
|
||||
info("Test 3");
|
||||
|
||||
setLowDiskMode(true);
|
||||
|
||||
let request = indexedDB.open(dbName, dbVersion);
|
||||
request.onerror = expectedErrorHandler("QuotaExceededError");
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "error", "Didn't create new database in low disk mode");
|
||||
}
|
||||
|
||||
{ // Make sure opening an already-existing db in low disk mode succeeds.
|
||||
info("Test 4");
|
||||
|
||||
setLowDiskMode(false);
|
||||
|
||||
let request = indexedDB.open(dbName, dbVersion);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Upgrading database");
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Created database");
|
||||
ok(event.target.result === db, "Got the same database");
|
||||
|
||||
db.close();
|
||||
|
||||
setLowDiskMode(true);
|
||||
|
||||
request = indexedDB.open(dbName);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Opened existing database in low disk mode");
|
||||
|
||||
db = event.target.result;
|
||||
db.close();
|
||||
}
|
||||
|
||||
{ // Make sure upgrading an already-existing db in low disk mode succeeds.
|
||||
info("Test 5");
|
||||
|
||||
setLowDiskMode(true);
|
||||
|
||||
let request = indexedDB.open(dbName, dbVersion + 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Upgrading database");
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Created database");
|
||||
ok(event.target.result === db, "Got the same database");
|
||||
|
||||
db.close();
|
||||
}
|
||||
|
||||
{ // Make sure creating objectStores in low disk mode fails.
|
||||
info("Test 6");
|
||||
|
||||
setLowDiskMode(true);
|
||||
|
||||
let request = indexedDB.open(dbName, dbVersion + 2);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Upgrading database");
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
let txn = event.target.transaction;
|
||||
txn.onerror = expectedErrorHandler("AbortError");
|
||||
txn.onabort = grabEventAndContinueHandler;
|
||||
|
||||
let objectStore = db.createObjectStore(objectStoreName, objectStoreOptions);
|
||||
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "abort", "Got correct event type");
|
||||
is(event.target.error.name, "QuotaExceededError", "Got correct error type");
|
||||
|
||||
request.onerror = expectedErrorHandler("AbortError");
|
||||
event = yield undefined;
|
||||
}
|
||||
|
||||
{ // Make sure creating indexes in low disk mode fails.
|
||||
info("Test 7");
|
||||
|
||||
setLowDiskMode(false);
|
||||
|
||||
let request = indexedDB.open(dbName, dbVersion + 2);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Upgrading database");
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
let objectStore = db.createObjectStore(objectStoreName, objectStoreOptions);
|
||||
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Upgraded database");
|
||||
ok(event.target.result === db, "Got the same database");
|
||||
|
||||
db.close();
|
||||
|
||||
setLowDiskMode(true);
|
||||
|
||||
request = indexedDB.open(dbName, dbVersion + 3);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Upgrading database");
|
||||
|
||||
db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
let txn = event.target.transaction;
|
||||
txn.onerror = expectedErrorHandler("AbortError");
|
||||
txn.onabort = grabEventAndContinueHandler;
|
||||
|
||||
objectStore = event.target.transaction.objectStore(objectStoreName);
|
||||
let index = objectStore.createIndex(indexName, indexName, indexOptions);
|
||||
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "abort", "Got correct event type");
|
||||
is(event.target.error.name, "QuotaExceededError", "Got correct error type");
|
||||
|
||||
request.onerror = expectedErrorHandler("AbortError");
|
||||
event = yield undefined;
|
||||
}
|
||||
|
||||
{ // Make sure deleting indexes in low disk mode succeeds.
|
||||
info("Test 8");
|
||||
|
||||
setLowDiskMode(false);
|
||||
|
||||
let request = indexedDB.open(dbName, dbVersion + 3);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Upgrading database");
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
let objectStore = event.target.transaction.objectStore(objectStoreName);
|
||||
let index = objectStore.createIndex(indexName, indexName, indexOptions);
|
||||
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Upgraded database");
|
||||
ok(event.target.result === db, "Got the same database");
|
||||
|
||||
db.close();
|
||||
|
||||
setLowDiskMode(true);
|
||||
|
||||
request = indexedDB.open(dbName, dbVersion + 4);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Upgrading database");
|
||||
|
||||
db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
objectStore = event.target.transaction.objectStore(objectStoreName);
|
||||
objectStore.deleteIndex(indexName);
|
||||
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Upgraded database");
|
||||
ok(event.target.result === db, "Got the same database");
|
||||
|
||||
db.close();
|
||||
}
|
||||
|
||||
{ // Make sure deleting objectStores in low disk mode succeeds.
|
||||
info("Test 9");
|
||||
|
||||
setLowDiskMode(true);
|
||||
|
||||
let request = indexedDB.open(dbName, dbVersion + 5);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Upgrading database");
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
db.deleteObjectStore(objectStoreName);
|
||||
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Upgraded database");
|
||||
ok(event.target.result === db, "Got the same database");
|
||||
|
||||
db.close();
|
||||
|
||||
// Reset everything.
|
||||
indexedDB.deleteDatabase(dbName);
|
||||
}
|
||||
|
||||
|
||||
{ // Add data that the rest of the tests will use.
|
||||
info("Adding test data");
|
||||
|
||||
setLowDiskMode(false);
|
||||
|
||||
let request = indexedDB.open(dbName, dbVersion);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Upgrading database");
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
let objectStore = db.createObjectStore(objectStoreName, objectStoreOptions);
|
||||
let index = objectStore.createIndex(indexName, indexName, indexOptions);
|
||||
|
||||
for (let data of dbData) {
|
||||
objectStore.add(data);
|
||||
}
|
||||
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Upgraded database");
|
||||
ok(event.target.result === db, "Got the same database");
|
||||
|
||||
db.close();
|
||||
}
|
||||
|
||||
{ // Make sure read operations in readonly transactions succeed in low disk
|
||||
// mode.
|
||||
info("Test 10");
|
||||
|
||||
setLowDiskMode(true);
|
||||
|
||||
let request = indexedDB.open(dbName, dbVersion);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
let transaction = db.transaction(objectStoreName);
|
||||
let objectStore = transaction.objectStore(objectStoreName);
|
||||
let index = objectStore.index(indexName);
|
||||
|
||||
let data = dbData[0];
|
||||
|
||||
let requestCounter = new RequestCounter();
|
||||
|
||||
objectStore.get(data.foo).onsuccess = requestCounter.handler();
|
||||
objectStore.mozGetAll().onsuccess = requestCounter.handler();
|
||||
objectStore.count().onsuccess = requestCounter.handler();
|
||||
index.get(data.bar).onsuccess = requestCounter.handler();
|
||||
index.mozGetAll().onsuccess = requestCounter.handler();
|
||||
index.getKey(data.bar).onsuccess = requestCounter.handler();
|
||||
index.mozGetAllKeys().onsuccess = requestCounter.handler();
|
||||
index.count().onsuccess = requestCounter.handler();
|
||||
|
||||
let objectStoreDataCount = 0;
|
||||
|
||||
request = objectStore.openCursor();
|
||||
request.onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
objectStoreDataCount++;
|
||||
objectStoreDataCount % 2 ? cursor.continue() : cursor.advance(1);
|
||||
}
|
||||
else {
|
||||
is(objectStoreDataCount, dbData.length, "Saw all data");
|
||||
requestCounter.decr();
|
||||
}
|
||||
};
|
||||
requestCounter.incr();
|
||||
|
||||
let indexDataCount = 0;
|
||||
|
||||
request = index.openCursor();
|
||||
request.onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
indexDataCount++;
|
||||
indexDataCount % 2 ? cursor.continue() : cursor.advance(1);
|
||||
}
|
||||
else {
|
||||
is(indexDataCount, dbData.length, "Saw all data");
|
||||
requestCounter.decr();
|
||||
}
|
||||
};
|
||||
requestCounter.incr();
|
||||
|
||||
let indexKeyDataCount = 0;
|
||||
|
||||
request = index.openCursor();
|
||||
request.onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
indexKeyDataCount++;
|
||||
indexKeyDataCount % 2 ? cursor.continue() : cursor.advance(1);
|
||||
}
|
||||
else {
|
||||
is(indexKeyDataCount, dbData.length, "Saw all data");
|
||||
requestCounter.decr();
|
||||
}
|
||||
};
|
||||
requestCounter.incr();
|
||||
|
||||
// Wait for all requests.
|
||||
yield undefined;
|
||||
|
||||
transaction.oncomplete = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "complete", "Transaction succeeded");
|
||||
|
||||
db.close();
|
||||
}
|
||||
|
||||
{ // Make sure read operations in readwrite transactions succeed in low disk
|
||||
// mode.
|
||||
info("Test 11");
|
||||
|
||||
setLowDiskMode(true);
|
||||
|
||||
let request = indexedDB.open(dbName, dbVersion);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
let transaction = db.transaction(objectStoreName, "readwrite");
|
||||
let objectStore = transaction.objectStore(objectStoreName);
|
||||
let index = objectStore.index(indexName);
|
||||
|
||||
let data = dbData[0];
|
||||
|
||||
let requestCounter = new RequestCounter();
|
||||
|
||||
objectStore.get(data.foo).onsuccess = requestCounter.handler();
|
||||
objectStore.mozGetAll().onsuccess = requestCounter.handler();
|
||||
objectStore.count().onsuccess = requestCounter.handler();
|
||||
index.get(data.bar).onsuccess = requestCounter.handler();
|
||||
index.mozGetAll().onsuccess = requestCounter.handler();
|
||||
index.getKey(data.bar).onsuccess = requestCounter.handler();
|
||||
index.mozGetAllKeys().onsuccess = requestCounter.handler();
|
||||
index.count().onsuccess = requestCounter.handler();
|
||||
|
||||
let objectStoreDataCount = 0;
|
||||
|
||||
request = objectStore.openCursor();
|
||||
request.onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
objectStoreDataCount++;
|
||||
objectStoreDataCount % 2 ? cursor.continue() : cursor.advance(1);
|
||||
}
|
||||
else {
|
||||
is(objectStoreDataCount, dbData.length, "Saw all data");
|
||||
requestCounter.decr();
|
||||
}
|
||||
};
|
||||
requestCounter.incr();
|
||||
|
||||
let indexDataCount = 0;
|
||||
|
||||
request = index.openCursor();
|
||||
request.onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
indexDataCount++;
|
||||
indexDataCount % 2 ? cursor.continue() : cursor.advance(1);
|
||||
}
|
||||
else {
|
||||
is(indexDataCount, dbData.length, "Saw all data");
|
||||
requestCounter.decr();
|
||||
}
|
||||
};
|
||||
requestCounter.incr();
|
||||
|
||||
let indexKeyDataCount = 0;
|
||||
|
||||
request = index.openCursor();
|
||||
request.onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
indexKeyDataCount++;
|
||||
indexKeyDataCount % 2 ? cursor.continue() : cursor.advance(1);
|
||||
}
|
||||
else {
|
||||
is(indexKeyDataCount, dbData.length, "Saw all data");
|
||||
requestCounter.decr();
|
||||
}
|
||||
};
|
||||
requestCounter.incr();
|
||||
|
||||
// Wait for all requests.
|
||||
yield undefined;
|
||||
|
||||
transaction.oncomplete = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "complete", "Transaction succeeded");
|
||||
|
||||
db.close();
|
||||
}
|
||||
|
||||
{ // Make sure write operations in readwrite transactions fail in low disk
|
||||
// mode.
|
||||
info("Test 12");
|
||||
|
||||
setLowDiskMode(true);
|
||||
|
||||
let request = indexedDB.open(dbName, dbVersion);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
let transaction = db.transaction(objectStoreName, "readwrite");
|
||||
let objectStore = transaction.objectStore(objectStoreName);
|
||||
let index = objectStore.index(indexName);
|
||||
|
||||
let data = dbData[0];
|
||||
let newData = { foo: 999, bar: 999 };
|
||||
|
||||
let requestCounter = new RequestCounter();
|
||||
|
||||
objectStore.add(newData).onerror = requestCounter.errorHandler();
|
||||
objectStore.put(newData).onerror = requestCounter.errorHandler();
|
||||
|
||||
objectStore.get(data.foo).onsuccess = requestCounter.handler();
|
||||
objectStore.mozGetAll().onsuccess = requestCounter.handler();
|
||||
objectStore.count().onsuccess = requestCounter.handler();
|
||||
index.get(data.bar).onsuccess = requestCounter.handler();
|
||||
index.mozGetAll().onsuccess = requestCounter.handler();
|
||||
index.getKey(data.bar).onsuccess = requestCounter.handler();
|
||||
index.mozGetAllKeys().onsuccess = requestCounter.handler();
|
||||
index.count().onsuccess = requestCounter.handler();
|
||||
|
||||
let objectStoreDataCount = 0;
|
||||
|
||||
request = objectStore.openCursor();
|
||||
request.onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
objectStoreDataCount++;
|
||||
cursor.update(cursor.value).onerror = requestCounter.errorHandler();
|
||||
objectStoreDataCount % 2 ? cursor.continue() : cursor.advance(1);
|
||||
}
|
||||
else {
|
||||
is(objectStoreDataCount, dbData.length, "Saw all data");
|
||||
requestCounter.decr();
|
||||
}
|
||||
};
|
||||
requestCounter.incr();
|
||||
|
||||
let indexDataCount = 0;
|
||||
|
||||
request = index.openCursor();
|
||||
request.onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
indexDataCount++;
|
||||
cursor.update(cursor.value).onerror = requestCounter.errorHandler();
|
||||
indexDataCount % 2 ? cursor.continue() : cursor.advance(1);
|
||||
}
|
||||
else {
|
||||
is(indexDataCount, dbData.length, "Saw all data");
|
||||
requestCounter.decr();
|
||||
}
|
||||
};
|
||||
requestCounter.incr();
|
||||
|
||||
let indexKeyDataCount = 0;
|
||||
|
||||
request = index.openCursor();
|
||||
request.onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
indexKeyDataCount++;
|
||||
cursor.update(cursor.value).onerror = requestCounter.errorHandler();
|
||||
indexKeyDataCount % 2 ? cursor.continue() : cursor.advance(1);
|
||||
}
|
||||
else {
|
||||
is(indexKeyDataCount, dbData.length, "Saw all data");
|
||||
requestCounter.decr();
|
||||
}
|
||||
};
|
||||
requestCounter.incr();
|
||||
|
||||
// Wait for all requests.
|
||||
yield undefined;
|
||||
|
||||
transaction.oncomplete = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "complete", "Transaction succeeded");
|
||||
|
||||
db.close();
|
||||
}
|
||||
|
||||
{ // Make sure deleting operations in readwrite transactions succeed in low
|
||||
// disk mode.
|
||||
info("Test 13");
|
||||
|
||||
setLowDiskMode(true);
|
||||
|
||||
let request = indexedDB.open(dbName, dbVersion);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
let transaction = db.transaction(objectStoreName, "readwrite");
|
||||
let objectStore = transaction.objectStore(objectStoreName);
|
||||
let index = objectStore.index(indexName);
|
||||
|
||||
let dataIndex = 0;
|
||||
let data = dbData[dataIndex++];
|
||||
|
||||
let requestCounter = new RequestCounter();
|
||||
|
||||
objectStore.delete(data.foo).onsuccess = requestCounter.handler();
|
||||
|
||||
objectStore.openCursor().onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
cursor.delete().onsuccess = requestCounter.handler();
|
||||
}
|
||||
requestCounter.decr();
|
||||
};
|
||||
requestCounter.incr();
|
||||
|
||||
index.openCursor(null, "prev").onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
cursor.delete().onsuccess = requestCounter.handler();
|
||||
}
|
||||
requestCounter.decr();
|
||||
};
|
||||
requestCounter.incr();
|
||||
|
||||
yield undefined;
|
||||
|
||||
objectStore.count().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, dbData.length - 3, "Actually deleted something");
|
||||
|
||||
objectStore.clear();
|
||||
objectStore.count().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, 0, "Actually cleared");
|
||||
|
||||
transaction.oncomplete = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "complete", "Transaction succeeded");
|
||||
|
||||
db.close();
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
function RequestCounter(expectedType) {
|
||||
this._counter = 0;
|
||||
}
|
||||
RequestCounter.prototype = {
|
||||
incr: function() {
|
||||
this._counter++;
|
||||
},
|
||||
|
||||
decr: function() {
|
||||
if (!--this._counter) {
|
||||
continueToNextStepSync();
|
||||
}
|
||||
},
|
||||
|
||||
handler: function(type, preventDefault) {
|
||||
this.incr();
|
||||
return function(event) {
|
||||
is(event.type, type || "success", "Correct type");
|
||||
this.decr();
|
||||
}.bind(this);
|
||||
},
|
||||
|
||||
errorHandler: function(eventType, errorName) {
|
||||
this.incr();
|
||||
return function(event) {
|
||||
is(event.type, eventType || "error", "Correct type");
|
||||
is(event.target.error.name, errorName || "QuotaExceededError",
|
||||
"Correct error name");
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.decr();
|
||||
}.bind(this);
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var disableWorkerTest = "Need a way to set temporary prefs from a worker";
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ?
|
||||
window.location.pathname : "test_maximal_serialized_object_size.js";
|
||||
const megaBytes = 1024 * 1024;
|
||||
const kMessageOverhead = 1; // in MB
|
||||
const kMaxIpcMessageSize = 20; // in MB
|
||||
const kMaxIdbMessageSize = kMaxIpcMessageSize - kMessageOverhead;
|
||||
|
||||
let chunks = new Array(kMaxIdbMessageSize);
|
||||
for (let i = 0; i < kMaxIdbMessageSize; i++) {
|
||||
chunks[i] = new ArrayBuffer(1 * megaBytes);
|
||||
}
|
||||
|
||||
if (this.window) {
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{ "set": [["dom.indexedDB.maxSerializedMsgSize",
|
||||
kMaxIpcMessageSize * megaBytes ]]
|
||||
},
|
||||
continueToNextStep
|
||||
);
|
||||
yield undefined;
|
||||
} else {
|
||||
setMaxSerializedMsgSize(kMaxIpcMessageSize * megaBytes);
|
||||
}
|
||||
|
||||
let openRequest = indexedDB.open(name, 1);
|
||||
openRequest.onerror = errorHandler;
|
||||
openRequest.onupgradeneeded = grabEventAndContinueHandler;
|
||||
openRequest.onsuccess = unexpectedSuccessHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
let txn = event.target.transaction;
|
||||
|
||||
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
|
||||
|
||||
let objectStore = db.createObjectStore("test store", { keyPath: "id" });
|
||||
is(db.objectStoreNames.length, 1, "Correct objectStoreNames list");
|
||||
is(db.objectStoreNames.item(0), objectStore.name, "Correct object store name");
|
||||
|
||||
function testTooLargeError(aOperation, aObject) {
|
||||
try {
|
||||
objectStore[aOperation](aObject).onerror = errorHandler;
|
||||
ok(false, "UnknownError is expected to be thrown!");
|
||||
} catch (e) {
|
||||
ok(e instanceof DOMException, "got a DOM exception");
|
||||
is(e.name, "UnknownError", "correct error");
|
||||
ok(!!e.message, "Error message: " + e.message);
|
||||
ok(e.message.startsWith("The serialized value is too large"),
|
||||
"Correct error message prefix.");
|
||||
}
|
||||
}
|
||||
|
||||
info("Verify IDBObjectStore.add() - object is too large");
|
||||
testTooLargeError("add", { id: 1, data: chunks });
|
||||
|
||||
info("Verify IDBObjectStore.add() - object size is closed to the maximal size.");
|
||||
chunks.length = chunks.length - 1;
|
||||
let request = objectStore.add({ id: 1, data: chunks });
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
yield undefined;
|
||||
|
||||
info("Verify IDBObjectStore.add() - object key is too large");
|
||||
chunks.length = 10;
|
||||
testTooLargeError("add", { id: chunks });
|
||||
|
||||
objectStore.createIndex("index name", "index");
|
||||
ok(objectStore.index("index name"), "Index created.");
|
||||
|
||||
info("Verify IDBObjectStore.add() - index key is too large");
|
||||
testTooLargeError("add", { id: 2, index: chunks });
|
||||
|
||||
info("Verify IDBObjectStore.add() - object key and index key are too large");
|
||||
let indexChunks = chunks.splice(0, 5);
|
||||
testTooLargeError("add", { id: chunks, index: indexChunks });
|
||||
|
||||
openRequest.onsuccess = continueToNextStep;
|
||||
yield undefined;
|
||||
|
||||
db.close();
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
268
dom/indexedDB/test/unit/test_metadata2Restore.js
Normal file
268
dom/indexedDB/test/unit/test_metadata2Restore.js
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const openParams = [
|
||||
// This one lives in storage/permanent/chrome
|
||||
// The .metadata-v2 file was intentionally removed for this origin directory
|
||||
// to test restoring.
|
||||
{ dbName: "dbA",
|
||||
dbOptions: { version: 1, storage: "persistent" } },
|
||||
|
||||
// This one lives in storage/temporary/http+++localhost
|
||||
// The .metadata-v2 file was intentionally removed for this origin directory
|
||||
// to test restoring.
|
||||
{ url: "http://localhost", dbName: "dbB",
|
||||
dbOptions: { version: 1, storage: "temporary" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+81^userContextId=1
|
||||
// The .metadata-v2 file was intentionally removed for this origin directory
|
||||
// to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:81", dbName: "dbC",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+82^userContextId=1
|
||||
// The .metadata-v2 file was intentionally truncated for this origin directory
|
||||
// to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:82", dbName: "dbD",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+83^userContextId=1
|
||||
// The .metadata-v2 file was intentionally modified to contain only
|
||||
// 4 bytes of the 64 bit timestamp
|
||||
// for this origin directory to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:83", dbName: "dbE",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+84^userContextId=1
|
||||
// The .metadata-v2 file was intentionally modified to contain only
|
||||
// the 64 bit timestamp
|
||||
// for this origin directory to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:84", dbName: "dbF",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+85^userContextId=1
|
||||
// The .metadata-v2 file was intentionally modified to contain only
|
||||
// the 64 bit timestamp and
|
||||
// the 8 bit persisted flag
|
||||
// for this origin directory to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:85", dbName: "dbG",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+86^userContextId=1
|
||||
// The .metadata-v2 file was intentionally modified to contain only
|
||||
// the 64 bit timestamp,
|
||||
// the 8 bit persisted flag and
|
||||
// 2 bytes of the 32 bit reserved data 1
|
||||
// for this origin directory to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:86", dbName: "dbH",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+87^userContextId=1
|
||||
// The .metadata-v2 file was intentionally modified to contain only
|
||||
// the 64 bit timestamp,
|
||||
// the 8 bit persisted flag and
|
||||
// the 32 bit reserved data 1
|
||||
// for this origin directory to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:87", dbName: "dbI",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+88^userContextId=1
|
||||
// The .metadata-v2 file was intentionally modified to contain only
|
||||
// the 64 bit timestamp,
|
||||
// the 8 bit persisted flag,
|
||||
// the 32 bit reserved data 1 and
|
||||
// 2 bytes of the 32 bit reserved data 2
|
||||
// for this origin directory to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:88", dbName: "dbJ",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+89^userContextId=1
|
||||
// The .metadata-v2 file was intentionally modified to contain only
|
||||
// the 64 bit timestamp,
|
||||
// the 8 bit persisted flag,
|
||||
// the 32 bit reserved data 1 and
|
||||
// the 32 bit reserved data 2
|
||||
// for this origin directory to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:89", dbName: "dbK",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+90^userContextId=1
|
||||
// The .metadata-v2 file was intentionally modified to contain only
|
||||
// the 64 bit timestamp,
|
||||
// the 8 bit persisted flag,
|
||||
// the 32 bit reserved data 1,
|
||||
// the 32 bit reserved data 2 and
|
||||
// 2 bytes of the 32 bit suffix length
|
||||
// for this origin directory to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:90", dbName: "dbL",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+91^userContextId=1
|
||||
// The .metadata-v2 file was intentionally modified to contain only
|
||||
// the 64 bit timestamp,
|
||||
// the 8 bit persisted flag,
|
||||
// the 32 bit reserved data 1,
|
||||
// the 32 bit reserved data 2,
|
||||
// the 32 bit suffix length and
|
||||
// first 5 chars of the suffix
|
||||
// for this origin directory to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:91", dbName: "dbM",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+92^userContextId=1
|
||||
// The .metadata-v2 file was intentionally modified to contain only
|
||||
// the 64 bit timestamp,
|
||||
// the 8 bit persisted flag,
|
||||
// the 32 bit reserved data 1,
|
||||
// the 32 bit reserved data 2,
|
||||
// the 32 bit suffix length and
|
||||
// the suffix
|
||||
// for this origin directory to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:92", dbName: "dbN",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+93^userContextId=1
|
||||
// The .metadata-v2 file was intentionally modified to contain only
|
||||
// the 64 bit timestamp,
|
||||
// the 8 bit persisted flag,
|
||||
// the 32 bit reserved data 1,
|
||||
// the 32 bit reserved data 2,
|
||||
// the 32 bit suffix length,
|
||||
// the suffix and
|
||||
// 2 bytes of the 32 bit group length
|
||||
// for this origin directory to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:93", dbName: "dbO",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+94^userContextId=1
|
||||
// The .metadata-v2 file was intentionally modified to contain only
|
||||
// the 64 bit timestamp,
|
||||
// the 8 bit persisted flag,
|
||||
// the 32 bit reserved data 1,
|
||||
// the 32 bit reserved data 2,
|
||||
// the 32 bit suffix length,
|
||||
// the suffix,
|
||||
// the 32 bit group length and
|
||||
// first 5 chars of the group
|
||||
// for this origin directory to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:94", dbName: "dbP",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+95^userContextId=1
|
||||
// The .metadata-v2 file was intentionally modified to contain only
|
||||
// the 64 bit timestamp,
|
||||
// the 8 bit persisted flag,
|
||||
// the 32 bit reserved data 1,
|
||||
// the 32 bit reserved data 2,
|
||||
// the 32 bit suffix length,
|
||||
// the suffix,
|
||||
// the 32 bit group length and
|
||||
// the group
|
||||
// for this origin directory to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:95", dbName: "dbQ",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+96^userContextId=1
|
||||
// The .metadata-v2 file was intentionally modified to contain only
|
||||
// the 64 bit timestamp,
|
||||
// the 8 bit persisted flag,
|
||||
// the 32 bit reserved data 1,
|
||||
// the 32 bit reserved data 2,
|
||||
// the 32 bit suffix length,
|
||||
// the suffix,
|
||||
// the 32 bit group length,
|
||||
// the group and
|
||||
// 2 bytes of the 32 bit origin length
|
||||
// for this origin directory to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:96", dbName: "dbR",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+97^userContextId=1
|
||||
// The .metadata-v2 file was intentionally modified to contain only
|
||||
// the 64 bit timestamp,
|
||||
// the 8 bit persisted flag,
|
||||
// the 32 bit reserved data 1,
|
||||
// the 32 bit reserved data 2,
|
||||
// the 32 bit suffix length,
|
||||
// the suffix,
|
||||
// the 32 bit group length,
|
||||
// the group,
|
||||
// the 32 bit origin length and
|
||||
// first 12 char of the origin
|
||||
// for this origin directory to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:97", dbName: "dbS",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+98^userContextId=1
|
||||
// The .metadata-v2 file was intentionally modified to contain only
|
||||
// the 64 bit timestamp,
|
||||
// the 8 bit persisted flag,
|
||||
// the 32 bit reserved data 1,
|
||||
// the 32 bit reserved data 2,
|
||||
// the 32 bit suffix length,
|
||||
// the suffix,
|
||||
// the 32 bit group length,
|
||||
// the group,
|
||||
// the 32 bit origin length and
|
||||
// the origin
|
||||
// for this origin directory to test restoring.
|
||||
{ attrs: { userContextId: 1 }, url: "http://localhost:98", dbName: "dbT",
|
||||
dbOptions: { version: 1, storage: "default" } }
|
||||
];
|
||||
|
||||
let ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(SpecialPowers.Ci.nsIIOService);
|
||||
|
||||
let ssm = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(SpecialPowers.Ci.nsIScriptSecurityManager);
|
||||
|
||||
function openDatabase(params) {
|
||||
let request;
|
||||
if ("url" in params) {
|
||||
let uri = ios.newURI(params.url, null, null);
|
||||
let principal = ssm.createCodebasePrincipal(uri, params.attrs || {});
|
||||
request = indexedDB.openForPrincipal(principal, params.dbName,
|
||||
params.dbOptions);
|
||||
} else {
|
||||
request = indexedDB.open(params.dbName, params.dbOptions);
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
clearAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
installPackagedProfile("metadata2Restore_profile");
|
||||
|
||||
for (let params of openParams) {
|
||||
let request = openDatabase(params);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Correct event type");
|
||||
}
|
||||
|
||||
resetAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
for (let params of openParams) {
|
||||
let request = openDatabase(params);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Correct event type");
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
109
dom/indexedDB/test/unit/test_metadataRestore.js
Normal file
109
dom/indexedDB/test/unit/test_metadataRestore.js
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const openParams = [
|
||||
// This one lives in storage/permanent/chrome
|
||||
{ dbName: "dbA",
|
||||
dbOptions: { version: 1, storage: "persistent" } },
|
||||
|
||||
// This one lives in storage/temporary/http+++localhost
|
||||
{ url: "http://localhost", dbName: "dbB",
|
||||
dbOptions: { version: 1, storage: "temporary" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+81
|
||||
{ url: "http://localhost:81", dbName: "dbC",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+82
|
||||
{ url: "http://localhost:82", dbName: "dbD",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+83
|
||||
{ url: "http://localhost:83", dbName: "dbE",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+84
|
||||
{ url: "http://localhost:84", dbName: "dbF",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+85
|
||||
{ url: "http://localhost:85", dbName: "dbG",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+86
|
||||
{ url: "http://localhost:86", dbName: "dbH",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+87
|
||||
{ url: "http://localhost:87", dbName: "dbI",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+88
|
||||
{ url: "http://localhost:88", dbName: "dbJ",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+89
|
||||
{ url: "http://localhost:89", dbName: "dbK",
|
||||
dbOptions: { version: 1, storage: "default" } },
|
||||
|
||||
// This one lives in storage/default/http+++localhost+90
|
||||
{ url: "http://localhost:90", dbName: "dbL",
|
||||
dbOptions: { version: 1, storage: "default" } }
|
||||
];
|
||||
|
||||
let ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(SpecialPowers.Ci.nsIIOService);
|
||||
|
||||
let ssm = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(SpecialPowers.Ci.nsIScriptSecurityManager);
|
||||
|
||||
function openDatabase(params) {
|
||||
let request;
|
||||
if ("url" in params) {
|
||||
let uri = ios.newURI(params.url, null, null);
|
||||
let principal = ssm.createCodebasePrincipal(uri, {});
|
||||
request = indexedDB.openForPrincipal(principal, params.dbName,
|
||||
params.dbOptions);
|
||||
} else {
|
||||
request = indexedDB.open(params.dbName, params.dbOptions);
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
clearAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
installPackagedProfile("metadataRestore_profile");
|
||||
|
||||
for (let params of openParams) {
|
||||
let request = openDatabase(params);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Correct event type");
|
||||
}
|
||||
|
||||
resetAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
for (let params of openParams) {
|
||||
let request = openDatabase(params);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Correct event type");
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
218
dom/indexedDB/test/unit/test_multientry.js
Normal file
218
dom/indexedDB/test/unit/test_multientry.js
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
// Test object stores
|
||||
|
||||
let name = this.window ? window.location.pathname : "Splendid Test";
|
||||
let openRequest = indexedDB.open(name, 1);
|
||||
openRequest.onerror = errorHandler;
|
||||
openRequest.onupgradeneeded = grabEventAndContinueHandler;
|
||||
openRequest.onsuccess = unexpectedSuccessHandler;
|
||||
let event = yield undefined;
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
let tests =
|
||||
[{ add: { x: 1, id: 1 },
|
||||
indexes:[{ v: 1, k: 1 }] },
|
||||
{ add: { x: [2, 3], id: 2 },
|
||||
indexes:[{ v: 1, k: 1 },
|
||||
{ v: 2, k: 2 },
|
||||
{ v: 3, k: 2 }] },
|
||||
{ put: { x: [2, 4], id: 1 },
|
||||
indexes:[{ v: 2, k: 1 },
|
||||
{ v: 2, k: 2 },
|
||||
{ v: 3, k: 2 },
|
||||
{ v: 4, k: 1 }] },
|
||||
{ add: { x: [5, 6, 5, -2, 3], id: 3 },
|
||||
indexes:[{ v:-2, k: 3 },
|
||||
{ v: 2, k: 1 },
|
||||
{ v: 2, k: 2 },
|
||||
{ v: 3, k: 2 },
|
||||
{ v: 3, k: 3 },
|
||||
{ v: 4, k: 1 },
|
||||
{ v: 5, k: 3 },
|
||||
{ v: 6, k: 3 }] },
|
||||
{ delete: IDBKeyRange.bound(1, 3),
|
||||
indexes:[] },
|
||||
{ put: { x: ["food", {}, false, undefined, /x/, [73, false]], id: 2 },
|
||||
indexes:[{ v: "food", k: 2 }] },
|
||||
{ add: { x: [{}, /x/, -12, "food", null, [false], undefined], id: 3 },
|
||||
indexes:[{ v: -12, k: 3 },
|
||||
{ v: "food", k: 2 },
|
||||
{ v: "food", k: 3 }] },
|
||||
{ put: { x: [], id: 2 },
|
||||
indexes:[{ v: -12, k: 3 },
|
||||
{ v: "food", k: 3 }] },
|
||||
{ put: { x: { y: 3 }, id: 3 },
|
||||
indexes:[] },
|
||||
{ add: { x: false, id: 7 },
|
||||
indexes:[] },
|
||||
{ delete: IDBKeyRange.lowerBound(0),
|
||||
indexes:[] },
|
||||
];
|
||||
|
||||
let store = db.createObjectStore("mystore", { keyPath: "id" });
|
||||
let index = store.createIndex("myindex", "x", { multiEntry: true });
|
||||
is(index.multiEntry, true, "index created with multiEntry");
|
||||
|
||||
let i;
|
||||
for (i = 0; i < tests.length; ++i) {
|
||||
let test = tests[i];
|
||||
let testName = " for " + JSON.stringify(test);
|
||||
let req;
|
||||
if (test.add) {
|
||||
req = store.add(test.add);
|
||||
}
|
||||
else if (test.put) {
|
||||
req = store.put(test.put);
|
||||
}
|
||||
else if (test.delete) {
|
||||
req = store.delete(test.delete);
|
||||
}
|
||||
else {
|
||||
ok(false, "borked test");
|
||||
}
|
||||
req.onsuccess = grabEventAndContinueHandler;
|
||||
let e = yield undefined;
|
||||
|
||||
req = index.openKeyCursor();
|
||||
req.onsuccess = grabEventAndContinueHandler;
|
||||
for (let j = 0; j < test.indexes.length; ++j) {
|
||||
e = yield undefined;
|
||||
is(req.result.key, test.indexes[j].v, "found expected index key at index " + j + testName);
|
||||
is(req.result.primaryKey, test.indexes[j].k, "found expected index primary key at index " + j + testName);
|
||||
req.result.continue();
|
||||
}
|
||||
e = yield undefined;
|
||||
ok(req.result == null, "exhausted indexes");
|
||||
|
||||
let tempIndex = store.createIndex("temp index", "x", { multiEntry: true });
|
||||
req = tempIndex.openKeyCursor();
|
||||
req.onsuccess = grabEventAndContinueHandler;
|
||||
for (let j = 0; j < test.indexes.length; ++j) {
|
||||
e = yield undefined;
|
||||
is(req.result.key, test.indexes[j].v, "found expected temp index key at index " + j + testName);
|
||||
is(req.result.primaryKey, test.indexes[j].k, "found expected temp index primary key at index " + j + testName);
|
||||
req.result.continue();
|
||||
}
|
||||
e = yield undefined;
|
||||
ok(req.result == null, "exhausted temp index");
|
||||
store.deleteIndex("temp index");
|
||||
}
|
||||
|
||||
// Unique indexes
|
||||
tests =
|
||||
[{ add: { x: 1, id: 1 },
|
||||
indexes:[{ v: 1, k: 1 }] },
|
||||
{ add: { x: [2, 3], id: 2 },
|
||||
indexes:[{ v: 1, k: 1 },
|
||||
{ v: 2, k: 2 },
|
||||
{ v: 3, k: 2 }] },
|
||||
{ put: { x: [2, 4], id: 3 },
|
||||
fail: true },
|
||||
{ put: { x: [1, 4], id: 1 },
|
||||
indexes:[{ v: 1, k: 1 },
|
||||
{ v: 2, k: 2 },
|
||||
{ v: 3, k: 2 },
|
||||
{ v: 4, k: 1 }] },
|
||||
{ add: { x: [5, 0, 5, 5, 5], id: 3 },
|
||||
indexes:[{ v: 0, k: 3 },
|
||||
{ v: 1, k: 1 },
|
||||
{ v: 2, k: 2 },
|
||||
{ v: 3, k: 2 },
|
||||
{ v: 4, k: 1 },
|
||||
{ v: 5, k: 3 }] },
|
||||
{ delete: IDBKeyRange.bound(1, 2),
|
||||
indexes:[{ v: 0, k: 3 },
|
||||
{ v: 5, k: 3 }] },
|
||||
{ add: { x: [0, 6], id: 8 },
|
||||
fail: true },
|
||||
{ add: { x: 5, id: 8 },
|
||||
fail: true },
|
||||
{ put: { x: 0, id: 8 },
|
||||
fail: true },
|
||||
];
|
||||
|
||||
store.deleteIndex("myindex");
|
||||
index = store.createIndex("myindex", "x", { multiEntry: true, unique: true });
|
||||
is(index.multiEntry, true, "index created with multiEntry");
|
||||
|
||||
let indexes;
|
||||
for (i = 0; i < tests.length; ++i) {
|
||||
let test = tests[i];
|
||||
let testName = " for " + JSON.stringify(test);
|
||||
let req;
|
||||
if (test.add) {
|
||||
req = store.add(test.add);
|
||||
}
|
||||
else if (test.put) {
|
||||
req = store.put(test.put);
|
||||
}
|
||||
else if (test.delete) {
|
||||
req = store.delete(test.delete);
|
||||
}
|
||||
else {
|
||||
ok(false, "borked test");
|
||||
}
|
||||
|
||||
if (!test.fail) {
|
||||
req.onsuccess = grabEventAndContinueHandler;
|
||||
let e = yield undefined;
|
||||
indexes = test.indexes;
|
||||
}
|
||||
else {
|
||||
req.onsuccess = unexpectedSuccessHandler;
|
||||
req.onerror = grabEventAndContinueHandler;
|
||||
ok(true, "waiting for error");
|
||||
let e = yield undefined;
|
||||
ok(true, "got error: " + e.type);
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
let e;
|
||||
req = index.openKeyCursor();
|
||||
req.onsuccess = grabEventAndContinueHandler;
|
||||
for (let j = 0; j < indexes.length; ++j) {
|
||||
e = yield undefined;
|
||||
is(req.result.key, indexes[j].v, "found expected index key at index " + j + testName);
|
||||
is(req.result.primaryKey, indexes[j].k, "found expected index primary key at index " + j + testName);
|
||||
req.result.continue();
|
||||
}
|
||||
e = yield undefined;
|
||||
ok(req.result == null, "exhausted indexes");
|
||||
|
||||
let tempIndex = store.createIndex("temp index", "x", { multiEntry: true, unique: true });
|
||||
req = tempIndex.openKeyCursor();
|
||||
req.onsuccess = grabEventAndContinueHandler;
|
||||
for (let j = 0; j < indexes.length; ++j) {
|
||||
e = yield undefined;
|
||||
is(req.result.key, indexes[j].v, "found expected temp index key at index " + j + testName);
|
||||
is(req.result.primaryKey, indexes[j].k, "found expected temp index primary key at index " + j + testName);
|
||||
req.result.continue();
|
||||
}
|
||||
e = yield undefined;
|
||||
ok(req.result == null, "exhausted temp index");
|
||||
store.deleteIndex("temp index");
|
||||
}
|
||||
|
||||
|
||||
openRequest.onsuccess = grabEventAndContinueHandler;
|
||||
yield undefined;
|
||||
|
||||
let trans = db.transaction(["mystore"], "readwrite");
|
||||
store = trans.objectStore("mystore");
|
||||
index = store.index("myindex");
|
||||
is(index.multiEntry, true, "index still is multiEntry");
|
||||
trans.oncomplete = grabEventAndContinueHandler;
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
122
dom/indexedDB/test/unit/test_mutableFileUpgrade.js
Normal file
122
dom/indexedDB/test/unit/test_mutableFileUpgrade.js
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const dbNames = [
|
||||
"No files",
|
||||
"Blobs and mutable files"
|
||||
]
|
||||
const version = 1;
|
||||
const objectStoreName = "test";
|
||||
|
||||
clearAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
installPackagedProfile("mutableFileUpgrade_profile");
|
||||
|
||||
let request = indexedDB.open(dbNames[0], version);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Correct event type");
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
request = db.transaction([objectStoreName])
|
||||
.objectStore(objectStoreName)
|
||||
.get(1);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, "text", "Correct result");
|
||||
|
||||
request = indexedDB.open(dbNames[1], version);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Correct event type");
|
||||
|
||||
db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
request = db.transaction([objectStoreName])
|
||||
.objectStore(objectStoreName)
|
||||
.get(1);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, "text", "Correct result");
|
||||
|
||||
request = db.transaction([objectStoreName])
|
||||
.objectStore(objectStoreName)
|
||||
.get(2);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
verifyBlob(event.target.result, getBlob("blob0"));
|
||||
yield undefined;
|
||||
|
||||
request = db.transaction([objectStoreName])
|
||||
.objectStore(objectStoreName)
|
||||
.get(3);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
let result = event.target.result;
|
||||
|
||||
verifyBlob(result[0], getBlob("blob1"));
|
||||
yield undefined;
|
||||
|
||||
verifyBlob(result[1], getBlob("blob2"));
|
||||
yield undefined;
|
||||
|
||||
request = db.transaction([objectStoreName])
|
||||
.objectStore(objectStoreName)
|
||||
.get(4);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
verifyMutableFile(event.target.result, getFile("mutablefile0", "", ""));
|
||||
yield undefined;
|
||||
|
||||
request = db.transaction([objectStoreName])
|
||||
.objectStore(objectStoreName)
|
||||
.get(5);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
result = event.target.result;
|
||||
|
||||
verifyMutableFile(result[0], getFile("mutablefile1", "", ""));
|
||||
yield undefined;
|
||||
|
||||
verifyMutableFile(result[1], getFile("mutablefile2", "", ""));
|
||||
yield undefined;
|
||||
|
||||
request = db.transaction([objectStoreName])
|
||||
.objectStore(objectStoreName)
|
||||
.get(6);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
result = event.target.result;
|
||||
|
||||
verifyBlob(result[0], getBlob("blob3"));
|
||||
yield undefined;
|
||||
|
||||
verifyMutableFile(result[1], getFile("mutablefile3", "", ""));
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
114
dom/indexedDB/test/unit/test_names_sorted.js
Normal file
114
dom/indexedDB/test/unit/test_names_sorted.js
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const objectStoreInfo = [
|
||||
{ name: "foo", options: { keyPath: "id" }, location: 1 },
|
||||
{ name: "bar", options: { keyPath: "id" }, location: 0 },
|
||||
];
|
||||
const indexInfo = [
|
||||
{ name: "foo", keyPath: "value", location: 1 },
|
||||
{ name: "bar", keyPath: "value", location: 0 },
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
let event = yield undefined;
|
||||
let db = event.target.result;
|
||||
|
||||
for (let i = 0; i < objectStoreInfo.length; i++) {
|
||||
let info = objectStoreInfo[i];
|
||||
let objectStore = info.hasOwnProperty("options") ?
|
||||
db.createObjectStore(info.name, info.options) :
|
||||
db.createObjectStore(info.name);
|
||||
|
||||
// Test index creation, and that it ends up in indexNames.
|
||||
let objectStoreName = info.name;
|
||||
for (let j = 0; j < indexInfo.length; j++) {
|
||||
let info = indexInfo[j];
|
||||
let count = objectStore.indexNames.length;
|
||||
let index = info.hasOwnProperty("options") ?
|
||||
objectStore.createIndex(info.name, info.keyPath,
|
||||
info.options) :
|
||||
objectStore.createIndex(info.name, info.keyPath);
|
||||
}
|
||||
}
|
||||
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
let objectStoreNames = []
|
||||
for (let i = 0; i < objectStoreInfo.length; i++) {
|
||||
let info = objectStoreInfo[i];
|
||||
objectStoreNames.push(info.name);
|
||||
|
||||
is(db.objectStoreNames[info.location], info.name,
|
||||
"Got objectStore name in the right location");
|
||||
|
||||
let trans = db.transaction(info.name);
|
||||
let objectStore = trans.objectStore(info.name);
|
||||
for (let j = 0; j < indexInfo.length; j++) {
|
||||
let info = indexInfo[j];
|
||||
is(objectStore.indexNames[info.location], info.name,
|
||||
"Got index name in the right location");
|
||||
}
|
||||
}
|
||||
|
||||
let trans = db.transaction(objectStoreNames);
|
||||
for (let i = 0; i < objectStoreInfo.length; i++) {
|
||||
let info = objectStoreInfo[i];
|
||||
|
||||
is(trans.objectStoreNames[info.location], info.name,
|
||||
"Got objectStore name in the right location");
|
||||
}
|
||||
|
||||
db.close();
|
||||
|
||||
request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
event = yield undefined;
|
||||
|
||||
db = event.target.result;
|
||||
|
||||
objectStoreNames = []
|
||||
for (let i = 0; i < objectStoreInfo.length; i++) {
|
||||
let info = objectStoreInfo[i];
|
||||
objectStoreNames.push(info.name);
|
||||
|
||||
is(db.objectStoreNames[info.location], info.name,
|
||||
"Got objectStore name in the right location");
|
||||
|
||||
let trans = db.transaction(info.name);
|
||||
let objectStore = trans.objectStore(info.name);
|
||||
for (let j = 0; j < indexInfo.length; j++) {
|
||||
let info = indexInfo[j];
|
||||
is(objectStore.indexNames[info.location], info.name,
|
||||
"Got index name in the right location");
|
||||
}
|
||||
}
|
||||
|
||||
trans = db.transaction(objectStoreNames);
|
||||
for (let i = 0; i < objectStoreInfo.length; i++) {
|
||||
let info = objectStoreInfo[i];
|
||||
|
||||
is(trans.objectStoreNames[info.location], info.name,
|
||||
"Got objectStore name in the right location");
|
||||
}
|
||||
|
||||
db.close();
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
85
dom/indexedDB/test/unit/test_objectCursors.js
Normal file
85
dom/indexedDB/test/unit/test_objectCursors.js
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
|
||||
const objectStores = [
|
||||
{ name: "a", autoIncrement: false },
|
||||
{ name: "b", autoIncrement: true }
|
||||
];
|
||||
|
||||
const indexes = [
|
||||
{ name: "a", options: { } },
|
||||
{ name: "b", options: { unique: true } }
|
||||
];
|
||||
|
||||
var j = 0;
|
||||
for (let i in objectStores) {
|
||||
let request = indexedDB.open(name, ++j);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
db.onversionchange = function(event) {
|
||||
event.target.close();
|
||||
};
|
||||
|
||||
let objectStore =
|
||||
db.createObjectStore(objectStores[i].name,
|
||||
{ keyPath: "id",
|
||||
autoIncrement: objectStores[i].autoIncrement });
|
||||
|
||||
for (let j in indexes) {
|
||||
objectStore.createIndex(indexes[j].name, "name", indexes[j].options);
|
||||
}
|
||||
|
||||
let data = { name: "Ben" };
|
||||
if (!objectStores[i].autoIncrement) {
|
||||
data.id = 1;
|
||||
}
|
||||
|
||||
request = objectStore.add(data);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(event.target.result == 1 || event.target.result == 2, "Good id");
|
||||
}
|
||||
|
||||
executeSoon(function() { testGenerator.next(); });
|
||||
yield undefined;
|
||||
|
||||
let request = indexedDB.open(name, j);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
for (let i in objectStores) {
|
||||
for (let j in indexes) {
|
||||
let objectStore = db.transaction(objectStores[i].name)
|
||||
.objectStore(objectStores[i].name);
|
||||
let index = objectStore.index(indexes[j].name);
|
||||
|
||||
request = index.openCursor();
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function (event) {
|
||||
is(event.target.result.value.name, "Ben", "Good object");
|
||||
executeSoon(function() { testGenerator.next(); });
|
||||
}
|
||||
yield undefined;
|
||||
}
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
123
dom/indexedDB/test/unit/test_objectStore_getAllKeys.js
Normal file
123
dom/indexedDB/test/unit/test_objectStore_getAllKeys.js
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps() {
|
||||
const dbName = this.window ?
|
||||
window.location.pathname :
|
||||
"test_objectStore_getAllKeys";
|
||||
const dbVersion = 1;
|
||||
const objectStoreName = "foo";
|
||||
const keyCount = 200;
|
||||
|
||||
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).objectStore(objectStoreName);
|
||||
|
||||
info("Getting all keys");
|
||||
objectStore.getAllKeys().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, keyCount, "Got correct array length");
|
||||
|
||||
let match = true;
|
||||
for (let i = 0; i < keyCount; i++) {
|
||||
if (event.target.result[i] != i) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(match, "Got correct keys");
|
||||
|
||||
info("Getting all keys with key range");
|
||||
let keyRange = IDBKeyRange.bound(10, 20, false, true);
|
||||
objectStore.getAllKeys(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, 10, "Got correct array length");
|
||||
|
||||
match = true;
|
||||
for (let i = 10; i < 20; i++) {
|
||||
if (event.target.result[i - 10] != i) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(match, "Got correct keys");
|
||||
|
||||
info("Getting all keys with unmatched key range");
|
||||
keyRange = IDBKeyRange.bound(10000, 200000);
|
||||
objectStore.getAllKeys(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, 0, "Got correct array length");
|
||||
|
||||
info("Getting all keys with limit");
|
||||
objectStore.getAllKeys(null, 5).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, 5, "Got correct array length");
|
||||
|
||||
match = true;
|
||||
for (let i = 0; i < 5; i++) {
|
||||
if (event.target.result[i] != i) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(match, "Got correct keys");
|
||||
|
||||
info("Getting all keys with key range and limit");
|
||||
keyRange = IDBKeyRange.bound(10, 20, false, true);
|
||||
objectStore.getAllKeys(keyRange, 5).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, 5, "Got correct array length");
|
||||
|
||||
match = true;
|
||||
for (let i = 10; i < 15; i++) {
|
||||
if (event.target.result[i - 10] != i) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(match, "Got correct keys");
|
||||
|
||||
info("Getting all keys with unmatched key range and limit");
|
||||
keyRange = IDBKeyRange.bound(10000, 200000);
|
||||
objectStore.getAllKeys(keyRange, 5).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, 0, "Got correct array length");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
|
||||
var request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
var event = yield undefined;
|
||||
|
||||
var db = event.target.result;
|
||||
|
||||
var test = {
|
||||
name: "inline key; key generator",
|
||||
autoIncrement: true,
|
||||
storedObject: {name: "Lincoln"},
|
||||
keyName: "id",
|
||||
};
|
||||
|
||||
let objectStore = db.createObjectStore(test.name,
|
||||
{ keyPath: test.keyName,
|
||||
autoIncrement: test.autoIncrement });
|
||||
|
||||
request = objectStore.add(test.storedObject);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
let id = event.target.result;
|
||||
request = objectStore.get(id);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
// Sanity check!
|
||||
is(event.target.result.name, test.storedObject.name,
|
||||
"The correct object was stored.");
|
||||
|
||||
// Ensure that the id was also stored on the object.
|
||||
is(event.target.result.id, id, "The object had the id stored on it.");
|
||||
|
||||
// Wait for success
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
400
dom/indexedDB/test/unit/test_objectStore_openKeyCursor.js
Normal file
400
dom/indexedDB/test/unit/test_objectStore_openKeyCursor.js
Normal file
|
|
@ -0,0 +1,400 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps() {
|
||||
const dbName = this.window ?
|
||||
window.location.pathname :
|
||||
"test_objectStore_openKeyCursor";
|
||||
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;
|
||||
}
|
||||
92
dom/indexedDB/test/unit/test_objectStore_remove_values.js
Normal file
92
dom/indexedDB/test/unit/test_objectStore_remove_values.js
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
|
||||
var data = [
|
||||
{ name: "inline key; key generator",
|
||||
autoIncrement: true,
|
||||
storedObject: {name: "Lincoln"},
|
||||
keyName: "id",
|
||||
keyValue: undefined,
|
||||
},
|
||||
{ name: "inline key; no key generator",
|
||||
autoIncrement: false,
|
||||
storedObject: {id: 1, name: "Lincoln"},
|
||||
keyName: "id",
|
||||
keyValue: undefined,
|
||||
},
|
||||
{ name: "out of line key; key generator",
|
||||
autoIncrement: true,
|
||||
storedObject: {name: "Lincoln"},
|
||||
keyName: undefined,
|
||||
keyValue: undefined,
|
||||
},
|
||||
{ name: "out of line key; no key generator",
|
||||
autoIncrement: false,
|
||||
storedObject: {name: "Lincoln"},
|
||||
keyName: null,
|
||||
keyValue: 1,
|
||||
}
|
||||
];
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
let test = data[i];
|
||||
|
||||
let request = indexedDB.open(name, i+1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
db.onversionchange = function(event) {
|
||||
event.target.close();
|
||||
};
|
||||
|
||||
let objectStore = db.createObjectStore(test.name,
|
||||
{ keyPath: test.keyName,
|
||||
autoIncrement: test.autoIncrement });
|
||||
|
||||
request = objectStore.add(test.storedObject, test.keyValue);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
let id = event.target.result;
|
||||
request = objectStore.get(id);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
// Sanity check!
|
||||
is(test.storedObject.name, event.target.result.name,
|
||||
"The correct object was stored.");
|
||||
|
||||
request = objectStore.delete(id);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
// Make sure it was removed.
|
||||
request = objectStore.get(id);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(event.target.result === undefined, "Object was deleted");
|
||||
|
||||
// Wait for success
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
48
dom/indexedDB/test/unit/test_object_identity.js
Normal file
48
dom/indexedDB/test/unit/test_object_identity.js
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
let transaction = event.target.transaction;
|
||||
|
||||
let objectStore1 = db.createObjectStore("foo");
|
||||
let objectStore2 = transaction.objectStore("foo");
|
||||
ok(objectStore1 === objectStore2, "Got same objectStores");
|
||||
|
||||
let index1 = objectStore1.createIndex("bar", "key");
|
||||
let index2 = objectStore2.index("bar");
|
||||
ok(index1 === index2, "Got same indexes");
|
||||
|
||||
request.onsuccess = continueToNextStep;
|
||||
yield undefined;
|
||||
|
||||
transaction = db.transaction(db.objectStoreNames);
|
||||
|
||||
let objectStore3 = transaction.objectStore("foo");
|
||||
let objectStore4 = transaction.objectStore("foo");
|
||||
ok(objectStore3 === objectStore4, "Got same objectStores");
|
||||
|
||||
ok(objectStore3 !== objectStore1, "Different objectStores");
|
||||
ok(objectStore4 !== objectStore2, "Different objectStores");
|
||||
|
||||
let index3 = objectStore3.index("bar");
|
||||
let index4 = objectStore4.index("bar");
|
||||
ok(index3 === index4, "Got same indexes");
|
||||
|
||||
ok(index3 !== index1, "Different indexes");
|
||||
ok(index4 !== index2, "Different indexes");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
76
dom/indexedDB/test/unit/test_odd_result_order.js
Normal file
76
dom/indexedDB/test/unit/test_odd_result_order.js
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const data = { key: 5, index: 10 };
|
||||
|
||||
let request = indexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
ok(db instanceof IDBDatabase, "Got a real database");
|
||||
|
||||
db.onerror = errorHandler;
|
||||
|
||||
let objectStore = db.createObjectStore("foo", { keyPath: "key",
|
||||
autoIncrement: true });
|
||||
let index = objectStore.createIndex("foo", "index");
|
||||
|
||||
event.target.onsuccess = continueToNextStep;
|
||||
yield undefined;
|
||||
|
||||
objectStore = db.transaction("foo", "readwrite")
|
||||
.objectStore("foo");
|
||||
request = objectStore.add(data);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
let key;
|
||||
executeSoon(function() {
|
||||
key = request.result;
|
||||
continueToNextStep();
|
||||
});
|
||||
yield undefined;
|
||||
|
||||
is(key, data.key, "Got the right key");
|
||||
|
||||
objectStore = db.transaction("foo").objectStore("foo");
|
||||
objectStore.get(data.key).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
let obj;
|
||||
executeSoon(function() {
|
||||
obj = event.target.result;
|
||||
continueToNextStep();
|
||||
});
|
||||
yield undefined;
|
||||
|
||||
is(obj.key, data.key, "Got the right key");
|
||||
is(obj.index, data.index, "Got the right property value");
|
||||
|
||||
objectStore = db.transaction("foo", "readwrite")
|
||||
.objectStore("foo");
|
||||
request = objectStore.delete(data.key);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
key = undefined;
|
||||
executeSoon(function() {
|
||||
key = request.result;
|
||||
continueToNextStep();
|
||||
}, 0);
|
||||
yield undefined;
|
||||
|
||||
ok(key === undefined, "Got the right value");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
72
dom/indexedDB/test/unit/test_oldDirectories.js
Normal file
72
dom/indexedDB/test/unit/test_oldDirectories.js
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
// This lives in storage/default/http+++www.mozilla.org
|
||||
const url = "http://www.mozilla.org";
|
||||
const dbName = "dbC";
|
||||
const dbVersion = 1;
|
||||
|
||||
let ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(SpecialPowers.Ci.nsIIOService);
|
||||
|
||||
let ssm = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(SpecialPowers.Ci.nsIScriptSecurityManager);
|
||||
|
||||
function openDatabase() {
|
||||
let uri = ios.newURI(url, null, null);
|
||||
let principal = ssm.createCodebasePrincipal(uri, {});
|
||||
let request = indexedDB.openForPrincipal(principal, dbName, dbVersion);
|
||||
return request;
|
||||
}
|
||||
|
||||
clearAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
installPackagedProfile("oldDirectories_profile");
|
||||
|
||||
let request = openDatabase();
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Correct event type");
|
||||
|
||||
resetAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
request = openDatabase();
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Correct event type");
|
||||
|
||||
let directoryService = Cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Ci.nsIProperties);
|
||||
|
||||
let profileDir = directoryService.get("ProfD", Ci.nsIFile);
|
||||
|
||||
let dir = profileDir.clone();
|
||||
dir.append("indexedDB");
|
||||
|
||||
let exists = dir.exists();
|
||||
ok(!exists, "indexedDB doesn't exist");
|
||||
|
||||
dir = profileDir.clone();
|
||||
dir.append("storage");
|
||||
dir.append("persistent");
|
||||
|
||||
exists = dir.exists();
|
||||
ok(!exists, "storage/persistent doesn't exist");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
46
dom/indexedDB/test/unit/test_open_empty_db.js
Normal file
46
dom/indexedDB/test/unit/test_open_empty_db.js
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const names = [
|
||||
//"",
|
||||
null,
|
||||
undefined,
|
||||
this.window ? window.location.pathname : "Splendid Test"
|
||||
];
|
||||
|
||||
const version = 1;
|
||||
|
||||
for (let name of names) {
|
||||
let request = indexedDB.open(name, version);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
if (name === null) {
|
||||
name = "null";
|
||||
}
|
||||
else if (name === undefined) {
|
||||
name = "undefined";
|
||||
}
|
||||
|
||||
let db = event.target.result;
|
||||
is(db.name, name, "Bad name");
|
||||
is(db.version, version, "Bad version");
|
||||
is(db.objectStoreNames.length, 0, "Bad objectStores list");
|
||||
|
||||
is(db.name, request.result.name, "Bad name");
|
||||
is(db.version, request.result.version, "Bad version");
|
||||
is(db.objectStoreNames.length, request.result.objectStoreNames.length,
|
||||
"Bad objectStores list");
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
90
dom/indexedDB/test/unit/test_open_for_principal.js
Normal file
90
dom/indexedDB/test/unit/test_open_for_principal.js
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
|
||||
const objectStoreName = "Foo";
|
||||
|
||||
const data = { key: 1, value: "bar" };
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Got correct event type");
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
let objectStore = db.createObjectStore(objectStoreName, { });
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got correct event type");
|
||||
|
||||
objectStore = db.transaction([objectStoreName], "readwrite")
|
||||
.objectStore(objectStoreName);
|
||||
|
||||
request = objectStore.get(data.key);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, null, "Got no data");
|
||||
|
||||
request = objectStore.add(data.value, data.key);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, data.key, "Got correct key");
|
||||
|
||||
let uri = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService)
|
||||
.newURI("http://appdata.example.com", null, null);
|
||||
let ssm = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Components.interfaces.nsIScriptSecurityManager);
|
||||
let principal = ssm.createCodebasePrincipal(uri, {});
|
||||
|
||||
request = indexedDB.openForPrincipal(principal, name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Got correct event type");
|
||||
|
||||
db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
objectStore = db.createObjectStore(objectStoreName, { });
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got correct event type");
|
||||
|
||||
objectStore = db.transaction([objectStoreName])
|
||||
.objectStore(objectStoreName);
|
||||
|
||||
request = objectStore.get(data.key);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, null, "Got no data");
|
||||
|
||||
db.close();
|
||||
|
||||
request = indexedDB.deleteForPrincipal(principal, name);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler
|
||||
event = yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
39
dom/indexedDB/test/unit/test_open_objectStore.js
Normal file
39
dom/indexedDB/test/unit/test_open_objectStore.js
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const objectStoreName = "Objects";
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
is(db.objectStoreNames.length, 0, "Bad objectStores list");
|
||||
|
||||
let objectStore = db.createObjectStore(objectStoreName,
|
||||
{ keyPath: "foo" });
|
||||
|
||||
is(db.objectStoreNames.length, 1, "Bad objectStores list");
|
||||
is(db.objectStoreNames.item(0), objectStoreName, "Bad name");
|
||||
|
||||
yield undefined;
|
||||
|
||||
objectStore = db.transaction(objectStoreName).objectStore(objectStoreName);
|
||||
|
||||
is(objectStore.name, objectStoreName, "Bad name");
|
||||
is(objectStore.keyPath, "foo", "Bad keyPath");
|
||||
if(objectStore.indexNames.length, 0, "Bad indexNames");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
1711
dom/indexedDB/test/unit/test_optionalArguments.js
Normal file
1711
dom/indexedDB/test/unit/test_optionalArguments.js
Normal file
File diff suppressed because it is too large
Load diff
92
dom/indexedDB/test/unit/test_overlapping_transactions.js
Normal file
92
dom/indexedDB/test/unit/test_overlapping_transactions.js
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const objectStores = [ "foo", "bar" ];
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
|
||||
|
||||
event.target.onsuccess = grabEventAndContinueHandler;
|
||||
for (let i in objectStores) {
|
||||
db.createObjectStore(objectStores[i], { autoIncrement: true });
|
||||
}
|
||||
event = yield undefined;
|
||||
|
||||
is(db.objectStoreNames.length, objectStores.length,
|
||||
"Correct objectStoreNames list");
|
||||
|
||||
for (let i = 0; i < 50; i++) {
|
||||
let stepNumber = 0;
|
||||
|
||||
request = db.transaction(["foo"], "readwrite")
|
||||
.objectStore("foo")
|
||||
.add({});
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(stepNumber, 1, "This callback came first");
|
||||
stepNumber++;
|
||||
event.target.transaction.oncomplete = grabEventAndContinueHandler;
|
||||
}
|
||||
|
||||
request = db.transaction(["foo"], "readwrite")
|
||||
.objectStore("foo")
|
||||
.add({});
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(stepNumber, 2, "This callback came second");
|
||||
stepNumber++;
|
||||
event.target.transaction.oncomplete = grabEventAndContinueHandler;
|
||||
}
|
||||
|
||||
request = db.transaction(["foo", "bar"], "readwrite")
|
||||
.objectStore("bar")
|
||||
.add({});
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(stepNumber, 3, "This callback came third");
|
||||
stepNumber++;
|
||||
event.target.transaction.oncomplete = grabEventAndContinueHandler;
|
||||
}
|
||||
|
||||
request = db.transaction(["foo", "bar"], "readwrite")
|
||||
.objectStore("bar")
|
||||
.add({});
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(stepNumber, 4, "This callback came fourth");
|
||||
stepNumber++;
|
||||
event.target.transaction.oncomplete = grabEventAndContinueHandler;
|
||||
}
|
||||
|
||||
request = db.transaction(["bar"], "readwrite")
|
||||
.objectStore("bar")
|
||||
.add({});
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(stepNumber, 5, "This callback came fifth");
|
||||
stepNumber++;
|
||||
event.target.transaction.oncomplete = grabEventAndContinueHandler;
|
||||
}
|
||||
|
||||
stepNumber++;
|
||||
yield undefined; yield undefined; yield undefined; yield undefined; yield undefined;
|
||||
|
||||
is(stepNumber, 6, "All callbacks received");
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
86
dom/indexedDB/test/unit/test_persistenceType.js
Normal file
86
dom/indexedDB/test/unit/test_persistenceType.js
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = "Splendid Test";
|
||||
const version = 1;
|
||||
|
||||
const objectStoreName = "Foo";
|
||||
const data = { key: 1, value: "bar" };
|
||||
|
||||
try {
|
||||
indexedDB.open(name, { version: version, storage: "unknown" });
|
||||
ok(false, "Should have thrown!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(e instanceof TypeError, "Got TypeError.");
|
||||
is(e.name, "TypeError", "Good error name.");
|
||||
}
|
||||
|
||||
let request = indexedDB.open(name, { version: version,
|
||||
storage: "persistent" });
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Got correct event type");
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
let objectStore = db.createObjectStore(objectStoreName, { });
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got correct event type");
|
||||
|
||||
is(db.name, name, "Correct name");
|
||||
is(db.version, version, "Correct version");
|
||||
is(db.storage, "persistent", "Correct persistence type");
|
||||
|
||||
objectStore = db.transaction([objectStoreName], "readwrite")
|
||||
.objectStore(objectStoreName);
|
||||
|
||||
request = objectStore.get(data.key);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, undefined, "Got no data");
|
||||
|
||||
request = objectStore.add(data.value, data.key);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, data.key, "Got correct key");
|
||||
|
||||
request = indexedDB.open(name, { version: version,
|
||||
storage: "temporary" });
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got correct event type");
|
||||
|
||||
is(db.name, name, "Correct name");
|
||||
is(db.version, version, "Correct version");
|
||||
is(db.storage, "persistent", "Correct persistence type");
|
||||
|
||||
objectStore = db.transaction([objectStoreName])
|
||||
.objectStore(objectStoreName);
|
||||
|
||||
request = objectStore.get(data.key);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, data.value, "Got correct data");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
55
dom/indexedDB/test/unit/test_put_get_values.js
Normal file
55
dom/indexedDB/test/unit/test_put_get_values.js
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const objectStoreName = "Objects";
|
||||
|
||||
let testString = { key: 0, value: "testString" };
|
||||
let testInt = { key: 1, value: 1002 };
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
let objectStore = db.createObjectStore(objectStoreName,
|
||||
{ autoIncrement: 0 });
|
||||
|
||||
request = objectStore.add(testString.value, testString.key);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(event.target.result, testString.key, "Got the right key");
|
||||
request = objectStore.get(testString.key);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(event.target.result, testString.value, "Got the right value");
|
||||
};
|
||||
};
|
||||
|
||||
request = objectStore.add(testInt.value, testInt.key);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(event.target.result, testInt.key, "Got the right key");
|
||||
request = objectStore.get(testInt.key);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(event.target.result, testInt.value, "Got the right value");
|
||||
};
|
||||
}
|
||||
|
||||
// Wait for success
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
54
dom/indexedDB/test/unit/test_put_get_values_autoIncrement.js
Normal file
54
dom/indexedDB/test/unit/test_put_get_values_autoIncrement.js
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const objectStoreName = "Objects";
|
||||
|
||||
let testString = { value: "testString" };
|
||||
let testInt = { value: 1002 };
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
let objectStore = db.createObjectStore(objectStoreName,
|
||||
{ autoIncrement: 1 });
|
||||
|
||||
request = objectStore.put(testString.value);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
testString.key = event.target.result;
|
||||
request = objectStore.get(testString.key);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(event.target.result, testString.value, "Got the right value");
|
||||
};
|
||||
};
|
||||
|
||||
request = objectStore.put(testInt.value);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
testInt.key = event.target.result;
|
||||
request = objectStore.get(testInt.key);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(event.target.result, testInt.value, "Got the right value");
|
||||
};
|
||||
}
|
||||
|
||||
// Wait for success
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
141
dom/indexedDB/test/unit/test_quotaExceeded_recovery.js
Normal file
141
dom/indexedDB/test/unit/test_quotaExceeded_recovery.js
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var disableWorkerTest = "Need a way to set temporary prefs from a worker";
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const spec = "http://foo.com";
|
||||
const name =
|
||||
this.window ? window.location.pathname : "test_quotaExceeded_recovery";
|
||||
const objectStoreName = "foo";
|
||||
|
||||
const android = mozinfo.os == "android";
|
||||
|
||||
// We want 512 KB database on Android and 4 MB database on other platforms.
|
||||
const groupLimitKB = android ? 512 : 4096;
|
||||
|
||||
// The group limit is calculated as 20% of the global temporary storage limit.
|
||||
const tempStorageLimitKB = groupLimitKB * 5;
|
||||
|
||||
// We want 64 KB chunks on Android and 512 KB chunks on other platforms.
|
||||
const dataSizeKB = android ? 64 : 512;
|
||||
const dataSize = dataSizeKB * 1024;
|
||||
|
||||
const maxIter = 5;
|
||||
|
||||
for (let blobs of [false, true]) {
|
||||
setTemporaryStorageLimit(tempStorageLimitKB);
|
||||
|
||||
clearAllDatabases(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
info("Opening database");
|
||||
|
||||
let request = indexedDB.openForPrincipal(getPrincipal(spec), name);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
|
||||
yield undefined;
|
||||
|
||||
// upgradeneeded
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
info("Creating objectStore");
|
||||
|
||||
request.result.createObjectStore(objectStoreName, { autoIncrement: true });
|
||||
|
||||
yield undefined;
|
||||
|
||||
// success
|
||||
let db = request.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
ok(true, "Filling database");
|
||||
|
||||
let obj = {
|
||||
name: "foo"
|
||||
}
|
||||
|
||||
if (!blobs) {
|
||||
obj.data = getRandomView(dataSize);
|
||||
}
|
||||
|
||||
let iter = 1;
|
||||
let i = 1;
|
||||
let j = 1;
|
||||
while (true) {
|
||||
if (blobs) {
|
||||
obj.data = getBlob(getView(dataSize));
|
||||
}
|
||||
|
||||
let trans = db.transaction(objectStoreName, "readwrite");
|
||||
request = trans.objectStore(objectStoreName).add(obj);
|
||||
request.onerror = function(event)
|
||||
{
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
trans.oncomplete = function(event) {
|
||||
if (iter == 1) {
|
||||
i++;
|
||||
}
|
||||
j++;
|
||||
testGenerator.send(true);
|
||||
}
|
||||
trans.onabort = function(event) {
|
||||
is(trans.error.name, "QuotaExceededError", "Reached quota limit");
|
||||
testGenerator.send(false);
|
||||
}
|
||||
|
||||
let completeFired = yield undefined;
|
||||
if (completeFired) {
|
||||
ok(true, "Got complete event");
|
||||
continue;
|
||||
}
|
||||
|
||||
ok(true, "Got abort event");
|
||||
|
||||
if (iter++ == maxIter) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (iter > 1) {
|
||||
ok(i == j, "Recycled entire database");
|
||||
j = 1;
|
||||
}
|
||||
|
||||
trans = db.transaction(objectStoreName, "readwrite");
|
||||
|
||||
// Don't use a cursor for deleting stored blobs (Cursors prolong live
|
||||
// of stored files since each record must be fetched from the database
|
||||
// first which creates a memory reference to the stored blob.)
|
||||
if (blobs) {
|
||||
request = trans.objectStore(objectStoreName).clear();
|
||||
} else {
|
||||
request = trans.objectStore(objectStoreName).openCursor();
|
||||
request.onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
cursor.delete();
|
||||
cursor.continue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trans.onabort = unexpectedSuccessHandler;;
|
||||
trans.oncomplete = grabEventAndContinueHandler;
|
||||
|
||||
yield undefined;
|
||||
}
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
174
dom/indexedDB/test/unit/test_readonly_transactions.js
Normal file
174
dom/indexedDB/test/unit/test_readonly_transactions.js
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const osName = "foo";
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
let db = event.target.result;
|
||||
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
|
||||
|
||||
db.createObjectStore(osName, { autoIncrement: "true" });
|
||||
|
||||
yield undefined;
|
||||
|
||||
let key1, key2;
|
||||
|
||||
request = db.transaction([osName], "readwrite")
|
||||
.objectStore(osName)
|
||||
.add({});
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(event.target.transaction.mode, "readwrite", "Correct mode");
|
||||
key1 = event.target.result;
|
||||
testGenerator.next();
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
request = db.transaction(osName, "readwrite").objectStore(osName).add({});
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(event.target.transaction.mode, "readwrite", "Correct mode");
|
||||
key2 = event.target.result;
|
||||
testGenerator.next();
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
request = db.transaction([osName], "readwrite")
|
||||
.objectStore(osName)
|
||||
.put({}, key1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(event.target.transaction.mode, "readwrite", "Correct mode");
|
||||
testGenerator.next();
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
request = db.transaction(osName, "readwrite")
|
||||
.objectStore(osName)
|
||||
.put({}, key2);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(event.target.transaction.mode, "readwrite", "Correct mode");
|
||||
testGenerator.next();
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
request = db.transaction([osName], "readwrite")
|
||||
.objectStore(osName)
|
||||
.put({}, key1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(event.target.transaction.mode, "readwrite", "Correct mode");
|
||||
testGenerator.next();
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
request = db.transaction(osName, "readwrite")
|
||||
.objectStore(osName)
|
||||
.put({}, key1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(event.target.transaction.mode, "readwrite", "Correct mode");
|
||||
testGenerator.next();
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
request = db.transaction([osName], "readwrite")
|
||||
.objectStore(osName)
|
||||
.delete(key1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(event.target.transaction.mode, "readwrite", "Correct mode");
|
||||
testGenerator.next();
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
request = db.transaction(osName, "readwrite")
|
||||
.objectStore(osName)
|
||||
.delete(key2);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = function(event) {
|
||||
is(event.target.transaction.mode, "readwrite", "Correct mode");
|
||||
testGenerator.next();
|
||||
}
|
||||
yield undefined;
|
||||
|
||||
try {
|
||||
request = db.transaction([osName]).objectStore(osName).add({});
|
||||
ok(false, "Adding to a readonly transaction should fail!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "Adding to a readonly transaction failed");
|
||||
}
|
||||
|
||||
try {
|
||||
request = db.transaction(osName).objectStore(osName).add({});
|
||||
ok(false, "Adding to a readonly transaction should fail!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "Adding to a readonly transaction failed");
|
||||
}
|
||||
|
||||
try {
|
||||
request = db.transaction([osName]).objectStore(osName).put({});
|
||||
ok(false, "Adding or modifying a readonly transaction should fail!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "Adding or modifying a readonly transaction failed");
|
||||
}
|
||||
|
||||
try {
|
||||
request = db.transaction(osName).objectStore(osName).put({});
|
||||
ok(false, "Adding or modifying a readonly transaction should fail!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "Adding or modifying a readonly transaction failed");
|
||||
}
|
||||
|
||||
try {
|
||||
request = db.transaction([osName]).objectStore(osName).put({}, key1);
|
||||
ok(false, "Modifying a readonly transaction should fail!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "Modifying a readonly transaction failed");
|
||||
}
|
||||
|
||||
try {
|
||||
request = db.transaction(osName).objectStore(osName).put({}, key1);
|
||||
ok(false, "Modifying a readonly transaction should fail!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "Modifying a readonly transaction failed");
|
||||
}
|
||||
|
||||
try {
|
||||
request = db.transaction([osName]).objectStore(osName).delete(key1);
|
||||
ok(false, "Removing from a readonly transaction should fail!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "Removing from a readonly transaction failed");
|
||||
}
|
||||
|
||||
try {
|
||||
request = db.transaction(osName).objectStore(osName).delete(key2);
|
||||
ok(false, "Removing from a readonly transaction should fail!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "Removing from a readonly transaction failed");
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue