| <!-- webkit-test-runner [ useEphemeralSession=true ] --> |
| <!DOCTYPE html> |
| <script src="../../resources/js-test.js"></script> |
| <script src="resources/shared.js"></script> |
| <script> |
| |
| description("Verify edge cases that lazy index population in an IndexedDB implementation might reveal."); |
| |
| indexedDBTest(prepareDatabase, verifyPreExistingIndex); |
| function prepareDatabase() |
| { |
| connection = event.target.result; |
| deleteAllObjectStores(connection); |
| evalAndLog("store = connection.createObjectStore('store')"); |
| evalAndLog("store.createIndex('index1', 'name', {unique: true})"); |
| } |
| |
| function verifyPreExistingIndex() |
| { |
| debug("Verify that uniqueness constraints are enforced with a pre-existing index:"); |
| evalAndLog("trans = connection.transaction('store', 'readwrite')"); |
| evalAndLog("store = trans.objectStore('store')"); |
| evalAndLog("request1 = store.put({name: 'bob'}, 1)"); |
| evalAndLog("request2 = store.put({name: 'bob'}, 2)"); |
| evalAndLog("state = 0"); |
| |
| request1.onerror = unexpectedErrorCallback; |
| request1.onsuccess = function () { |
| debug("request1 received success event"); |
| shouldBe("++state", "1"); |
| }; |
| |
| request2.onsuccess = unexpectedSuccessCallback; |
| request2.onerror = function () { |
| debug("request2 received error event"); |
| shouldBe("++state", "2"); |
| }; |
| |
| trans.oncomplete = unexpectedCompleteCallback; |
| trans.onabort = function () { |
| debug("transaction aborted"); |
| shouldBe("++state", "3"); |
| shouldBe("trans.error.name", "'ConstraintError'"); |
| verifyCreateThenPut(); |
| }; |
| } |
| |
| function verifyCreateThenPut() |
| { |
| debug(""); |
| debug("Verify that uniqueness constraints are enforced when index is created before puts:"); |
| |
| evalAndLog("connection.close()"); |
| request = evalAndLog("indexedDB.open(dbname, 2)"); |
| request.onerror = verifyPutThenCreate; |
| request.onblocked = unexpectedBlockedCallback; |
| request.onsuccess = unexpectedSuccessCallback; |
| request.onupgradeneeded = function() { |
| connection = request.result; |
| trans = request.transaction; |
| |
| evalAndLog("deleteAllObjectStores(connection)"); |
| |
| evalAndLog("store = connection.createObjectStore('store')"); |
| evalAndLog("store.createIndex('index2', 'name', {unique: true})"); |
| evalAndLog("request1 = store.put({name: 'carol'}, 1)"); |
| evalAndLog("request2 = store.put({name: 'carol'}, 2)"); |
| evalAndLog("state = 0"); |
| |
| request1.onerror = unexpectedErrorCallback; |
| request1.onsuccess = function () { |
| debug("request1 (index2) received success event"); |
| shouldBe("++state", "1"); |
| }; |
| |
| request2.onsuccess = unexpectedSuccessCallback; |
| request2.onerror = function () { |
| debug("request2 (index2) received error event"); |
| shouldBe("++state", "2"); |
| }; |
| |
| trans.oncomplete = unexpectedCompleteCallback; |
| trans.onabort = function () { |
| debug("transaction aborted"); |
| shouldBe("++state", "3"); |
| shouldBe("trans.error.name", "'ConstraintError'"); |
| }; |
| }; |
| } |
| |
| function verifyPutThenCreate() |
| { |
| debug(""); |
| debug("Verify that uniqueness constraints are enforced when index is created after puts:"); |
| |
| request = evalAndLog("indexedDB.open(dbname, 3)"); |
| request.onerror = verifyPutThenCreateThenPut; |
| request.onblocked = unexpectedBlockedCallback; |
| request.onsuccess = unexpectedSuccessCallback; |
| request.onupgradeneeded = function() { |
| connection = request.result; |
| trans = request.transaction; |
| |
| evalAndLog("deleteAllObjectStores(connection)"); |
| |
| evalAndLog("store = connection.createObjectStore('store')"); |
| evalAndLog("request1 = store.put({name: 'ted'}, 1)"); |
| evalAndLog("request2 = store.put({name: 'ted'}, 2)"); |
| evalAndLog("store.createIndex('index3', 'name', {unique: true})"); |
| evalAndLog("state = 0"); |
| |
| request1.onerror = unexpectedErrorCallback; |
| request1.onsuccess = function () { |
| debug("request1 received success event"); |
| shouldBe("++state", "1"); |
| }; |
| |
| request2.onerror = unexpectedErrorCallback; |
| request2.onsuccess = function () { |
| debug("request2 received success event"); |
| shouldBe("++state", "2"); |
| }; |
| |
| trans.oncomplete = unexpectedCompleteCallback; |
| trans.onabort = function () { |
| debug("transaction aborted"); |
| shouldBe("++state", "3"); |
| shouldBe("trans.error.name", "'ConstraintError'"); |
| }; |
| }; |
| } |
| |
| function verifyPutThenCreateThenPut() |
| { |
| debug(""); |
| debug("Verify that uniqueness constraints are enforced when index is created between puts:"); |
| |
| request = evalAndLog("indexedDB.open(dbname, 4)"); |
| request.onerror = finishJSTest; |
| request.onblocked = unexpectedBlockedCallback; |
| request.onsuccess = unexpectedSuccessCallback; |
| request.onupgradeneeded = function() { |
| connection = request.result; |
| trans = request.transaction; |
| |
| evalAndLog("deleteAllObjectStores(connection)"); |
| |
| evalAndLog("store = connection.createObjectStore('store')"); |
| evalAndLog("request1 = store.put({name: 'alice'}, 1)"); |
| evalAndLog("store.createIndex('index4', 'name', {unique: true})"); |
| evalAndLog("request2 = store.put({name: 'alice'}, 2)"); |
| evalAndLog("state = 0"); |
| |
| request1.onerror = unexpectedErrorCallback; |
| request1.onsuccess = function () { |
| debug("request1 received success event"); |
| shouldBe("++state", "1"); |
| }; |
| |
| request2.onsuccess = unexpectedSuccessCallback; |
| request2.onerror = function () { |
| debug("request2 received error event"); |
| shouldBe("++state", "2"); |
| }; |
| |
| trans.oncomplete = unexpectedCompleteCallback; |
| trans.onabort = function () { |
| debug("transaction aborted"); |
| shouldBe("++state", "3"); |
| shouldBe("trans.error.name", "'ConstraintError'"); |
| }; |
| }; |
| } |
| |
| </script> |