/**
* 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 () {
info(
"addRequest.onerror, objectId: " + objectId);
txn.onerror = grabEventAndContinueHandler;
testGenerator.next(
true);
};
addRequest.onsuccess =
function () {
testGenerator.next(
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.next(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 () {
info(
"readRequest.onerror, numberOfReadObjects: " + numberOfReadObjects);
testGenerator.next(
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.next(
false);
}
};
clearAllDatabases(() => {
info(
"clearAllDatabases is done.");
continueToNextStep();
});
let 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();
}