2016-05-31 13:08:20 +03:00
|
|
|
/**
|
|
|
|
* Any copyright is dedicated to the Public Domain.
|
|
|
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
|
|
|
*/
|
|
|
|
|
|
|
|
var testGenerator = testSteps();
|
|
|
|
|
2016-12-01 12:11:32 +03:00
|
|
|
function* testSteps()
|
2016-05-31 13:08:20 +03:00
|
|
|
{
|
|
|
|
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 " +
|
2017-05-03 19:54:12 +03:00
|
|
|
"in *write* operation after cleared by the agent.");
|
2016-05-31 13:08:20 +03:00
|
|
|
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;
|
2017-05-03 19:30:48 +03:00
|
|
|
while (true) {
|
2016-05-31 13:08:20 +03:00
|
|
|
let addRequest = objectStore.add({foo: "foo"}, objectId);
|
|
|
|
addRequest.onerror = function(event) {
|
|
|
|
info("addRequest.onerror, objectId: " + objectId);
|
|
|
|
txn.onerror = grabEventAndContinueHandler;
|
2016-12-01 12:11:32 +03:00
|
|
|
testGenerator.next(true);
|
2016-05-31 13:08:20 +03:00
|
|
|
}
|
|
|
|
addRequest.onsuccess = function() {
|
2016-12-01 12:11:32 +03:00
|
|
|
testGenerator.next(false);
|
2016-05-31 13:08:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2017-05-03 19:30:48 +03:00
|
|
|
while (true) {
|
2016-05-31 13:08:20 +03:00
|
|
|
let addRequest = objectStore.add({foo: "foo"});
|
|
|
|
addRequest.onsuccess = function() {
|
|
|
|
objectId++;
|
2016-12-01 12:11:32 +03:00
|
|
|
testGenerator.next(objectId == numberOfObjects);
|
2016-05-31 13:08:20 +03:00
|
|
|
}
|
|
|
|
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);
|
2016-12-01 12:11:32 +03:00
|
|
|
testGenerator.next(true);
|
2016-05-31 13:08:20 +03:00
|
|
|
}
|
|
|
|
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!");
|
2016-12-01 12:11:32 +03:00
|
|
|
testGenerator.next(false);
|
2016-05-31 13:08:20 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
clearAllDatabases(() => {
|
|
|
|
info("clearAllDatabases is done.");
|
|
|
|
continueToNextStep();
|
|
|
|
});
|
|
|
|
|
2017-04-25 23:53:00 +03:00
|
|
|
let readRequestError = yield undefined;
|
2016-05-31 13:08:20 +03:00
|
|
|
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();
|
|
|
|
}
|