if (this.importScripts) {
importScripts('../../../resources/js-test.js');
importScripts('shared.js');
}
description("Test IndexedDB transaction basics.");
indexedDBTest(prepareDatabase, testSetVersionAbort1);
function prepareDatabase()
{
db = event.target.result;
}
function testSetVersionAbort1()
{
checkMetadataEmpty();
evalAndLog("request = newConnection()");
request.onupgradeneeded = addRemoveIDBObjects;
request.onsuccess = unexpectedSuccessCallback;
request.onerror = testSetVersionAbort2;
}
function addRemoveIDBObjects()
{
debug("addRemoveIDBObjects():");
db = event.target.result;
evalAndLog("trans = event.target.transaction");
shouldBeNonNull("trans");
trans.oncomplete = unexpectedCompleteCallback;
var store = evalAndLog("store = db.createObjectStore('storeFail', null)");
var index = evalAndLog("index = store.createIndex('indexFail', 'x')");
evalAndLog("db.deleteObjectStore('storeFail')");
evalAndExpectException("store.deleteIndex('indexFail')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
trans.abort();
}
function testSetVersionAbort2()
{
debug("");
debug("testSetVersionAbort2():");
checkMetadataEmpty();
evalAndLog("request = newConnection()");
request.onupgradeneeded = addRemoveAddIDBObjects;
request.onerror = null;
}
function addRemoveAddIDBObjects()
{
debug("addRemoveAddIDBObjects():");
db = event.target.result;
var trans = evalAndLog("trans = event.target.transaction");
shouldBeNonNull("trans");
trans.addEventListener('abort', testSetVersionAbort3, false);
trans.oncomplete = unexpectedCompleteCallback;
var store = evalAndLog("store = db.createObjectStore('storeFail', null)");
var index = evalAndLog("index = store.createIndex('indexFail', 'x')");
evalAndLog("db.deleteObjectStore('storeFail')");
evalAndExpectException("store.deleteIndex('indexFail')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");
var store = evalAndLog("store = db.createObjectStore('storeFail', null)");
var index = evalAndLog("index = store.createIndex('indexFail', 'x')");
trans.abort();
}
function testSetVersionAbort3()
{
debug("");
debug("testSetVersionAbort3():");
shouldBeFalse("event.cancelable");
checkMetadataEmpty();
evalAndLog("request = newConnection()");
request.onupgradeneeded = addIDBObjects;
request.onsuccess = unexpectedSuccessCallback;
request.onerror = testSetVersionAbort4;
}
function addIDBObjects()
{
debug("addIDBObjects():");
db = event.target.result;
shouldBeFalse("event.cancelable");
var trans = evalAndLog("trans = event.target.transaction");
shouldBeNonNull("trans");
trans.onabort = testInactiveAbortedTransaction;
trans.oncomplete = unexpectedCompleteCallback;
store = evalAndLog("store = db.createObjectStore('storeFail', null)");
index = evalAndLog("index = store.createIndex('indexFail', 'x')");
trans.abort();
}
function testInactiveAbortedTransaction()
{
debug("");
debug("testInactiveAbortedTransaction():");
evalAndExpectException("index.openCursor()", "11", "'InvalidStateError'");
evalAndExpectException("index.openKeyCursor()", "11", "'InvalidStateError'");
evalAndExpectException("index.get(0)", "11", "'InvalidStateError'");
evalAndExpectException("index.getKey(0)", "11", "'InvalidStateError'");
evalAndExpectException("index.count()", "11", "'InvalidStateError'");
evalAndExpectException("store.put(0, 0)", "11", "'InvalidStateError'");
evalAndExpectException("store.add(0, 0)", "11", "'InvalidStateError'");
evalAndExpectException("store.delete(0)", "11", "'InvalidStateError'");
evalAndExpectException("store.clear()", "11", "'InvalidStateError'");
evalAndExpectException("store.get(0)", "11", "'InvalidStateError'");
evalAndExpectException("store.openCursor()", "11", "'InvalidStateError'");
}
function testSetVersionAbort4()
{
debug("");
debug("testSetVersionAbort4():");
checkMetadataEmpty();
evalAndLog("request = newConnection()");
request.onupgradeneeded = addIDBObjectsAndCommit;
request.onerror = unexpectedErrorCallback;
request.onsuccess = testSetVersionAbort5;
}
function addIDBObjectsAndCommit()
{
db = event.target.result;
debug("addIDBObjectsAndCommit():");
var trans = evalAndLog("trans = event.target.transaction");
shouldBeNonNull("trans");
trans.onabort = unexpectedAbortCallback;
store = evalAndLog("store = db.createObjectStore('storeFail', null)");
index = evalAndLog("index = store.createIndex('indexFail', 'x')");
trans.oncomplete = testInactiveCompletedTransaction;
}
function testInactiveCompletedTransaction()
{
debug("");
debug("testInactiveCompletedTransaction():");
evalAndExpectException("index.openCursor()", "0", "'TransactionInactiveError'");
evalAndExpectException("index.openKeyCursor()", "0", "'TransactionInactiveError'");
evalAndExpectException("index.get(0)", "0", "'TransactionInactiveError'");
evalAndExpectException("index.getKey(0)", "0", "'TransactionInactiveError'");
evalAndExpectException("index.count()", "0", "'TransactionInactiveError'");
evalAndExpectException("store.put(0, 0)", "0", "'TransactionInactiveError'");
evalAndExpectException("store.add(0, 0)", "0", "'TransactionInactiveError'");
evalAndExpectException("store.delete(0)", "0", "'TransactionInactiveError'");
evalAndExpectException("store.clear()", "0", "'TransactionInactiveError'");
evalAndExpectException("store.get(0)", "0", "'TransactionInactiveError'");
evalAndExpectException("store.openCursor()", "0", "'TransactionInactiveError'");
}
function testSetVersionAbort5()
{
debug("");
debug("testSetVersionAbort5():");
checkMetadataExistingObjectStore();
evalAndLog("request = newConnection()");
request.onupgradeneeded = removeIDBObjects;
request.onsuccess = unexpectedSuccessCallback;
request.onerror = testSetVersionAbort6;
}
function removeIDBObjects()
{
db = event.target.result;
debug("removeIDBObjects():");
var trans = evalAndLog("trans = event.target.transaction");
shouldBeNonNull("trans");
trans.oncomplete = unexpectedCompleteCallback;
var store = evalAndLog("store = trans.objectStore('storeFail')");
evalAndLog("store.deleteIndex('indexFail')");
evalAndLog("db.deleteObjectStore('storeFail')");
trans.abort();
}
function testSetVersionAbort6()
{
debug("");
debug("testSetVersionAbort6():");
checkMetadataExistingObjectStore();
evalAndLog("request = newConnection()");
request.onupgradeneeded = setVersionSuccess;
request.onsuccess = completeCallback;
}
function checkMetadataEmpty()
{
shouldBe("self.db.objectStoreNames", "[]");
shouldBe("self.db.objectStoreNames.length", "0");
shouldBe("self.db.objectStoreNames.contains('storeFail')", "false");
}
function checkMetadataExistingObjectStore()
{
shouldBe("db.objectStoreNames", "['storeFail']");
shouldBe("db.objectStoreNames.length", "1");
shouldBe("db.objectStoreNames.contains('storeFail')", "true");
}
var version = 1;
function newConnection()
{
db.close();
var request = evalAndLog("indexedDB.open(dbname, " + (++version) + ")");
request.onerror = unexpectedErrorCallback;
request.onblocked = unexpectedBlockedCallback;
return request;
}
function setVersionSuccess()
{
db = event.target.result;
debug("");
debug("setVersionSuccess():");
evalAndLog("trans = event.target.transaction");
shouldBeNonNull("trans");
trans.onabort = unexpectedAbortCallback;
deleteAllObjectStores(db);
evalAndLog("db.createObjectStore('storeName', null)");
}
function completeCallback()
{
preamble();
shouldBeFalse("event.cancelable");
testPassed("complete event fired");
transaction = evalAndLog("db.transaction(['storeName'])");
transaction.oncomplete = emptyCompleteCallback;
var store = evalAndLog("store = transaction.objectStore('storeName')");
shouldBeEqualToString("store.name", "storeName");
}
function emptyCompleteCallback()
{
testPassed("complete event fired");
testDOMStringList();
}
function testDOMStringList()
{
debug("");
debug("Verifying DOMStringList works as argument for IDBDatabase.transaction()");
debug("db.objectStoreNames is " + db.objectStoreNames);
debug("... which contains: " + JSON.stringify(Array.prototype.slice.call(db.objectStoreNames)));
evalAndLog("transaction = db.transaction(db.objectStoreNames)");
testPassed("no exception thrown");
for (var i = 0; i < db.objectStoreNames.length; ++i) {
shouldBeNonNull("transaction.objectStore(" + JSON.stringify(db.objectStoreNames[i]) + ")");
}
testPassed("all stores present in transaction");
transaction.oncomplete = testInvalidMode;
}
function testInvalidMode()
{
debug("");
debug("Verify that specifying an invalid mode raises an exception");
evalAndExpectExceptionClass("db.transaction(['storeName'], 'lsakjdf')", "TypeError");
testDegenerateNames();
}
function testDegenerateNames()
{
debug("");
debug("Test that null and undefined are treated as strings");
evalAndExpectException("db.transaction(null)", "DOMException.NOT_FOUND_ERR", "'NotFoundError'");
evalAndExpectException("db.transaction(undefined)", "DOMException.NOT_FOUND_ERR", "'NotFoundError'");
evalAndLog("request = newConnection()");
request.onerror = unexpectedErrorCallback;
request.onupgradeneeded = function () {
var trans = request.transaction;
db = event.target.result;
evalAndLog("db.createObjectStore('null')");
evalAndLog("db.createObjectStore('undefined')");
trans.oncomplete = verifyDegenerateNames;
};
function verifyDegenerateNames() {
shouldNotThrow("transaction = db.transaction(null)");
shouldBeNonNull("transaction.objectStore('null')");
shouldNotThrow("transaction = db.transaction(undefined)");
shouldBeNonNull("transaction.objectStore('undefined')");
finishJSTest();
}
}