Modern IDB: Split all storage/indexeddb tests into separate HTML + JS format.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Jan 2016 19:32:06 +0000 (19:32 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Jan 2016 19:32:06 +0000 (19:32 +0000)
https://bugs.webkit.org/show_bug.cgi?id=153178

Reviewed by Sam Weinig.

* storage/indexeddb/clone-exception.html:
* storage/indexeddb/closed-cursor.html:
* storage/indexeddb/connection-leak.html:
* storage/indexeddb/cursor-cast.html:
* storage/indexeddb/cursor-leak.html:
* storage/indexeddb/cursor-overloads.html:
* storage/indexeddb/cursor-request-cycle.html:
* storage/indexeddb/deleteIndex-bug110792.html:
* storage/indexeddb/deletedatabase-transaction.html:
* storage/indexeddb/metadata-race.html:
* storage/indexeddb/noblobs.html:
* storage/indexeddb/object-lookups-in-versionchange.html:
* storage/indexeddb/open-bad-versions.html:
* storage/indexeddb/optional-arguments.html:
* storage/indexeddb/prefetch-invalidation.html:
* storage/indexeddb/prefetch-race.html:
* storage/indexeddb/primary-key-unique-to-objectstore.html:
* storage/indexeddb/request-leak.html:
* storage/indexeddb/request-result-cache.html:
* storage/indexeddb/resources/clone-exception.js: Copied from LayoutTests/storage/indexeddb/clone-exception.html.
* storage/indexeddb/resources/closed-cursor.js: Copied from LayoutTests/storage/indexeddb/closed-cursor.html.
* storage/indexeddb/resources/connection-leak.js: Copied from LayoutTests/storage/indexeddb/connection-leak.html.
* storage/indexeddb/resources/cursor-cast.js: Copied from LayoutTests/storage/indexeddb/cursor-cast.html.
* storage/indexeddb/resources/cursor-leak.js: Copied from LayoutTests/storage/indexeddb/cursor-leak.html.
* storage/indexeddb/resources/cursor-overloads.js: Copied from LayoutTests/storage/indexeddb/cursor-overloads.html.
* storage/indexeddb/resources/cursor-request-cycle.js: Copied from LayoutTests/storage/indexeddb/cursor-request-cycle.html.
* storage/indexeddb/resources/deleteIndex-bug110792.js: Copied from LayoutTests/storage/indexeddb/deleteIndex-bug110792.html.
* storage/indexeddb/resources/deletedatabase-transaction.js: Copied from LayoutTests/storage/indexeddb/deletedatabase-transaction.html.
* storage/indexeddb/resources/metadata-race.js: Copied from LayoutTests/storage/indexeddb/metadata-race.html.
* storage/indexeddb/resources/noblobs.js: Copied from LayoutTests/storage/indexeddb/noblobs.html.
* storage/indexeddb/resources/object-lookups-in-versionchange.js: Copied from LayoutTests/storage/indexeddb/object-lookups-in-versionchange.html.
* storage/indexeddb/resources/open-bad-versions.js: Copied from LayoutTests/storage/indexeddb/open-bad-versions.html.
* storage/indexeddb/resources/optional-arguments.js: Copied from LayoutTests/storage/indexeddb/optional-arguments.html.
* storage/indexeddb/resources/prefetch-invalidation.js: Copied from LayoutTests/storage/indexeddb/prefetch-invalidation.html.
* storage/indexeddb/resources/prefetch-race.js: Copied from LayoutTests/storage/indexeddb/prefetch-race.html.
* storage/indexeddb/resources/primary-key-unique-to-objectstore.js: Copied from LayoutTests/storage/indexeddb/primary-key-unique-to-objectstore.html.
* storage/indexeddb/resources/request-leak.js: Copied from LayoutTests/storage/indexeddb/request-leak.html.
* storage/indexeddb/resources/request-result-cache.js: Copied from LayoutTests/storage/indexeddb/request-result-cache.html.
* storage/indexeddb/resources/structured-clone.js: Copied from LayoutTests/storage/indexeddb/structured-clone.html.
* storage/indexeddb/resources/transaction-complete-with-js-recursion-cross-frame.js: Copied from LayoutTests/storage/indexeddb/transaction-complete-with-js-recursion-cross-frame.html.
* storage/indexeddb/resources/transaction-complete-with-js-recursion.js: Copied from LayoutTests/storage/indexeddb/transaction-complete-with-js-recursion.html.
* storage/indexeddb/resources/transaction-crash-in-tasks.js: Copied from LayoutTests/storage/indexeddb/transaction-crash-in-tasks.html.
* storage/indexeddb/resources/transaction-ordering.js: Copied from LayoutTests/storage/indexeddb/transaction-ordering.html.
* storage/indexeddb/resources/transaction-overlapping.js: Copied from LayoutTests/storage/indexeddb/transaction-overlapping.html.
* storage/indexeddb/resources/version-change-event-basic.js: Copied from LayoutTests/storage/indexeddb/version-change-event-basic.html.
* storage/indexeddb/resources/version-change-event.js: Copied from LayoutTests/storage/indexeddb/version-change-event.html.
* storage/indexeddb/structured-clone.html:
* storage/indexeddb/transaction-complete-with-js-recursion-cross-frame.html:
* storage/indexeddb/transaction-complete-with-js-recursion.html:
* storage/indexeddb/transaction-crash-in-tasks.html:
* storage/indexeddb/transaction-ordering.html:
* storage/indexeddb/transaction-overlapping.html:
* storage/indexeddb/transaction-starvation.html:
* storage/indexeddb/version-change-event-basic.html:
* storage/indexeddb/version-change-event.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@195299 268f45cc-cd09-0410-ab3c-d52691b4dbfc

56 files changed:
LayoutTests/ChangeLog
LayoutTests/storage/indexeddb/clone-exception.html
LayoutTests/storage/indexeddb/closed-cursor.html
LayoutTests/storage/indexeddb/connection-leak.html
LayoutTests/storage/indexeddb/cursor-cast.html
LayoutTests/storage/indexeddb/cursor-leak.html
LayoutTests/storage/indexeddb/cursor-overloads.html
LayoutTests/storage/indexeddb/cursor-request-cycle.html
LayoutTests/storage/indexeddb/deleteIndex-bug110792.html
LayoutTests/storage/indexeddb/deletedatabase-transaction.html
LayoutTests/storage/indexeddb/metadata-race.html
LayoutTests/storage/indexeddb/noblobs.html
LayoutTests/storage/indexeddb/object-lookups-in-versionchange.html
LayoutTests/storage/indexeddb/open-bad-versions.html
LayoutTests/storage/indexeddb/optional-arguments.html
LayoutTests/storage/indexeddb/prefetch-invalidation.html
LayoutTests/storage/indexeddb/prefetch-race.html
LayoutTests/storage/indexeddb/primary-key-unique-to-objectstore.html
LayoutTests/storage/indexeddb/request-leak.html
LayoutTests/storage/indexeddb/request-result-cache.html
LayoutTests/storage/indexeddb/resources/clone-exception.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/closed-cursor.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/connection-leak.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/cursor-cast.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/cursor-leak.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/cursor-overloads.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/cursor-request-cycle.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/deleteIndex-bug110792.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/deletedatabase-transaction.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/metadata-race.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/noblobs.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/object-lookups-in-versionchange.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/open-bad-versions.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/optional-arguments.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/prefetch-invalidation.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/prefetch-race.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/primary-key-unique-to-objectstore.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/request-leak.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/request-result-cache.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/structured-clone.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/transaction-complete-with-js-recursion-cross-frame.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/transaction-complete-with-js-recursion.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/transaction-crash-in-tasks.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/transaction-ordering.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/transaction-overlapping.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/version-change-event-basic.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/version-change-event.js [new file with mode: 0644]
LayoutTests/storage/indexeddb/structured-clone.html
LayoutTests/storage/indexeddb/transaction-complete-with-js-recursion-cross-frame.html
LayoutTests/storage/indexeddb/transaction-complete-with-js-recursion.html
LayoutTests/storage/indexeddb/transaction-crash-in-tasks.html
LayoutTests/storage/indexeddb/transaction-ordering.html
LayoutTests/storage/indexeddb/transaction-overlapping.html
LayoutTests/storage/indexeddb/transaction-starvation.html
LayoutTests/storage/indexeddb/version-change-event-basic.html
LayoutTests/storage/indexeddb/version-change-event.html

index 1583faf..86dd08a 100644 (file)
@@ -1,3 +1,66 @@
+2016-01-19  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: Split all storage/indexeddb tests into separate HTML + JS format.
+        https://bugs.webkit.org/show_bug.cgi?id=153178
+
+        Reviewed by Sam Weinig.
+
+        * storage/indexeddb/clone-exception.html:
+        * storage/indexeddb/closed-cursor.html:
+        * storage/indexeddb/connection-leak.html:
+        * storage/indexeddb/cursor-cast.html:
+        * storage/indexeddb/cursor-leak.html:
+        * storage/indexeddb/cursor-overloads.html:
+        * storage/indexeddb/cursor-request-cycle.html:
+        * storage/indexeddb/deleteIndex-bug110792.html:
+        * storage/indexeddb/deletedatabase-transaction.html:
+        * storage/indexeddb/metadata-race.html:
+        * storage/indexeddb/noblobs.html:
+        * storage/indexeddb/object-lookups-in-versionchange.html:
+        * storage/indexeddb/open-bad-versions.html:
+        * storage/indexeddb/optional-arguments.html:
+        * storage/indexeddb/prefetch-invalidation.html:
+        * storage/indexeddb/prefetch-race.html:
+        * storage/indexeddb/primary-key-unique-to-objectstore.html:
+        * storage/indexeddb/request-leak.html:
+        * storage/indexeddb/request-result-cache.html:
+        * storage/indexeddb/resources/clone-exception.js: Copied from LayoutTests/storage/indexeddb/clone-exception.html.
+        * storage/indexeddb/resources/closed-cursor.js: Copied from LayoutTests/storage/indexeddb/closed-cursor.html.
+        * storage/indexeddb/resources/connection-leak.js: Copied from LayoutTests/storage/indexeddb/connection-leak.html.
+        * storage/indexeddb/resources/cursor-cast.js: Copied from LayoutTests/storage/indexeddb/cursor-cast.html.
+        * storage/indexeddb/resources/cursor-leak.js: Copied from LayoutTests/storage/indexeddb/cursor-leak.html.
+        * storage/indexeddb/resources/cursor-overloads.js: Copied from LayoutTests/storage/indexeddb/cursor-overloads.html.
+        * storage/indexeddb/resources/cursor-request-cycle.js: Copied from LayoutTests/storage/indexeddb/cursor-request-cycle.html.
+        * storage/indexeddb/resources/deleteIndex-bug110792.js: Copied from LayoutTests/storage/indexeddb/deleteIndex-bug110792.html.
+        * storage/indexeddb/resources/deletedatabase-transaction.js: Copied from LayoutTests/storage/indexeddb/deletedatabase-transaction.html.
+        * storage/indexeddb/resources/metadata-race.js: Copied from LayoutTests/storage/indexeddb/metadata-race.html.
+        * storage/indexeddb/resources/noblobs.js: Copied from LayoutTests/storage/indexeddb/noblobs.html.
+        * storage/indexeddb/resources/object-lookups-in-versionchange.js: Copied from LayoutTests/storage/indexeddb/object-lookups-in-versionchange.html.
+        * storage/indexeddb/resources/open-bad-versions.js: Copied from LayoutTests/storage/indexeddb/open-bad-versions.html.
+        * storage/indexeddb/resources/optional-arguments.js: Copied from LayoutTests/storage/indexeddb/optional-arguments.html.
+        * storage/indexeddb/resources/prefetch-invalidation.js: Copied from LayoutTests/storage/indexeddb/prefetch-invalidation.html.
+        * storage/indexeddb/resources/prefetch-race.js: Copied from LayoutTests/storage/indexeddb/prefetch-race.html.
+        * storage/indexeddb/resources/primary-key-unique-to-objectstore.js: Copied from LayoutTests/storage/indexeddb/primary-key-unique-to-objectstore.html.
+        * storage/indexeddb/resources/request-leak.js: Copied from LayoutTests/storage/indexeddb/request-leak.html.
+        * storage/indexeddb/resources/request-result-cache.js: Copied from LayoutTests/storage/indexeddb/request-result-cache.html.
+        * storage/indexeddb/resources/structured-clone.js: Copied from LayoutTests/storage/indexeddb/structured-clone.html.
+        * storage/indexeddb/resources/transaction-complete-with-js-recursion-cross-frame.js: Copied from LayoutTests/storage/indexeddb/transaction-complete-with-js-recursion-cross-frame.html.
+        * storage/indexeddb/resources/transaction-complete-with-js-recursion.js: Copied from LayoutTests/storage/indexeddb/transaction-complete-with-js-recursion.html.
+        * storage/indexeddb/resources/transaction-crash-in-tasks.js: Copied from LayoutTests/storage/indexeddb/transaction-crash-in-tasks.html.
+        * storage/indexeddb/resources/transaction-ordering.js: Copied from LayoutTests/storage/indexeddb/transaction-ordering.html.
+        * storage/indexeddb/resources/transaction-overlapping.js: Copied from LayoutTests/storage/indexeddb/transaction-overlapping.html.
+        * storage/indexeddb/resources/version-change-event-basic.js: Copied from LayoutTests/storage/indexeddb/version-change-event-basic.html.
+        * storage/indexeddb/resources/version-change-event.js: Copied from LayoutTests/storage/indexeddb/version-change-event.html.
+        * storage/indexeddb/structured-clone.html:
+        * storage/indexeddb/transaction-complete-with-js-recursion-cross-frame.html:
+        * storage/indexeddb/transaction-complete-with-js-recursion.html:
+        * storage/indexeddb/transaction-crash-in-tasks.html:
+        * storage/indexeddb/transaction-ordering.html:
+        * storage/indexeddb/transaction-overlapping.html:
+        * storage/indexeddb/transaction-starvation.html:
+        * storage/indexeddb/version-change-event-basic.html:
+        * storage/indexeddb/version-change-event.html:
+
 2016-01-19  Javier Fernandez  <jfernandez@igalia.com>
 
         [css-grid][css-align] justify-self stretch is not applied for img elements
index a37d834..9b75944 100644 (file)
@@ -1,50 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-
-description("Ensure DataCloneError is consistently thrown by IndexedDB methods");
-
-var NON_CLONEABLE = self;
-var INVALID_KEY = {};
-
-setDBNameFromPath();
-doFirstOpen();
-
-function doFirstOpen()
-{
-    preamble();
-    request = evalAndLog("indexedDB.open(dbname + '1')");
-    request.onupgradeneeded = function onUpgradeNeeded(e) {
-        preamble();
-        db = e.target.result;
-        evalAndExpectException("db.createObjectStore('store').put(NON_CLONEABLE, 0);", "25", "'DataCloneError'");
-        doSecondOpen();
-    };
-}
-
-function doSecondOpen()
-{
-    preamble();
-    request = evalAndLog("indexedDB.open(dbname + '2')");
-    request.onupgradeneeded = function onUpgradeNeeded(e) {
-        preamble();
-        db = e.target.result;
-        evalAndExpectException("db.createObjectStore('store').put(NON_CLONEABLE, 0);", "25", "'DataCloneError'");
-        doThirdOpen();
-    };
-}
-
-function doThirdOpen()
-{
-    preamble();
-    request = evalAndLog("indexedDB.open(dbname + '3')");
-    request.onupgradeneeded = function onUpgradeNeeded(e) {
-        preamble();
-        db = e.target.result;
-        evalAndExpectException("db.createObjectStore('store').put(NON_CLONEABLE, INVALID_KEY);", "25", "'DataCloneError'");
-        finishJSTest();
-    };
-}
-
-</script>
+</head>
+<body>
+<script src="resources/clone-exception.js"></script>
+</body>
+</html>
index a307620..cfd3abc 100644 (file)
@@ -1,38 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-
-description("Verify that that cursors accessed after being closed are well behaved");
-
-indexedDBTest(prepareDatabase, onOpen);
-function prepareDatabase(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("store = db.createObjectStore('store')");
-    evalAndLog("store.put({value: 'value'}, ['key'])");
-}
-
-function onOpen(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("tx = db.transaction('store')");
-    evalAndLog("store = tx.objectStore('store')");
-    evalAndLog("cursorRequest = store.openCursor()");
-    cursorRequest.onsuccess = function openCursorSuccess(evt) {
-        preamble(evt);
-        evalAndLog("cursor = cursorRequest.result");
-        debug("Don't continue the cursor, so it retains its key/primaryKey/value");
-    };
-    tx.oncomplete = function transactionComplete(evt) {
-        preamble(evt);
-        shouldBeEqualToString("JSON.stringify(cursor.key)", '["key"]');
-        shouldBeEqualToString("JSON.stringify(cursor.primaryKey)", '["key"]');
-        shouldBeEqualToString("JSON.stringify(cursor.value)", '{"value":"value"}');
-        finishJSTest();
-    };
-}
-
-</script>
+</head>
+<body>
+<script src="resources/closed-cursor.js"></script>
+</body>
+</html>
index 38906a9..c6d8950 100644 (file)
@@ -1,78 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-
-description("Regression test to ensure that IndexedDB connections don't leak");
-
-setDBNameFromPath();
-doFirstOpen();
-
-function doFirstOpen()
-{
-    preamble();
-
-    evalAndLog("request = indexedDB.open(dbname, 1)");
-    evalAndLog("sawUpgradeNeeded1 = false");
-    request.onerror = unexpectedErrorCallback;
-    request.onblocked = unexpectedBlockedCallback;
-    request.onupgradeneeded = function onUpgradeNeeded1() {
-        preamble();
-        evalAndLog("sawUpgradeNeeded1 = true");
-    };
-    request.onsuccess = function onOpenSuccess1() {
-        preamble();
-        shouldBeTrue("sawUpgradeNeeded1");
-        evalAndLog("db = request.result");
-        evalAndLog("db.close()");
-
-        doSecondOpen();
-    };
-}
-
-function doSecondOpen()
-{
-    preamble();
-
-    evalAndLog("request = indexedDB.open(dbname, 1)");
-    request.onerror = unexpectedErrorCallback;
-    request.onblocked = unexpectedBlockedCallback;
-    request.onupgradeneeded = unexpectedUpgradeNeededCallback;
-    request.onsuccess = function onOpenSuccess2() {
-        preamble();
-        evalAndLog("db = request.result");
-
-        evalAndLog("db = null");
-        evalAndLog("request = null");
-
-        debug("Run GC outside of request's callback via setTimeout()");
-        setTimeout( function() {
-            evalAndLog("window.gc()");
-            doThirdOpen();
-        }, 0);
-    };
-}
-
-function doThirdOpen()
-{
-    preamble();
-
-    evalAndLog("request = indexedDB.open(dbname, 2)");
-    evalAndLog("sawUpgradeNeeded3 = false");
-    request.onerror = unexpectedErrorCallback;
-    request.onblocked = unexpectedBlockedCallback;
-    request.onupgradeneeded = function onUpgradeNeeded2() {
-        preamble();
-        evalAndLog("sawUpgradeNeeded3 = true");
-    };
-    request.onsuccess = function onOpenSuccess3() {
-        preamble();
-        shouldBeTrue("sawUpgradeNeeded3");
-        evalAndLog("db = request.result");
-        evalAndLog("db.close()");
-
-        finishJSTest();
-    };
-}
-
-</script>
+</head>
+<body>
+<script src="resources/connection-leak.js"></script>
+</body>
+</html>
index bd62a3b..34ab83d 100644 (file)
@@ -1,44 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-
-description("Ensure cursor wrappers are created correctly.");
-
-indexedDBTest(prepareDatabase, verifyWrappers);
-function prepareDatabase(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("store = db.createObjectStore('store')");
-    evalAndLog("store.put(0, 0)");
-}
-
-function verifyWrappers(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("tx = db.transaction('store', 'readwrite')");
-    evalAndLog("request = tx.objectStore('store').openCursor()");
-
-    request.onsuccess = function onOpenCursorSuccess(evt) {
-        preamble(evt);
-        evalAndLog("cursor = event.target.result");
-        evalAndLog("request = cursor.update(1)");
-
-        request.onsuccess = function onUpdateSuccess(evt) {
-            preamble(evt);
-            evalAndLog("cursor = null");
-            gc();
-            gc(); // FIXME: Shouldn't need to call twice. http://crbug.com/288072
-            setTimeout(checkCursorType, 0);
-        };
-    };
-}
-
-function checkCursorType() {
-    shouldBeEqualToString("request.source.toString()", "[object IDBCursorWithValue]");
-    finishJSTest();
-}
-
-</script>
+</head>
+<body>
+<script src="resources/cursor-cast.js"></script>
+</body>
+</html>
index abeabf8..3dbbcc9 100644 (file)
@@ -1,56 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-
-description("Verify that that cursors weakly hold script value properties");
-
-if (window.internals) {
-    indexedDBTest(prepareDatabase, onOpen);
-} else {
-    testFailed('This test requires access to the Internals object');
-    finishJSTest();
-}
-
-function prepareDatabase(evt)
-{
-    db = event.target.result;
-    store = db.createObjectStore('store');
-    store.put({value: 'value'}, ['key']);
-}
-
-function onOpen(evt)
-{
-    // evalAndLog() is not used as that generates new DOM nodes.
-
-    db = evt.target.result;
-    tx = db.transaction('store');
-    store = tx.objectStore('store');
-    cursorRequest = store.openCursor();
-    cursorRequest.onsuccess = function() {
-        cursor = cursorRequest.result;
-    };
-    tx.oncomplete = function() {
-        db.close();
-
-        // Try and induce a leak by a reference cycle from DOM to V8 and back.
-        // If the v8 value of cursor.key (etc) is only held by the cursor's
-        // V8 wrapper then there will be no leak.
-        cursor.key.cursor = cursor;
-        cursor.primaryKey.cursor = cursor;
-        cursor.value.cursor = cursor;
-
-        cursorObserver = internals.observeGC(cursor);
-
-        cursorRequest = null;
-        cursor = null;
-
-        gc();
-
-        shouldBeTrue("cursorObserver.wasCollected");
-        finishJSTest();
-    };
-}
-
-
-</script>
+</head>
+<body>
+<script src="resources/cursor-leak.js"></script>
+</body>
+</html>
index 74ae526..15eb610 100644 (file)
@@ -1,78 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-description("Validate the overloads of IDBObjectStore.openCursor(), IDBIndex.openCursor() and IDBIndex.openKeyCursor().");
-
-indexedDBTest(prepareDatabase, verifyOverloads);
-function prepareDatabase()
-{
-    db = event.target.result;
-    event.target.transaction.onabort = unexpectedAbortCallback;
-    evalAndLog("store = db.createObjectStore('store')");
-    evalAndLog("index = store.createIndex('index', 'value')");
-    evalAndLog("store.put({value: 0}, 0)");
-}
-
-function verifyOverloads()
-{
-    debug("");
-    debug("verifyOverloads():");
-    evalAndLog("trans = db.transaction('store')");
-    evalAndLog("store = trans.objectStore('store')");
-    evalAndLog("index = store.index('index')");
-
-    checkCursorDirection("store.openCursor()", "next");
-    checkCursorDirection("store.openCursor(0)", "next");
-    checkCursorDirection("store.openCursor(0, 'next')", "next");
-    checkCursorDirection("store.openCursor(0, 'nextunique')", "nextunique");
-    checkCursorDirection("store.openCursor(0, 'prev')", "prev");
-    checkCursorDirection("store.openCursor(0, 'prevunique')", "prevunique");
-
-    checkCursorDirection("store.openCursor(IDBKeyRange.only(0))", "next");
-    checkCursorDirection("store.openCursor(IDBKeyRange.only(0), 'next')", "next");
-    checkCursorDirection("store.openCursor(IDBKeyRange.only(0), 'nextunique')", "nextunique");
-    checkCursorDirection("store.openCursor(IDBKeyRange.only(0), 'prev')", "prev");
-    checkCursorDirection("store.openCursor(IDBKeyRange.only(0), 'prevunique')", "prevunique");
-
-    checkCursorDirection("index.openCursor()", "next");
-    checkCursorDirection("index.openCursor(0)", "next");
-    checkCursorDirection("index.openCursor(0, 'next')", "next");
-    checkCursorDirection("index.openCursor(0, 'nextunique')", "nextunique");
-    checkCursorDirection("index.openCursor(0, 'prev')", "prev");
-    checkCursorDirection("index.openCursor(0, 'prevunique')", "prevunique");
-
-    checkCursorDirection("index.openCursor(IDBKeyRange.only(0))", "next");
-    checkCursorDirection("index.openCursor(IDBKeyRange.only(0), 'next')", "next");
-    checkCursorDirection("index.openCursor(IDBKeyRange.only(0), 'nextunique')", "nextunique");
-    checkCursorDirection("index.openCursor(IDBKeyRange.only(0), 'prev')", "prev");
-    checkCursorDirection("index.openCursor(IDBKeyRange.only(0), 'prevunique')", "prevunique");
-
-    checkCursorDirection("index.openKeyCursor()", "next");
-    checkCursorDirection("index.openKeyCursor(0)", "next");
-    checkCursorDirection("index.openKeyCursor(0, 'next')", "next");
-    checkCursorDirection("index.openKeyCursor(0, 'nextunique')", "nextunique");
-    checkCursorDirection("index.openKeyCursor(0, 'prev')", "prev");
-    checkCursorDirection("index.openKeyCursor(0, 'prevunique')", "prevunique");
-
-    checkCursorDirection("index.openKeyCursor(IDBKeyRange.only(0))", "next");
-    checkCursorDirection("index.openKeyCursor(IDBKeyRange.only(0), 'next')", "next");
-    checkCursorDirection("index.openKeyCursor(IDBKeyRange.only(0), 'nextunique')", "nextunique");
-    checkCursorDirection("index.openKeyCursor(IDBKeyRange.only(0), 'prev')", "prev");
-    checkCursorDirection("index.openKeyCursor(IDBKeyRange.only(0), 'prevunique')", "prevunique");
-
-    trans.oncomplete = finishJSTest;
-}
-
-function checkCursorDirection(statement, direction)
-{
-    request = eval(statement);
-    request.onerror = unexpectedErrorCallback;
-    request.onsuccess = function() {
-        debug(statement);
-        shouldBeNonNull("event.target.result")
-        shouldBeEqualToString("event.target.result.direction", direction);
-    };
-}
-
-</script>
+</head>
+<body>
+<script src="resources/cursor-overloads.js"></script>
+</body>
+</html>
index 4f65843..df96c28 100644 (file)
@@ -1,88 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-
-description("Verify that that cursors weakly hold request, and work if request is GC'd");
-
-indexedDBTest(prepareDatabase, onOpen);
-
-function prepareDatabase(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("store = db.createObjectStore('store')");
-    store.put("value1", "key1");
-    store.put("value2", "key2");
-}
-
-function onOpen(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("tx = db.transaction('store')");
-    evalAndLog("store = tx.objectStore('store')");
-
-    evalAndLog("cursorRequest = store.openCursor()");
-    cursorRequest.onsuccess = function openCursorRequestSuccess(evt) {
-        preamble(evt);
-        debug("Result will be checked later, to ensure that lazy access is safe");
-    };
-
-    evalAndLog("otherRequest = store.get(0)");
-    otherRequest.onsuccess = function otherRequestSuccess(evt) {
-        preamble(evt);
-
-        debug("Verify that the request's result can be accessed lazily:");
-        evalAndLog("gc()");
-
-        evalAndLog("cursor = cursorRequest.result");
-        shouldBeNonNull("cursor");
-        shouldBeEqualToString("cursor.key", "key1");
-        shouldBeEqualToString("cursor.value", "value1");
-        evalAndLog("cursorRequest.extra = 123");
-        evalAndLog("cursor.extra = 456");
-
-        // Assign a new handler to inspect the request and cursor indirectly.
-        cursorRequest.onsuccess = function cursorContinueSuccess(evt) {
-            preamble(evt);
-            evalAndLog("cursor = event.target.result");
-            shouldBeNonNull("cursor");
-            shouldBeEqualToString("cursor.key", "key2");
-            shouldBeEqualToString("cursor.value", "value2");
-            shouldBe("event.target.extra", "123");
-            shouldBe("cursor.extra", "456");
-        };
-
-        debug("Ensure request is not released if cursor is still around.");
-        cursorRequestObservation = internals.observeGC(cursorRequest);
-        evalAndLog("cursorRequest = null");
-        evalAndLog("gc()");
-        shouldBeFalse("cursorRequestObservation.wasCollected");
-
-        evalAndLog("cursor.continue()");
-
-        cursorObservation = internals.observeGC(cursor);
-        evalAndLog("cursor = null");
-        evalAndLog("gc()");
-        shouldBeFalse("cursorObservation.wasCollected");
-
-        evalAndLog("finalRequest = store.get(0)");
-        finalRequest.onsuccess = function finalRequestSuccess(evt) {
-            preamble(evt);
-            shouldBeEqualToString("cursor.key", "key2");
-            shouldBeEqualToString("cursor.value", "value2");
-
-            cursorObservation = internals.observeGC(cursor);
-            evalAndLog("cursor = null");
-            evalAndLog("gc()");
-            shouldBeTrue("cursorRequestObservation.wasCollected");
-            shouldBeTrue("cursorObservation.wasCollected");
-        };
-    };
-
-    tx.oncomplete = finishJSTest;
-}
-
-
-</script>
+</head>
+<body>
+<script src="resources/cursor-request-cycle.js"></script>
+</body>
+</html>
index 81af3cd..3e8d172 100644 (file)
@@ -1,41 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-
-description("Ensure IndexedDB's IDBObjectStore.deleteIndex() works if IDBIndex object has not been fetched - regression test for bug 110792.");
-
-indexedDBTest(onFirstUpgradeNeeded, closeAndReOpen, {version: 1});
-
-function onFirstUpgradeNeeded(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("store = db.createObjectStore('store')");
-    evalAndLog("store.createIndex('index', 'keyPath')");
-}
-
-function closeAndReOpen()
-{
-    preamble();
-    evalAndLog("db.close()");
-    debug("");
-    request = evalAndLog("indexedDB.open(dbname, 2)");
-    request.onblocked = unexpectedBlockedCallback;
-    request.onerror = unexpectedErrorCallback;
-    request.onupgradeneeded = onSecondUpgradeNeeded;
-    request.onsuccess = finishJSTest;
-}
-
-function onSecondUpgradeNeeded(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("store = event.target.transaction.objectStore('store')");
-    // Do NOT add a call to store.index('index') here (e.g. to assert it exists)
-    // or the bug disappears.
-    evalAndLog("store.deleteIndex('index')");
-    evalAndExpectException("store.index('index')", "DOMException.NOT_FOUND_ERR", "'NotFoundError'");
-}
-
-</script>
+</head>
+<body>
+<script src="resources/deleteIndex-bug110792.js"></script>
+</body>
+</html>
index 67b4af6..7238269 100644 (file)
@@ -1,33 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-description("Ensure deleteDatabase() can run concurrently with transactions in other databases");
-
-indexedDBTest(prepareDatabase, startTransaction);
-function prepareDatabase()
-{
-    db = event.target.result;
-    evalAndLog("db.createObjectStore('store')");
-}
-
-function startTransaction() {
-    debug("");
-    debug("Start a transaction against the first database:");
-    evalAndLog("trans = db.transaction('store', 'readonly')");
-    evalAndLog("trans.objectStore('store').get(0)");
-
-    debug("");
-    debug("Delete a different database:");
-    evalAndLog("dbname2 = dbname + '2'");
-    request = evalAndLog("indexedDB.deleteDatabase(dbname2)");
-    request.onblocked = unexpectedBlockedCallback;
-    request.onerror = unexpectedErrorCallback;
-    request.onsuccess = function() {
-        testPassed("success event was fired at delete request");
-    };
-
-    trans.oncomplete = finishJSTest;
-}
-
-</script>
+</head>
+<body>
+<script src="resources/deletedatabase-transaction.js"></script>
+</body>
+</html>
index 381e412..70478fd 100644 (file)
@@ -1,39 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-
-description("Ensure IndexedDB transactions created before open onsuccess have correct metadata");
-
-indexedDBTest(prepareDatabase, onOpenSuccess);
-function prepareDatabase(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("store = db.createObjectStore('store')");
-    evalAndLog("store.createIndex('index', 'keyPath')");
-    evalAndLog("transaction = event.target.transaction");
-    shouldNotThrow("index = transaction.objectStore('store').index('index')");
-    transaction.oncomplete = onTransactionComplete;
-}
-
-function onTransactionComplete(evt)
-{
-    preamble(evt);
-    debug("In multiprocess mode, 'complete' event may be dispatched before\n" +
-          "the 'success' arrives with updated metadata. Ensure the new metadata\n" +
-          "is still used for transactions.");
-    evalAndLog("store = db.transaction('store').objectStore('store')");
-    shouldNotThrow("index = store.index('index')");
-}
-
-function onOpenSuccess(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("store = db.transaction('store').objectStore('store')");
-    shouldNotThrow("index = store.index('index')");
-    finishJSTest();
-}
-
-</script>
+</head>
+<body>
+<script src="resources/metadata-race.js"></script>
+</body>
+</html>
index fa767fe..4281749 100644 (file)
@@ -5,82 +5,6 @@
 </head>
 <body>
 <input type="file" id="fileInput" multiple></input>
-<script>
-
-description("Confirm Blob/File/FileList limitations of WebKit's IndexedDB implementation.");
-// FIXME: This verifies that blob-type data is rejected for now, rather than silently failing.
-// Tracked for the Chromium port as: http://crbug.com/108012
-
-fileInput = document.getElementById("fileInput");
-if (window.eventSender) {
-    var fileRect = fileInput.getClientRects()[0];
-    var targetX = fileRect.left + fileRect.width / 2;
-    var targetY = fileRect.top + fileRect.height / 2;
-    eventSender.beginDragWithFiles(['resources/test-data.html', 'resources/test-data.txt']);
-    eventSender.mouseMoveTo(targetX, targetY);
-    eventSender.mouseUp();
-}
-
-function prepareDatabase()
-{
-    db = event.target.result;
-    var trans = event.target.transaction;
-    evalAndLog("store = db.createObjectStore('storeName')");
-    evalAndLog("store.put('value', 'key')");
-    trans.onerror = unexpectedErrorCallback;
-    trans.onabort = unexpectedAbortCallback;
-}
-
-function testBlob()
-{
-    debug("");
-    debug("testBlob():");
-
-    shouldBeTrue("FileReader != null");
-    evalAndLog("test_content = 'This is a test. This is only a test.'");
-    evalAndLog("blob = new Blob([test_content])");
-    validateExceptions("blob", testFile);
-}
-
-function testFile()
-{
-    debug("");
-    debug("testFile():");
-    evalAndLog("file = fileInput.files[0]");
-    validateExceptions("file", testFileList);
-}
-
-function testFileList()
-{
-    debug("");
-    debug("testFileList():");
-    evalAndLog("filelist = fileInput.files");
-    validateExceptions("filelist", finishJSTest);
-}
-
-function validateExceptions(variable, onComplete)
-{
-    debug("");
-    debug("validateExceptions(" + variable + "):");
-    evalAndLog("transaction = db.transaction('storeName', 'readwrite')");
-    evalAndLog("store = transaction.objectStore('storeName')");
-    evalAndExpectException("store.put(" + variable + ", 'key')", "DOMException.DATA_CLONE_ERR");
-    evalAndExpectException("store.add(" + variable + ", 'key')", "DOMException.DATA_CLONE_ERR");
-    evalAndLog("request = store.openCursor()");
-    request.onsuccess = function () {
-        evalAndLog("cursor = request.result");
-        evalAndExpectException("cursor.update(" + variable + ")", "DOMException.DATA_CLONE_ERR");
-    };
-    transaction.oncomplete = onComplete;
-}
-
-if (window.eventSender) {
-    indexedDBTest(prepareDatabase, testBlob);
-} else {
-    alert("Select file(s) using the input control above to initiate the test");
-    document.getElementById("fileInput").onchange = function() { indexedDBTest(prepareDatabase, testBlob); };
-}
-
-</script>
+<script src="resources/noblobs.js"></script>
 </body>
 </html>
index 7fd4af1..b20a025 100644 (file)
@@ -1,20 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-
-description("Regression test for http://webkit.org/b/102547");
-
-indexedDBTest(prepareDatabase, finishJSTest);
-
-function prepareDatabase() {
-    evalAndLog("db = event.target.result");
-    evalAndLog("transaction = event.target.transaction");
-    evalAndLog("store = db.createObjectStore('store')");
-    debug("");
-    evalAndExpectException("transaction.objectStore('no-such-store')", "DOMException.NOT_FOUND_ERR", "'NotFoundError'");
-    debug("");
-    evalAndExpectException("store.index('no-such-index')", "DOMException.NOT_FOUND_ERR", "'NotFoundError'");
-}
-
-</script>
+</head>
+<body>
+<script src="resources/object-lookups-in-versionchange.js"></script>
+</body>
+</html>
index 963921b..1acbc5f 100644 (file)
@@ -4,30 +4,6 @@
 <script src="resources/shared.js"></script>
 </head>
 <body>
-<script>
-
-description("No crashes when opening and reloading with bad version numbers");
-
-function test()
-{
-  removeVendorPrefixes();
-  evalAndLog("dbname = String(window.location)");
-
-  try { indexedDB.open(dbname, -1); } catch (e) { }
-  indexedDB.open(dbname, 2);
-  try { indexedDB.open(dbname, -1); } catch (e) { }
-
-  setTimeout(function() {
-    if (!window.location.search) {
-      window.location = window.location + "?2";
-    } else {
-      finishJSTest();
-    }
-  }, 500);
-}
-
-test();
-
-</script>
+<script src="resources/open-bad-versions.js"></script>
 </body>
 </html>
index 33adbe2..78efe57 100644 (file)
@@ -1,131 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-
-description("Exercise optional arguments with missing vs. undefined in IndexedDB methods.");
-
-indexedDBTest(prepareDatabase, checkOptionalArguments);
-function prepareDatabase(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("store = db.createObjectStore('store', {keyPath: 'id'})");
-    evalAndLog("store.createIndex('by_name', 'name', {unique: true})");
-
-    evalAndLog("store.put({id: 1, name: 'a'})");
-}
-
-function checkOptionalArguments(event)
-{
-    evalAndLog("tx = db.transaction('store', 'readwrite')");
-    tx.oncomplete = finishJSTest;
-
-    evalAndLog("store = tx.objectStore('store')");
-    evalAndLog("index = store.index('by_name')");
-
-    shouldBe("IDBKeyRange.lowerBound(0).lowerOpen", "false");
-    shouldBe("IDBKeyRange.upperBound(0).upperOpen", "false");
-    shouldBe("IDBKeyRange.bound(0, 1).lowerOpen", "false");
-    shouldBe("IDBKeyRange.bound(0, 1).upperOpen", "false");
-
-    shouldBe("IDBKeyRange.lowerBound(0, undefined).lowerOpen", "false");
-    shouldBe("IDBKeyRange.upperBound(0, undefined).upperOpen", "false");
-    shouldBe("IDBKeyRange.bound(0, 1, undefined, undefined).lowerOpen", "false");
-    shouldBe("IDBKeyRange.bound(0, 1, undefined, undefined).upperOpen", "false");
-
-    shouldNotThrow("store.add({id: 2, name: 'b'})");
-    shouldNotThrow("store.put({id: 3, name: 'c'})");
-    shouldNotThrow("store.add({id: 4, name: 'd'}, undefined)");
-    shouldNotThrow("store.put({id: 5, name: 'e'}, undefined)");
-
-    tasks = [
-        function(callback) { verifyCursor("store.openCursor()", "next", 5, callback); },
-        function(callback) { verifyCursor("store.openCursor(null)", "next", 5, callback); },
-        function(callback) { verifyCursor("store.openCursor(IDBKeyRange.lowerBound(4))", "next", 2, callback); },
-        function(callback) { verifyCursor("store.openCursor(3)", "next", 1, callback); },
-
-        function(callback) { verifyCursor("index.openCursor()", "next", 5, callback); },
-        function(callback) { verifyCursor("index.openCursor(null)", "next", 5, callback); },
-        function(callback) { verifyCursor("index.openCursor(IDBKeyRange.lowerBound('b'))", "next", 4, callback); },
-        function(callback) { verifyCursor("index.openCursor('c')", "next", 1, callback); },
-
-        function(callback) { verifyCursor("index.openKeyCursor()", "next", 5, callback); },
-        function(callback) { verifyCursor("index.openKeyCursor(null)", "next", 5, callback); },
-        function(callback) { verifyCursor("index.openKeyCursor(IDBKeyRange.lowerBound('b'))", "next", 4, callback); },
-        function(callback) { verifyCursor("index.openKeyCursor('c')", "next", 1, callback); },
-
-        function(callback) { verifyCount("store.count()", 5, callback); },
-        function(callback) { verifyCount("store.count(null)", 5, callback); },
-        function(callback) { verifyCount("store.count(IDBKeyRange.lowerBound(2))", 4, callback); },
-
-        function(callback) { verifyCount("index.count()", 5, callback); },
-        function(callback) { verifyCount("index.count(null)", 5, callback); },
-        function(callback) { verifyCount("index.count(IDBKeyRange.lowerBound('b'))", 4, callback); },
-
-        continueUndefined,
-
-    ];
-    function doNextTask() {
-        var task = tasks.shift();
-        if (task) {
-            task(doNextTask);
-        }
-    }
-    doNextTask();
-}
-
-function verifyCursor(expr, direction, expected, callback)
-{
-    preamble();
-    cursor = null;
-    continues = 0;
-    evalAndLog("request = " + expr);
-    request.onerror = unexpectedErrorCallback;
-
-    request.onsuccess = function() {
-        if (request.result) {
-            if (!cursor) {
-                evalAndLog("cursor = request.result");
-                shouldBeEqualToString("cursor.direction", direction);
-            }
-            ++continues;
-            cursor.continue();
-        } else {
-            shouldBe("continues", JSON.stringify(expected));
-            callback();
-        }
-    };
-}
-
-function verifyCount(expr, expected, callback)
-{
-    preamble();
-    evalAndLog("request = " + expr);
-    request.onerror = unexpectedErrorCallback;
-
-    request.onsuccess = function() {
-        shouldBe("request.result", JSON.stringify(expected));
-        callback();
-    };
-}
-
-function continueUndefined(callback)
-{
-    preamble();
-    first = true;
-    evalAndLog("request = store.openCursor()");
-    request.onerror = unexpectedErrorCallback;
-
-    request.onsuccess = function() {
-        if (first) {
-            first = false;
-            evalAndLog("cursor = request.result");
-            shouldBeNonNull("request.result");
-            shouldNotThrow("cursor.continue(undefined)");
-            callback();
-        }
-    };
-}
-
-</script>
+</head>
+<body>
+<script src="resources/optional-arguments.js"></script>
+</body>
+</html>
index ef2c843..dffefdc 100644 (file)
@@ -1,90 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-
-description("Ensure IndexedDB's write operations invalidate cursor prefetch caches");
-
-indexedDBTest(prepareDatabase, onOpenSuccess);
-function prepareDatabase(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("store = db.createObjectStore('store')");
-}
-
-function onOpenSuccess(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-
-    var steps = [
-        deleteRange,
-        clearStore
-    ];
-
-    (function nextStep() {
-        var step = steps.shift();
-        if (step) {
-            doPrefetchInvalidationTest(step, nextStep);
-        } else {
-            finishJSTest();
-            return;
-        }
-    }());
-}
-
-function doPrefetchInvalidationTest(operation, callback)
-{
-    debug("");
-    debug("-------------------------------------------");
-    preamble();
-    evalAndLog("store = db.transaction('store', 'readwrite').objectStore('store')");
-    debug("Populate the store with 200 records.");
-    for (var i = 0; i < 200; ++i)
-        store.put(i, i);
-    evalAndLog("cursorRequest = store.openCursor()");
-    continue100Times(operation, callback);
-}
-
-function continue100Times(operation, callback)
-{
-    preamble();
-    var count = 0;
-
-    cursorRequest.onsuccess = function() {
-        var cursor = cursorRequest.result;
-        ++count;
-        if (count < 100) {
-            cursor.continue();
-            return;
-        }
-        shouldBeNonNull("cursorRequest.result");
-        doOperationAndContinue(operation, callback);
-    }
-}
-
-function doOperationAndContinue(operation, callback)
-{
-    preamble();
-    operation();
-    evalAndLog("cursor = cursorRequest.result");
-    evalAndLog("cursor.continue()")
-    cursorRequest.onsuccess = function onContinueSuccess() {
-        preamble();
-        shouldBeNull("cursorRequest.result");
-        callback();
-    };
-}
-
-function deleteRange()
-{
-    return evalAndLog("store.delete(IDBKeyRange.bound(-Infinity, +Infinity))");
-}
-
-function clearStore()
-{
-    return evalAndLog("store.clear()");
-}
-
-</script>
+</head>
+<body>
+<script src="resources/prefetch-invalidation.js"></script>
+</body>
+</html>
index ec1b7af..727ff1f 100644 (file)
@@ -1,55 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-
-description("Ensure IndexedDB's cursor prefetch cache requests are invalidated");
-
-indexedDBTest(prepareDatabase, onOpenSuccess);
-function prepareDatabase(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("store = db.createObjectStore('store')");
-    debug("Populate with even records...");
-    for (var i = 0; i < 10; i += 2)
-        store.put(i, i);
-}
-
-function onOpenSuccess(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-
-    evalAndLog("tx = db.transaction('store', 'readwrite')");
-    evalAndLog("store = tx.objectStore('store')");
-    evalAndLog("request = store.openCursor()");
-
-    kPrefetchThreshold = 3;
-
-    expected = ["0", "2", "4", "6", "7", "8", "9"];
-    continueCount = 0;
-    request.onsuccess = function cursorSuccess() {
-        preamble();
-        cursor = request.result;
-        if (!cursor)
-            return;
-        ++continueCount;
-
-        expect = expected.shift();
-        shouldBe("cursor.key", expect);
-        evalAndLog("cursor.continue()");
-
-        if (continueCount === kPrefetchThreshold) {
-            debug("\nThat should have triggered a prefetch, injecting odd records...");
-            for (var i = 1; i < 10; i += 2)
-                store.put(i, i);
-        }
-    };
-
-    tx.oncomplete = function() {
-        shouldBe("continueCount", "7");
-        finishJSTest();
-    };
-}
-</script>
+</head>
+<body>
+<script src="resources/prefetch-race.js"></script>
+</body>
+</html>
index 54fbaf6..89a6aba 100644 (file)
+<html>
+<head>
+<script src="../../resources/js-test.js"></script>
+<script src="resources/shared.js"></script>
+</head>
 <body>
 <div id="logger"></div>
-<script>
-if (testRunner) {
-    testRunner.dumpAsText();
-    testRunner.waitUntilDone();
-}
-
-function log(msg) {
-    document.getElementById("logger").innerHTML += msg + "<br>";
-}
-
-var openRequest = indexedDB.open("pkutos", 1);
-
-openRequest.onupgradeneeded = function(e) {
-    var thisDB = e.target.result;
-
-    if(!thisDB.objectStoreNames.contains("people")) {
-        thisDB.createObjectStore("people", {keyPath:"id"});
-    }
-
-    if(!thisDB.objectStoreNames.contains("notes")) {
-        thisDB.createObjectStore("notes", {keyPath:"uid"});
-    }
-}
-
-openRequest.onsuccess = function(e) {
-    db = e.target.result;
-    addPerson();
-}    
-
-openRequest.onerror = function(e) {
-    log("openRequest error - " + e);
-}
-
-var sharedID = 0;
-
-function addPerson() {
-    log("About to add person and note");
-
-    //Get a transaction
-    //default for OS list is all, default for type is read
-    var transaction = db.transaction(["people"], "readwrite");
-
-    //Ask for the objectStore
-    var store = transaction.objectStore("people");
-
-    //Define a person
-    var person = {
-        name: "Person",
-        id: sharedID
-    }
-
-    //Perform the add
-    var request = store.add(person);
-
-    request.onerror = function(e) {
-        log("Error adding person - ", e);
-    }
-
-    request.onsuccess = function(e) {
-        log("Successfully added person");
-        setTimeout("addComplete();", 0);
-    }
-    
-    //Define a note
-    var note = {
-        note: "Note",
-        uid: sharedID
-    }
-
-    var transaction2 = db.transaction(["notes"], "readwrite");
-
-    //Ask for the objectStore
-    var store2 = transaction2.objectStore("notes");
-
-    //Perform the add
-    var request2 = store2.add(note);
-
-    request2.onerror = function(e) {
-        log("Error adding note - ", e);
-    }
-
-    request2.onsuccess = function(e) {
-        log("Successfully added note");
-        setTimeout("addComplete();", 0);
-    }
-    
-}
-
-var completedAdds = 0;
-function addComplete()
-{
-    if (++completedAdds < 2)
-        return;
-
-    //Get a transaction
-    var transaction = db.transaction(["people"], "readwrite");
-
-    //Ask for the objectStore
-    var store = transaction.objectStore("people");
-
-    //Perform the add
-    var request = store.get(sharedID);
-
-    request.onerror = function(e) {
-        log("Error getting person - ", e);
-    }
-
-    request.onsuccess = function(e) {
-        log("Successfully got person");
-        for (n in e.target.result) {
-            log(n);
-        }
-        getComplete();
-    }
-
-    var transaction2 = db.transaction(["notes"], "readwrite");
-
-    //Ask for the objectStore
-    var store2 = transaction2.objectStore("notes");
-
-    //Perform the add
-    var request2 = store2.get(sharedID);
-
-    request2.onerror = function(e) {
-        log("Error getting note - ", e);
-    }
-
-    request2.onsuccess = function(e) {
-        log("Successfully got note");
-        for (n in e.target.result) {
-            log(n);
-        }
-        getComplete();
-    }
-}
-
-var completedGets = 0;
-function getComplete()
-{
-    if (++completedGets == 2 && testRunner)
-        testRunner.notifyDone();
-}
-</script>
+<script src="resources/primary-key-unique-to-objectstore.js"></script>
 </body>
-</html>
\ No newline at end of file
+</html>
index 8d28fb4..bcdfa17 100644 (file)
@@ -1,52 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-
-description("Verify that that requests weakly hold script value properties");
-
-if (window.internals) {
-    indexedDBTest(prepareDatabase, onOpen);
-} else {
-    testFailed('This test requires access to the Internals object');
-    finishJSTest();
-}
-
-function prepareDatabase(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("store = db.createObjectStore('store')");
-    evalAndLog("store.put({value: 'value'}, 'key')");
-}
-
-function onOpen(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("tx = db.transaction('store')");
-    evalAndLog("store = tx.objectStore('store')");
-    evalAndLog("request = store.get('key')");
-    tx.oncomplete = function onTransactionComplete() {
-        preamble();
-        evalAndLog("db.close()");
-        shouldBeEqualToString("typeof request.result", "object");
-
-        // Verify that the same object is returned on each access to request.result.
-        evalAndLog("request.result.x = 123");
-        shouldBe("request.result.x", "123");
-
-        // Try and induce a leak by a reference cycle from DOM to V8 and back.
-        // If the v8 value of request.result (etc) is only held by the requests's
-        // V8 wrapper then there will be no leak.
-        evalAndLog("request.result.leak = request");
-        evalAndLog("observer = internals.observeGC(request)");
-        evalAndLog("request = null");
-        evalAndLog("gc()");
-        shouldBeTrue("observer.wasCollected");
-        finishJSTest();
-    };
-}
-
-
-</script>
+</head>
+<body>
+<script src="resources/request-leak.js"></script>
+</body>
+</html>
index 8652ca8..c38200a 100644 (file)
@@ -1,37 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-
-description("Verify that a request's result is dirtied when a cursor is continued");
-
-indexedDBTest(prepareDatabase, onOpen);
-
-function prepareDatabase(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("store = db.createObjectStore('store')");
-    store.put("value", "key");
-}
-
-function onOpen(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("tx = db.transaction('store')");
-    evalAndLog("store = tx.objectStore('store')");
-
-    evalAndLog("cursorRequest = store.openCursor()");
-    cursorRequest.onsuccess = function cursorRequestSuccess(evt) {
-        preamble(evt);
-        if (!cursorRequest.result)
-            return;
-
-        evalAndLog("cursor = cursorRequest.result");
-        evalAndLog("cursor.continue()");
-        evalAndExpectException("cursorRequest.result", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");    };
-
-    tx.oncomplete = finishJSTest;
-}
-</script>
+</head>
+<body>
+<script src="resources/request-result-cache.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/storage/indexeddb/resources/clone-exception.js b/LayoutTests/storage/indexeddb/resources/clone-exception.js
new file mode 100644 (file)
index 0000000..deece1d
--- /dev/null
@@ -0,0 +1,48 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Ensure DataCloneError is consistently thrown by IndexedDB methods");
+
+var NON_CLONEABLE = self;
+var INVALID_KEY = {};
+
+setDBNameFromPath();
+doFirstOpen();
+
+function doFirstOpen()
+{
+    preamble();
+    request = evalAndLog("indexedDB.open(dbname + '1')");
+    request.onupgradeneeded = function onUpgradeNeeded(e) {
+        preamble();
+        db = e.target.result;
+        evalAndExpectException("db.createObjectStore('store').put(NON_CLONEABLE, 0);", "25", "'DataCloneError'");
+        doSecondOpen();
+    };
+}
+
+function doSecondOpen()
+{
+    preamble();
+    request = evalAndLog("indexedDB.open(dbname + '2')");
+    request.onupgradeneeded = function onUpgradeNeeded(e) {
+        preamble();
+        db = e.target.result;
+        evalAndExpectException("db.createObjectStore('store').put(NON_CLONEABLE, 0);", "25", "'DataCloneError'");
+        doThirdOpen();
+    };
+}
+
+function doThirdOpen()
+{
+    preamble();
+    request = evalAndLog("indexedDB.open(dbname + '3')");
+    request.onupgradeneeded = function onUpgradeNeeded(e) {
+        preamble();
+        db = e.target.result;
+        evalAndExpectException("db.createObjectStore('store').put(NON_CLONEABLE, INVALID_KEY);", "25", "'DataCloneError'");
+        finishJSTest();
+    };
+}
diff --git a/LayoutTests/storage/indexeddb/resources/closed-cursor.js b/LayoutTests/storage/indexeddb/resources/closed-cursor.js
new file mode 100644 (file)
index 0000000..1306615
--- /dev/null
@@ -0,0 +1,36 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Verify that that cursors accessed after being closed are well behaved");
+
+indexedDBTest(prepareDatabase, onOpen);
+function prepareDatabase(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("store = db.createObjectStore('store')");
+    evalAndLog("store.put({value: 'value'}, ['key'])");
+}
+
+function onOpen(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("tx = db.transaction('store')");
+    evalAndLog("store = tx.objectStore('store')");
+    evalAndLog("cursorRequest = store.openCursor()");
+    cursorRequest.onsuccess = function openCursorSuccess(evt) {
+        preamble(evt);
+        evalAndLog("cursor = cursorRequest.result");
+        debug("Don't continue the cursor, so it retains its key/primaryKey/value");
+    };
+    tx.oncomplete = function transactionComplete(evt) {
+        preamble(evt);
+        shouldBeEqualToString("JSON.stringify(cursor.key)", '["key"]');
+        shouldBeEqualToString("JSON.stringify(cursor.primaryKey)", '["key"]');
+        shouldBeEqualToString("JSON.stringify(cursor.value)", '{"value":"value"}');
+        finishJSTest();
+    };
+}
diff --git a/LayoutTests/storage/indexeddb/resources/connection-leak.js b/LayoutTests/storage/indexeddb/resources/connection-leak.js
new file mode 100644 (file)
index 0000000..56bf418
--- /dev/null
@@ -0,0 +1,76 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Regression test to ensure that IndexedDB connections don't leak");
+
+setDBNameFromPath();
+doFirstOpen();
+
+function doFirstOpen()
+{
+    preamble();
+
+    evalAndLog("request = indexedDB.open(dbname, 1)");
+    evalAndLog("sawUpgradeNeeded1 = false");
+    request.onerror = unexpectedErrorCallback;
+    request.onblocked = unexpectedBlockedCallback;
+    request.onupgradeneeded = function onUpgradeNeeded1() {
+        preamble();
+        evalAndLog("sawUpgradeNeeded1 = true");
+    };
+    request.onsuccess = function onOpenSuccess1() {
+        preamble();
+        shouldBeTrue("sawUpgradeNeeded1");
+        evalAndLog("db = request.result");
+        evalAndLog("db.close()");
+
+        doSecondOpen();
+    };
+}
+
+function doSecondOpen()
+{
+    preamble();
+
+    evalAndLog("request = indexedDB.open(dbname, 1)");
+    request.onerror = unexpectedErrorCallback;
+    request.onblocked = unexpectedBlockedCallback;
+    request.onupgradeneeded = unexpectedUpgradeNeededCallback;
+    request.onsuccess = function onOpenSuccess2() {
+        preamble();
+        evalAndLog("db = request.result");
+
+        evalAndLog("db = null");
+        evalAndLog("request = null");
+
+        debug("Run GC outside of request's callback via setTimeout()");
+        setTimeout( function() {
+            evalAndLog("window.gc()");
+            doThirdOpen();
+        }, 0);
+    };
+}
+
+function doThirdOpen()
+{
+    preamble();
+
+    evalAndLog("request = indexedDB.open(dbname, 2)");
+    evalAndLog("sawUpgradeNeeded3 = false");
+    request.onerror = unexpectedErrorCallback;
+    request.onblocked = unexpectedBlockedCallback;
+    request.onupgradeneeded = function onUpgradeNeeded2() {
+        preamble();
+        evalAndLog("sawUpgradeNeeded3 = true");
+    };
+    request.onsuccess = function onOpenSuccess3() {
+        preamble();
+        shouldBeTrue("sawUpgradeNeeded3");
+        evalAndLog("db = request.result");
+        evalAndLog("db.close()");
+
+        finishJSTest();
+    };
+}
diff --git a/LayoutTests/storage/indexeddb/resources/cursor-cast.js b/LayoutTests/storage/indexeddb/resources/cursor-cast.js
new file mode 100644 (file)
index 0000000..4578517
--- /dev/null
@@ -0,0 +1,42 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Ensure cursor wrappers are created correctly.");
+
+indexedDBTest(prepareDatabase, verifyWrappers);
+function prepareDatabase(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("store = db.createObjectStore('store')");
+    evalAndLog("store.put(0, 0)");
+}
+
+function verifyWrappers(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("tx = db.transaction('store', 'readwrite')");
+    evalAndLog("request = tx.objectStore('store').openCursor()");
+
+    request.onsuccess = function onOpenCursorSuccess(evt) {
+        preamble(evt);
+        evalAndLog("cursor = event.target.result");
+        evalAndLog("request = cursor.update(1)");
+
+        request.onsuccess = function onUpdateSuccess(evt) {
+            preamble(evt);
+            evalAndLog("cursor = null");
+            gc();
+            gc(); // FIXME: Shouldn't need to call twice. http://crbug.com/288072
+            setTimeout(checkCursorType, 0);
+        };
+    };
+}
+
+function checkCursorType() {
+    shouldBeEqualToString("request.source.toString()", "[object IDBCursorWithValue]");
+    finishJSTest();
+}
diff --git a/LayoutTests/storage/indexeddb/resources/cursor-leak.js b/LayoutTests/storage/indexeddb/resources/cursor-leak.js
new file mode 100644 (file)
index 0000000..d905211
--- /dev/null
@@ -0,0 +1,53 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Verify that that cursors weakly hold script value properties");
+
+if (window.internals) {
+    indexedDBTest(prepareDatabase, onOpen);
+} else {
+    testFailed('This test requires access to the Internals object');
+    finishJSTest();
+}
+
+function prepareDatabase(evt)
+{
+    db = event.target.result;
+    store = db.createObjectStore('store');
+    store.put({value: 'value'}, ['key']);
+}
+
+function onOpen(evt)
+{
+    // evalAndLog() is not used as that generates new DOM nodes.
+
+    db = evt.target.result;
+    tx = db.transaction('store');
+    store = tx.objectStore('store');
+    cursorRequest = store.openCursor();
+    cursorRequest.onsuccess = function() {
+        cursor = cursorRequest.result;
+    };
+    tx.oncomplete = function() {
+        db.close();
+
+        // Try and induce a leak by a reference cycle from DOM to V8 and back.
+        // If the v8 value of cursor.key (etc) is only held by the cursor's
+        // V8 wrapper then there will be no leak.
+        cursor.key.cursor = cursor;
+        cursor.primaryKey.cursor = cursor;
+        cursor.value.cursor = cursor;
+
+        cursorObserver = internals.observeGC(cursor);
+
+        cursorRequest = null;
+        cursor = null;
+
+        gc();
+
+        shouldBeTrue("cursorObserver.wasCollected");
+        finishJSTest();
+    };
+}
diff --git a/LayoutTests/storage/indexeddb/resources/cursor-overloads.js b/LayoutTests/storage/indexeddb/resources/cursor-overloads.js
new file mode 100644 (file)
index 0000000..ae03b46
--- /dev/null
@@ -0,0 +1,77 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Validate the overloads of IDBObjectStore.openCursor(), IDBIndex.openCursor() and IDBIndex.openKeyCursor().");
+
+indexedDBTest(prepareDatabase, verifyOverloads);
+function prepareDatabase()
+{
+    db = event.target.result;
+    event.target.transaction.onabort = unexpectedAbortCallback;
+    evalAndLog("store = db.createObjectStore('store')");
+    evalAndLog("index = store.createIndex('index', 'value')");
+    evalAndLog("store.put({value: 0}, 0)");
+}
+
+function verifyOverloads()
+{
+    debug("");
+    debug("verifyOverloads():");
+    evalAndLog("trans = db.transaction('store')");
+    evalAndLog("store = trans.objectStore('store')");
+    evalAndLog("index = store.index('index')");
+
+    checkCursorDirection("store.openCursor()", "next");
+    checkCursorDirection("store.openCursor(0)", "next");
+    checkCursorDirection("store.openCursor(0, 'next')", "next");
+    checkCursorDirection("store.openCursor(0, 'nextunique')", "nextunique");
+    checkCursorDirection("store.openCursor(0, 'prev')", "prev");
+    checkCursorDirection("store.openCursor(0, 'prevunique')", "prevunique");
+
+    checkCursorDirection("store.openCursor(IDBKeyRange.only(0))", "next");
+    checkCursorDirection("store.openCursor(IDBKeyRange.only(0), 'next')", "next");
+    checkCursorDirection("store.openCursor(IDBKeyRange.only(0), 'nextunique')", "nextunique");
+    checkCursorDirection("store.openCursor(IDBKeyRange.only(0), 'prev')", "prev");
+    checkCursorDirection("store.openCursor(IDBKeyRange.only(0), 'prevunique')", "prevunique");
+
+    checkCursorDirection("index.openCursor()", "next");
+    checkCursorDirection("index.openCursor(0)", "next");
+    checkCursorDirection("index.openCursor(0, 'next')", "next");
+    checkCursorDirection("index.openCursor(0, 'nextunique')", "nextunique");
+    checkCursorDirection("index.openCursor(0, 'prev')", "prev");
+    checkCursorDirection("index.openCursor(0, 'prevunique')", "prevunique");
+
+    checkCursorDirection("index.openCursor(IDBKeyRange.only(0))", "next");
+    checkCursorDirection("index.openCursor(IDBKeyRange.only(0), 'next')", "next");
+    checkCursorDirection("index.openCursor(IDBKeyRange.only(0), 'nextunique')", "nextunique");
+    checkCursorDirection("index.openCursor(IDBKeyRange.only(0), 'prev')", "prev");
+    checkCursorDirection("index.openCursor(IDBKeyRange.only(0), 'prevunique')", "prevunique");
+
+    checkCursorDirection("index.openKeyCursor()", "next");
+    checkCursorDirection("index.openKeyCursor(0)", "next");
+    checkCursorDirection("index.openKeyCursor(0, 'next')", "next");
+    checkCursorDirection("index.openKeyCursor(0, 'nextunique')", "nextunique");
+    checkCursorDirection("index.openKeyCursor(0, 'prev')", "prev");
+    checkCursorDirection("index.openKeyCursor(0, 'prevunique')", "prevunique");
+
+    checkCursorDirection("index.openKeyCursor(IDBKeyRange.only(0))", "next");
+    checkCursorDirection("index.openKeyCursor(IDBKeyRange.only(0), 'next')", "next");
+    checkCursorDirection("index.openKeyCursor(IDBKeyRange.only(0), 'nextunique')", "nextunique");
+    checkCursorDirection("index.openKeyCursor(IDBKeyRange.only(0), 'prev')", "prev");
+    checkCursorDirection("index.openKeyCursor(IDBKeyRange.only(0), 'prevunique')", "prevunique");
+
+    trans.oncomplete = finishJSTest;
+}
+
+function checkCursorDirection(statement, direction)
+{
+    request = eval(statement);
+    request.onerror = unexpectedErrorCallback;
+    request.onsuccess = function() {
+        debug(statement);
+        shouldBeNonNull("event.target.result")
+        shouldBeEqualToString("event.target.result.direction", direction);
+    };
+}
diff --git a/LayoutTests/storage/indexeddb/resources/cursor-request-cycle.js b/LayoutTests/storage/indexeddb/resources/cursor-request-cycle.js
new file mode 100644 (file)
index 0000000..bbbec8c
--- /dev/null
@@ -0,0 +1,85 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Verify that that cursors weakly hold request, and work if request is GC'd");
+
+indexedDBTest(prepareDatabase, onOpen);
+
+function prepareDatabase(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("store = db.createObjectStore('store')");
+    store.put("value1", "key1");
+    store.put("value2", "key2");
+}
+
+function onOpen(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("tx = db.transaction('store')");
+    evalAndLog("store = tx.objectStore('store')");
+
+    evalAndLog("cursorRequest = store.openCursor()");
+    cursorRequest.onsuccess = function openCursorRequestSuccess(evt) {
+        preamble(evt);
+        debug("Result will be checked later, to ensure that lazy access is safe");
+    };
+
+    evalAndLog("otherRequest = store.get(0)");
+    otherRequest.onsuccess = function otherRequestSuccess(evt) {
+        preamble(evt);
+
+        debug("Verify that the request's result can be accessed lazily:");
+        evalAndLog("gc()");
+
+        evalAndLog("cursor = cursorRequest.result");
+        shouldBeNonNull("cursor");
+        shouldBeEqualToString("cursor.key", "key1");
+        shouldBeEqualToString("cursor.value", "value1");
+        evalAndLog("cursorRequest.extra = 123");
+        evalAndLog("cursor.extra = 456");
+
+        // Assign a new handler to inspect the request and cursor indirectly.
+        cursorRequest.onsuccess = function cursorContinueSuccess(evt) {
+            preamble(evt);
+            evalAndLog("cursor = event.target.result");
+            shouldBeNonNull("cursor");
+            shouldBeEqualToString("cursor.key", "key2");
+            shouldBeEqualToString("cursor.value", "value2");
+            shouldBe("event.target.extra", "123");
+            shouldBe("cursor.extra", "456");
+        };
+
+        debug("Ensure request is not released if cursor is still around.");
+        cursorRequestObservation = internals.observeGC(cursorRequest);
+        evalAndLog("cursorRequest = null");
+        evalAndLog("gc()");
+        shouldBeFalse("cursorRequestObservation.wasCollected");
+
+        evalAndLog("cursor.continue()");
+
+        cursorObservation = internals.observeGC(cursor);
+        evalAndLog("cursor = null");
+        evalAndLog("gc()");
+        shouldBeFalse("cursorObservation.wasCollected");
+
+        evalAndLog("finalRequest = store.get(0)");
+        finalRequest.onsuccess = function finalRequestSuccess(evt) {
+            preamble(evt);
+            shouldBeEqualToString("cursor.key", "key2");
+            shouldBeEqualToString("cursor.value", "value2");
+
+            cursorObservation = internals.observeGC(cursor);
+            evalAndLog("cursor = null");
+            evalAndLog("gc()");
+            shouldBeTrue("cursorRequestObservation.wasCollected");
+            shouldBeTrue("cursorObservation.wasCollected");
+        };
+    };
+
+    tx.oncomplete = finishJSTest;
+}
diff --git a/LayoutTests/storage/indexeddb/resources/deleteIndex-bug110792.js b/LayoutTests/storage/indexeddb/resources/deleteIndex-bug110792.js
new file mode 100644 (file)
index 0000000..d29a60e
--- /dev/null
@@ -0,0 +1,39 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Ensure IndexedDB's IDBObjectStore.deleteIndex() works if IDBIndex object has not been fetched - regression test for bug 110792.");
+
+indexedDBTest(onFirstUpgradeNeeded, closeAndReOpen, {version: 1});
+
+function onFirstUpgradeNeeded(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("store = db.createObjectStore('store')");
+    evalAndLog("store.createIndex('index', 'keyPath')");
+}
+
+function closeAndReOpen()
+{
+    preamble();
+    evalAndLog("db.close()");
+    debug("");
+    request = evalAndLog("indexedDB.open(dbname, 2)");
+    request.onblocked = unexpectedBlockedCallback;
+    request.onerror = unexpectedErrorCallback;
+    request.onupgradeneeded = onSecondUpgradeNeeded;
+    request.onsuccess = finishJSTest;
+}
+
+function onSecondUpgradeNeeded(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("store = event.target.transaction.objectStore('store')");
+    // Do NOT add a call to store.index('index') here (e.g. to assert it exists)
+    // or the bug disappears.
+    evalAndLog("store.deleteIndex('index')");
+    evalAndExpectException("store.index('index')", "DOMException.NOT_FOUND_ERR", "'NotFoundError'");
+}
diff --git a/LayoutTests/storage/indexeddb/resources/deletedatabase-transaction.js b/LayoutTests/storage/indexeddb/resources/deletedatabase-transaction.js
new file mode 100644 (file)
index 0000000..c01f643
--- /dev/null
@@ -0,0 +1,32 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Ensure deleteDatabase() can run concurrently with transactions in other databases");
+
+indexedDBTest(prepareDatabase, startTransaction);
+function prepareDatabase()
+{
+    db = event.target.result;
+    evalAndLog("db.createObjectStore('store')");
+}
+
+function startTransaction() {
+    debug("");
+    debug("Start a transaction against the first database:");
+    evalAndLog("trans = db.transaction('store', 'readonly')");
+    evalAndLog("trans.objectStore('store').get(0)");
+
+    debug("");
+    debug("Delete a different database:");
+    evalAndLog("dbname2 = dbname + '2'");
+    request = evalAndLog("indexedDB.deleteDatabase(dbname2)");
+    request.onblocked = unexpectedBlockedCallback;
+    request.onerror = unexpectedErrorCallback;
+    request.onsuccess = function() {
+        testPassed("success event was fired at delete request");
+    };
+
+    trans.oncomplete = finishJSTest;
+}
diff --git a/LayoutTests/storage/indexeddb/resources/metadata-race.js b/LayoutTests/storage/indexeddb/resources/metadata-race.js
new file mode 100644 (file)
index 0000000..df75cde
--- /dev/null
@@ -0,0 +1,37 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Ensure IndexedDB transactions created before open onsuccess have correct metadata");
+
+indexedDBTest(prepareDatabase, onOpenSuccess);
+function prepareDatabase(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("store = db.createObjectStore('store')");
+    evalAndLog("store.createIndex('index', 'keyPath')");
+    evalAndLog("transaction = event.target.transaction");
+    shouldNotThrow("index = transaction.objectStore('store').index('index')");
+    transaction.oncomplete = onTransactionComplete;
+}
+
+function onTransactionComplete(evt)
+{
+    preamble(evt);
+    debug("In multiprocess mode, 'complete' event may be dispatched before\n" +
+          "the 'success' arrives with updated metadata. Ensure the new metadata\n" +
+          "is still used for transactions.");
+    evalAndLog("store = db.transaction('store').objectStore('store')");
+    shouldNotThrow("index = store.index('index')");
+}
+
+function onOpenSuccess(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("store = db.transaction('store').objectStore('store')");
+    shouldNotThrow("index = store.index('index')");
+    finishJSTest();
+}
diff --git a/LayoutTests/storage/indexeddb/resources/noblobs.js b/LayoutTests/storage/indexeddb/resources/noblobs.js
new file mode 100644 (file)
index 0000000..6d47657
--- /dev/null
@@ -0,0 +1,78 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Confirm Blob/File/FileList limitations of WebKit's IndexedDB implementation.");
+// FIXME: This verifies that blob-type data is rejected for now, rather than silently failing.
+// Tracked for the Chromium port as: http://crbug.com/108012
+
+fileInput = document.getElementById("fileInput");
+if (window.eventSender) {
+    var fileRect = fileInput.getClientRects()[0];
+    var targetX = fileRect.left + fileRect.width / 2;
+    var targetY = fileRect.top + fileRect.height / 2;
+    eventSender.beginDragWithFiles(['resources/test-data.html', 'resources/test-data.txt']);
+    eventSender.mouseMoveTo(targetX, targetY);
+    eventSender.mouseUp();
+}
+
+function prepareDatabase()
+{
+    db = event.target.result;
+    var trans = event.target.transaction;
+    evalAndLog("store = db.createObjectStore('storeName')");
+    evalAndLog("store.put('value', 'key')");
+    trans.onerror = unexpectedErrorCallback;
+    trans.onabort = unexpectedAbortCallback;
+}
+
+function testBlob()
+{
+    debug("");
+    debug("testBlob():");
+
+    shouldBeTrue("FileReader != null");
+    evalAndLog("test_content = 'This is a test. This is only a test.'");
+    evalAndLog("blob = new Blob([test_content])");
+    validateExceptions("blob", testFile);
+}
+
+function testFile()
+{
+    debug("");
+    debug("testFile():");
+    evalAndLog("file = fileInput.files[0]");
+    validateExceptions("file", testFileList);
+}
+
+function testFileList()
+{
+    debug("");
+    debug("testFileList():");
+    evalAndLog("filelist = fileInput.files");
+    validateExceptions("filelist", finishJSTest);
+}
+
+function validateExceptions(variable, onComplete)
+{
+    debug("");
+    debug("validateExceptions(" + variable + "):");
+    evalAndLog("transaction = db.transaction('storeName', 'readwrite')");
+    evalAndLog("store = transaction.objectStore('storeName')");
+    evalAndExpectException("store.put(" + variable + ", 'key')", "DOMException.DATA_CLONE_ERR");
+    evalAndExpectException("store.add(" + variable + ", 'key')", "DOMException.DATA_CLONE_ERR");
+    evalAndLog("request = store.openCursor()");
+    request.onsuccess = function () {
+        evalAndLog("cursor = request.result");
+        evalAndExpectException("cursor.update(" + variable + ")", "DOMException.DATA_CLONE_ERR");
+    };
+    transaction.oncomplete = onComplete;
+}
+
+if (window.eventSender) {
+    indexedDBTest(prepareDatabase, testBlob);
+} else {
+    alert("Select file(s) using the input control above to initiate the test");
+    document.getElementById("fileInput").onchange = function() { indexedDBTest(prepareDatabase, testBlob); };
+}
diff --git a/LayoutTests/storage/indexeddb/resources/object-lookups-in-versionchange.js b/LayoutTests/storage/indexeddb/resources/object-lookups-in-versionchange.js
new file mode 100644 (file)
index 0000000..221b137
--- /dev/null
@@ -0,0 +1,18 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Regression test for http://webkit.org/b/102547");
+
+indexedDBTest(prepareDatabase, finishJSTest);
+
+function prepareDatabase() {
+    evalAndLog("db = event.target.result");
+    evalAndLog("transaction = event.target.transaction");
+    evalAndLog("store = db.createObjectStore('store')");
+    debug("");
+    evalAndExpectException("transaction.objectStore('no-such-store')", "DOMException.NOT_FOUND_ERR", "'NotFoundError'");
+    debug("");
+    evalAndExpectException("store.index('no-such-index')", "DOMException.NOT_FOUND_ERR", "'NotFoundError'");
+}
diff --git a/LayoutTests/storage/indexeddb/resources/open-bad-versions.js b/LayoutTests/storage/indexeddb/resources/open-bad-versions.js
new file mode 100644 (file)
index 0000000..d1a1158
--- /dev/null
@@ -0,0 +1,26 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("No crashes when opening and reloading with bad version numbers");
+
+function test()
+{
+  removeVendorPrefixes();
+  evalAndLog("dbname = String(window.location)");
+
+  try { indexedDB.open(dbname, -1); } catch (e) { }
+  indexedDB.open(dbname, 2);
+  try { indexedDB.open(dbname, -1); } catch (e) { }
+
+  setTimeout(function() {
+    if (!window.location.search) {
+      window.location = window.location + "?2";
+    } else {
+      finishJSTest();
+    }
+  }, 500);
+}
+
+test();
diff --git a/LayoutTests/storage/indexeddb/resources/optional-arguments.js b/LayoutTests/storage/indexeddb/resources/optional-arguments.js
new file mode 100644 (file)
index 0000000..caf402d
--- /dev/null
@@ -0,0 +1,129 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Exercise optional arguments with missing vs. undefined in IndexedDB methods.");
+
+indexedDBTest(prepareDatabase, checkOptionalArguments);
+function prepareDatabase(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("store = db.createObjectStore('store', {keyPath: 'id'})");
+    evalAndLog("store.createIndex('by_name', 'name', {unique: true})");
+
+    evalAndLog("store.put({id: 1, name: 'a'})");
+}
+
+function checkOptionalArguments(event)
+{
+    evalAndLog("tx = db.transaction('store', 'readwrite')");
+    tx.oncomplete = finishJSTest;
+
+    evalAndLog("store = tx.objectStore('store')");
+    evalAndLog("index = store.index('by_name')");
+
+    shouldBe("IDBKeyRange.lowerBound(0).lowerOpen", "false");
+    shouldBe("IDBKeyRange.upperBound(0).upperOpen", "false");
+    shouldBe("IDBKeyRange.bound(0, 1).lowerOpen", "false");
+    shouldBe("IDBKeyRange.bound(0, 1).upperOpen", "false");
+
+    shouldBe("IDBKeyRange.lowerBound(0, undefined).lowerOpen", "false");
+    shouldBe("IDBKeyRange.upperBound(0, undefined).upperOpen", "false");
+    shouldBe("IDBKeyRange.bound(0, 1, undefined, undefined).lowerOpen", "false");
+    shouldBe("IDBKeyRange.bound(0, 1, undefined, undefined).upperOpen", "false");
+
+    shouldNotThrow("store.add({id: 2, name: 'b'})");
+    shouldNotThrow("store.put({id: 3, name: 'c'})");
+    shouldNotThrow("store.add({id: 4, name: 'd'}, undefined)");
+    shouldNotThrow("store.put({id: 5, name: 'e'}, undefined)");
+
+    tasks = [
+        function(callback) { verifyCursor("store.openCursor()", "next", 5, callback); },
+        function(callback) { verifyCursor("store.openCursor(null)", "next", 5, callback); },
+        function(callback) { verifyCursor("store.openCursor(IDBKeyRange.lowerBound(4))", "next", 2, callback); },
+        function(callback) { verifyCursor("store.openCursor(3)", "next", 1, callback); },
+
+        function(callback) { verifyCursor("index.openCursor()", "next", 5, callback); },
+        function(callback) { verifyCursor("index.openCursor(null)", "next", 5, callback); },
+        function(callback) { verifyCursor("index.openCursor(IDBKeyRange.lowerBound('b'))", "next", 4, callback); },
+        function(callback) { verifyCursor("index.openCursor('c')", "next", 1, callback); },
+
+        function(callback) { verifyCursor("index.openKeyCursor()", "next", 5, callback); },
+        function(callback) { verifyCursor("index.openKeyCursor(null)", "next", 5, callback); },
+        function(callback) { verifyCursor("index.openKeyCursor(IDBKeyRange.lowerBound('b'))", "next", 4, callback); },
+        function(callback) { verifyCursor("index.openKeyCursor('c')", "next", 1, callback); },
+
+        function(callback) { verifyCount("store.count()", 5, callback); },
+        function(callback) { verifyCount("store.count(null)", 5, callback); },
+        function(callback) { verifyCount("store.count(IDBKeyRange.lowerBound(2))", 4, callback); },
+
+        function(callback) { verifyCount("index.count()", 5, callback); },
+        function(callback) { verifyCount("index.count(null)", 5, callback); },
+        function(callback) { verifyCount("index.count(IDBKeyRange.lowerBound('b'))", 4, callback); },
+
+        continueUndefined,
+
+    ];
+    function doNextTask() {
+        var task = tasks.shift();
+        if (task) {
+            task(doNextTask);
+        }
+    }
+    doNextTask();
+}
+
+function verifyCursor(expr, direction, expected, callback)
+{
+    preamble();
+    cursor = null;
+    continues = 0;
+    evalAndLog("request = " + expr);
+    request.onerror = unexpectedErrorCallback;
+
+    request.onsuccess = function() {
+        if (request.result) {
+            if (!cursor) {
+                evalAndLog("cursor = request.result");
+                shouldBeEqualToString("cursor.direction", direction);
+            }
+            ++continues;
+            cursor.continue();
+        } else {
+            shouldBe("continues", JSON.stringify(expected));
+            callback();
+        }
+    };
+}
+
+function verifyCount(expr, expected, callback)
+{
+    preamble();
+    evalAndLog("request = " + expr);
+    request.onerror = unexpectedErrorCallback;
+
+    request.onsuccess = function() {
+        shouldBe("request.result", JSON.stringify(expected));
+        callback();
+    };
+}
+
+function continueUndefined(callback)
+{
+    preamble();
+    first = true;
+    evalAndLog("request = store.openCursor()");
+    request.onerror = unexpectedErrorCallback;
+
+    request.onsuccess = function() {
+        if (first) {
+            first = false;
+            evalAndLog("cursor = request.result");
+            shouldBeNonNull("request.result");
+            shouldNotThrow("cursor.continue(undefined)");
+            callback();
+        }
+    };
+}
diff --git a/LayoutTests/storage/indexeddb/resources/prefetch-invalidation.js b/LayoutTests/storage/indexeddb/resources/prefetch-invalidation.js
new file mode 100644 (file)
index 0000000..640cda1
--- /dev/null
@@ -0,0 +1,88 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Ensure IndexedDB's write operations invalidate cursor prefetch caches");
+
+indexedDBTest(prepareDatabase, onOpenSuccess);
+function prepareDatabase(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("store = db.createObjectStore('store')");
+}
+
+function onOpenSuccess(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+
+    var steps = [
+        deleteRange,
+        clearStore
+    ];
+
+    (function nextStep() {
+        var step = steps.shift();
+        if (step) {
+            doPrefetchInvalidationTest(step, nextStep);
+        } else {
+            finishJSTest();
+            return;
+        }
+    }());
+}
+
+function doPrefetchInvalidationTest(operation, callback)
+{
+    debug("");
+    debug("-------------------------------------------");
+    preamble();
+    evalAndLog("store = db.transaction('store', 'readwrite').objectStore('store')");
+    debug("Populate the store with 200 records.");
+    for (var i = 0; i < 200; ++i)
+        store.put(i, i);
+    evalAndLog("cursorRequest = store.openCursor()");
+    continue100Times(operation, callback);
+}
+
+function continue100Times(operation, callback)
+{
+    preamble();
+    var count = 0;
+
+    cursorRequest.onsuccess = function() {
+        var cursor = cursorRequest.result;
+        ++count;
+        if (count < 100) {
+            cursor.continue();
+            return;
+        }
+        shouldBeNonNull("cursorRequest.result");
+        doOperationAndContinue(operation, callback);
+    }
+}
+
+function doOperationAndContinue(operation, callback)
+{
+    preamble();
+    operation();
+    evalAndLog("cursor = cursorRequest.result");
+    evalAndLog("cursor.continue()")
+    cursorRequest.onsuccess = function onContinueSuccess() {
+        preamble();
+        shouldBeNull("cursorRequest.result");
+        callback();
+    };
+}
+
+function deleteRange()
+{
+    return evalAndLog("store.delete(IDBKeyRange.bound(-Infinity, +Infinity))");
+}
+
+function clearStore()
+{
+    return evalAndLog("store.clear()");
+}
diff --git a/LayoutTests/storage/indexeddb/resources/prefetch-race.js b/LayoutTests/storage/indexeddb/resources/prefetch-race.js
new file mode 100644 (file)
index 0000000..60086e6
--- /dev/null
@@ -0,0 +1,54 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Ensure IndexedDB's cursor prefetch cache requests are invalidated");
+
+indexedDBTest(prepareDatabase, onOpenSuccess);
+function prepareDatabase(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("store = db.createObjectStore('store')");
+    debug("Populate with even records...");
+    for (var i = 0; i < 10; i += 2)
+        store.put(i, i);
+}
+
+function onOpenSuccess(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+
+    evalAndLog("tx = db.transaction('store', 'readwrite')");
+    evalAndLog("store = tx.objectStore('store')");
+    evalAndLog("request = store.openCursor()");
+
+    kPrefetchThreshold = 3;
+
+    expected = ["0", "2", "4", "6", "7", "8", "9"];
+    continueCount = 0;
+    request.onsuccess = function cursorSuccess() {
+        preamble();
+        cursor = request.result;
+        if (!cursor)
+            return;
+        ++continueCount;
+
+        expect = expected.shift();
+        shouldBe("cursor.key", expect);
+        evalAndLog("cursor.continue()");
+
+        if (continueCount === kPrefetchThreshold) {
+            debug("\nThat should have triggered a prefetch, injecting odd records...");
+            for (var i = 1; i < 10; i += 2)
+                store.put(i, i);
+        }
+    };
+
+    tx.oncomplete = function() {
+        shouldBe("continueCount", "7");
+        finishJSTest();
+    };
+}
diff --git a/LayoutTests/storage/indexeddb/resources/primary-key-unique-to-objectstore.js b/LayoutTests/storage/indexeddb/resources/primary-key-unique-to-objectstore.js
new file mode 100644 (file)
index 0000000..aeb6d0b
--- /dev/null
@@ -0,0 +1,146 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+if (testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+function log(msg) {
+    document.getElementById("logger").innerHTML += msg + "<br>";
+}
+
+var openRequest = indexedDB.open("pkutos", 1);
+
+openRequest.onupgradeneeded = function(e) {
+    var thisDB = e.target.result;
+
+    if(!thisDB.objectStoreNames.contains("people")) {
+        thisDB.createObjectStore("people", {keyPath:"id"});
+    }
+
+    if(!thisDB.objectStoreNames.contains("notes")) {
+        thisDB.createObjectStore("notes", {keyPath:"uid"});
+    }
+}
+
+openRequest.onsuccess = function(e) {
+    db = e.target.result;
+    addPerson();
+}    
+
+openRequest.onerror = function(e) {
+    log("openRequest error - " + e);
+}
+
+var sharedID = 0;
+
+function addPerson() {
+    log("About to add person and note");
+
+    //Get a transaction
+    //default for OS list is all, default for type is read
+    var transaction = db.transaction(["people"], "readwrite");
+
+    //Ask for the objectStore
+    var store = transaction.objectStore("people");
+
+    //Define a person
+    var person = {
+        name: "Person",
+        id: sharedID
+    }
+
+    //Perform the add
+    var request = store.add(person);
+
+    request.onerror = function(e) {
+        log("Error adding person - ", e);
+    }
+
+    request.onsuccess = function(e) {
+        log("Successfully added person");
+        setTimeout("addComplete();", 0);
+    }
+    
+    //Define a note
+    var note = {
+        note: "Note",
+        uid: sharedID
+    }
+
+    var transaction2 = db.transaction(["notes"], "readwrite");
+
+    //Ask for the objectStore
+    var store2 = transaction2.objectStore("notes");
+
+    //Perform the add
+    var request2 = store2.add(note);
+
+    request2.onerror = function(e) {
+        log("Error adding note - ", e);
+    }
+
+    request2.onsuccess = function(e) {
+        log("Successfully added note");
+        setTimeout("addComplete();", 0);
+    }
+    
+}
+
+var completedAdds = 0;
+function addComplete()
+{
+    if (++completedAdds < 2)
+        return;
+
+    //Get a transaction
+    var transaction = db.transaction(["people"], "readwrite");
+
+    //Ask for the objectStore
+    var store = transaction.objectStore("people");
+
+    //Perform the add
+    var request = store.get(sharedID);
+
+    request.onerror = function(e) {
+        log("Error getting person - ", e);
+    }
+
+    request.onsuccess = function(e) {
+        log("Successfully got person");
+        for (n in e.target.result) {
+            log(n);
+        }
+        getComplete();
+    }
+
+    var transaction2 = db.transaction(["notes"], "readwrite");
+
+    //Ask for the objectStore
+    var store2 = transaction2.objectStore("notes");
+
+    //Perform the add
+    var request2 = store2.get(sharedID);
+
+    request2.onerror = function(e) {
+        log("Error getting note - ", e);
+    }
+
+    request2.onsuccess = function(e) {
+        log("Successfully got note");
+        for (n in e.target.result) {
+            log(n);
+        }
+        getComplete();
+    }
+}
+
+var completedGets = 0;
+function getComplete()
+{
+    if (++completedGets == 2 && testRunner)
+        testRunner.notifyDone();
+}
diff --git a/LayoutTests/storage/indexeddb/resources/request-leak.js b/LayoutTests/storage/indexeddb/resources/request-leak.js
new file mode 100644 (file)
index 0000000..5938c74
--- /dev/null
@@ -0,0 +1,49 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Verify that that requests weakly hold script value properties");
+
+if (window.internals) {
+    indexedDBTest(prepareDatabase, onOpen);
+} else {
+    testFailed('This test requires access to the Internals object');
+    finishJSTest();
+}
+
+function prepareDatabase(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("store = db.createObjectStore('store')");
+    evalAndLog("store.put({value: 'value'}, 'key')");
+}
+
+function onOpen(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("tx = db.transaction('store')");
+    evalAndLog("store = tx.objectStore('store')");
+    evalAndLog("request = store.get('key')");
+    tx.oncomplete = function onTransactionComplete() {
+        preamble();
+        evalAndLog("db.close()");
+        shouldBeEqualToString("typeof request.result", "object");
+
+        // Verify that the same object is returned on each access to request.result.
+        evalAndLog("request.result.x = 123");
+        shouldBe("request.result.x", "123");
+
+        // Try and induce a leak by a reference cycle from DOM to V8 and back.
+        // If the v8 value of request.result (etc) is only held by the requests's
+        // V8 wrapper then there will be no leak.
+        evalAndLog("request.result.leak = request");
+        evalAndLog("observer = internals.observeGC(request)");
+        evalAndLog("request = null");
+        evalAndLog("gc()");
+        shouldBeTrue("observer.wasCollected");
+        finishJSTest();
+    };
+}
diff --git a/LayoutTests/storage/indexeddb/resources/request-result-cache.js b/LayoutTests/storage/indexeddb/resources/request-result-cache.js
new file mode 100644 (file)
index 0000000..33ecf1c
--- /dev/null
@@ -0,0 +1,36 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Verify that a request's result is dirtied when a cursor is continued");
+
+indexedDBTest(prepareDatabase, onOpen);
+
+function prepareDatabase(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("store = db.createObjectStore('store')");
+    store.put("value", "key");
+}
+
+function onOpen(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("tx = db.transaction('store')");
+    evalAndLog("store = tx.objectStore('store')");
+
+    evalAndLog("cursorRequest = store.openCursor()");
+    cursorRequest.onsuccess = function cursorRequestSuccess(evt) {
+        preamble(evt);
+        if (!cursorRequest.result)
+            return;
+
+        evalAndLog("cursor = cursorRequest.result");
+        evalAndLog("cursor.continue()");
+        evalAndExpectException("cursorRequest.result", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'");    };
+
+    tx.oncomplete = finishJSTest;
+}
diff --git a/LayoutTests/storage/indexeddb/resources/structured-clone.js b/LayoutTests/storage/indexeddb/resources/structured-clone.js
new file mode 100644 (file)
index 0000000..f31c799
--- /dev/null
@@ -0,0 +1,546 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Test structured clone permutations in IndexedDB. File/FileList tests require DumpRenderTree.");
+
+if (self.eventSender) {
+    var fileInput = document.getElementById("fileInput");
+    var fileRect = fileInput.getClientRects()[0];
+    var targetX = fileRect.left + fileRect.width / 2;
+    var targetY = fileRect.top + fileRect.height / 2;
+    eventSender.beginDragWithFiles(['resources/test-data.html', 'resources/test-data.txt']);
+    eventSender.mouseMoveTo(targetX, targetY);
+    eventSender.mouseUp();
+}
+
+indexedDBTest(prepareDatabase, startTests);
+function prepareDatabase()
+{
+    db = event.target.result;
+    evalAndLog("store = db.createObjectStore('storeName')");
+    debug("This index is not used, but evaluating key path on each put() call will exercise (de)serialization:");
+    evalAndLog("store.createIndex('indexName', 'dummyKeyPath')");
+}
+
+function startTests()
+{
+    debug("");
+    debug("Running tests...");
+    var tests_to_run = [
+        testUndefined,
+        testNull,
+        testBoolean,
+        testNumber,
+        testString,
+        testBooleanObject,
+        testNumberObject,
+        testStringObject,
+        testDateObject,
+        testRegExpObject,
+        testImageData,
+        testBlob,
+        testFile,
+        testFileList,
+        testArray,
+        testObject,
+        testTypedArray
+    ];
+
+    function nextTest() {
+        debug("");
+        if (tests_to_run.length) {
+            var test = tests_to_run.shift();
+            test(nextTest); // When done, call this again.
+        } else {
+            testBadTypes();
+        }
+    }
+    nextTest();
+}
+
+function forEachWithCallback(testFunction, values, callback)
+{
+    function nextValue() {
+        if (values.length) {
+            testFunction(values.shift(), nextValue);
+        } else {
+            callback();
+        }
+    }
+
+    nextValue();
+}
+
+function testValue(value, callback)
+{
+    // One transaction per test, since some tests require asynchronous
+    // operations to verify the result (e.g. via FileReader)
+    evalAndLog("transaction = db.transaction('storeName', 'readwrite')");
+    transaction.onerror = unexpectedErrorCallback;
+    transaction.onabort = unexpectedAbortCallback;
+    evalAndLog("store = transaction.objectStore('storeName')");
+
+    self.value = value;
+    request = evalAndLog("store.put(value, 'key')");
+    request.onerror = unexpectedErrorCallback;
+    request.onsuccess = function(e) {
+        request = evalAndLog("store.get('key')");
+        request.onerror = unexpectedErrorCallback;
+        request.onsuccess = function(e) {
+            callback(request.result);
+        };
+    };
+}
+
+// Identity testing, sensitive to NaN and -0
+function is(x, y) {
+    if (x === y) {
+        return x !== 0 || 1 / x === 1 / y;
+    }
+    return x !== x && y !== y;
+}
+
+function arrayCompare(a, b) {
+    if (a.length !== b.length) {
+        return false;
+    }
+    for (var i = 0; i < a.length; ++i) {
+        if (!is(a[i], b[i])) {
+            return false;
+        }
+    }
+    return true;
+}
+
+function testPrimitiveValue(string, callback)
+{
+    debug("Testing: " + string);
+    var value = eval("value = (" + string + ")");
+    test_data = value;
+    testValue(test_data, function(result) {
+        self.result = result;
+        shouldBeTrue("is(test_data, result)");
+        debug("");
+        callback();
+    });
+}
+
+function testObjectWithValue(string, callback)
+{
+    debug("Testing: " + string);
+    var value = eval("value = (" + string + ")");
+    test_data = value;
+    testValue(test_data, function(result) {
+        self.result = result;
+        shouldBeEqualToString("typeof result", "object");
+        shouldBe("Object.prototype.toString.call(result)", "Object.prototype.toString.call(test_data)");
+        shouldBeTrue("test_data !== result");
+        shouldBe("result.toString()", "test_data.toString()");
+        shouldBeTrue("is(test_data.valueOf(), result.valueOf())");
+        debug("");
+        callback();
+    });
+}
+
+function testUndefined(callback)
+{
+    testPrimitiveValue("undefined", callback);
+}
+
+function testNull(callback)
+{
+    testPrimitiveValue("null", callback);
+}
+
+function testBoolean(callback)
+{
+    debug("Testing boolean primitives");
+    debug("");
+    forEachWithCallback(testPrimitiveValue, ["true", "false"], callback);
+}
+
+function testBooleanObject(callback)
+{
+    debug("Testing Boolean objects");
+    debug("");
+    forEachWithCallback(testObjectWithValue, [
+        "new Boolean(true)",
+        "new Boolean(false)"
+    ], callback);
+}
+
+function testString(callback)
+{
+    debug("Testing string primitives");
+    debug("");
+    forEachWithCallback(testPrimitiveValue, [
+        "''",
+        "'this is a sample string'",
+        "'null(\\0)'"
+    ], callback);
+}
+
+function testStringObject(callback)
+{
+    debug("Testing String objects");
+    debug("");
+    forEachWithCallback(testObjectWithValue, [
+        "new String()",
+        "new String('this is a sample string')",
+        "new String('null(\\0)')"
+    ], callback);
+}
+
+function testNumber(callback)
+{
+    debug("Testing number primitives");
+    debug("");
+    forEachWithCallback(testPrimitiveValue, [
+        "NaN",
+        "-Infinity",
+        "-Number.MAX_VALUE",
+        "-0xffffffff",
+        "-0x80000000",
+        "-0x7fffffff",
+        "-1",
+        "-Number.MIN_VALUE",
+        "-0",
+        "0",
+        "1",
+        "Number.MIN_VALUE",
+        "0x7fffffff",
+        "0x80000000",
+        "0xffffffff",
+        "Number.MAX_VALUE",
+        "Infinity"
+    ], callback);
+}
+
+function testNumberObject(callback)
+{
+    debug("Testing Number objects");
+    debug("");
+    forEachWithCallback(testObjectWithValue, [
+        "new Number(NaN)",
+        "new Number(-Infinity)",
+        "new Number(-Number.MAX_VALUE)",
+        "new Number(-Number.MIN_VALUE)",
+        "new Number(-0)",
+        "new Number(0)",
+        "new Number(Number.MIN_VALUE)",
+        "new Number(Number.MAX_VALUE)",
+        "new Number(Infinity)"
+    ], callback);
+}
+
+function testDateObject(callback)
+{
+    debug("Testing Date objects");
+    debug("");
+    forEachWithCallback(testObjectWithValue, [
+        "new Date(-1e13)",
+        "new Date(-1e12)",
+        "new Date(-1e9)",
+        "new Date(-1e6)",
+        "new Date(-1e3)",
+        "new Date(0)",
+        "new Date(1e3)",
+        "new Date(1e6)",
+        "new Date(1e9)",
+        "new Date(1e12)",
+        "new Date(1e13)"
+    ], callback);
+}
+
+function testRegExpObject(callback)
+{
+    debug("Testing RegExp objects");
+    debug("");
+    function testRegExp(string, callback) {
+        debug("Testing RegExp: " + string);
+        var value = eval("value = (" + string + ")");
+        test_data = value;
+        testValue(test_data, function(result) {
+            self.result = result;
+            shouldBeTrue("test_data !== result");
+            shouldBeEqualToString("Object.prototype.toString.call(result)", "[object RegExp]");
+            shouldBe("result.toString()", "test_data.toString()");
+            debug("");
+            callback();
+        });
+    }
+
+    forEachWithCallback(testRegExp, [
+        "new RegExp()",
+        "/abc/",
+        "/abc/g",
+        "/abc/i",
+        "/abc/gi",
+        "/abc/m",
+        "/abc/mg",
+        "/abc/mi",
+        "/abc/mgi"
+    ], callback);
+}
+
+function testImageData(callback)
+{
+    debug("Testing ImageData");
+    evalAndLog("canvas = document.createElement('canvas')");
+    evalAndLog("canvas.width = 8");
+    evalAndLog("canvas.height = 8");
+    evalAndLog("test_data = canvas.getContext('2d').getImageData(0, 0, 8, 8)");
+
+    for (var i = 0; i < 256; ++i) {
+        test_data.data[i] = i;
+    }
+
+    testValue(test_data, function(result) {
+        self.result = result;
+        shouldBeTrue("test_data !== result");
+        shouldBeEqualToString("Object.prototype.toString.call(result)", "[object ImageData]");
+        shouldBe("result.width", "test_data.width");
+        shouldBe("result.height", "test_data.height");
+        shouldBe("result.data.length", "test_data.data.length");
+        if (arrayCompare(test_data.data, result.data)) {
+            testPassed("result data matches");
+        } else {
+            testFailed("result data doesn't match");
+        }
+        callback();
+    });
+}
+
+function readBlobAsText(blob, callback)
+{
+    var reader = new FileReader();
+    reader.onload = function(e) {
+        if (e.target.readyState === FileReader.DONE) {
+            callback(e.target.result);
+        }
+    };
+    reader.onerror = function(e) {
+        testFailed("Error reading blob as text: " + e);
+        finishJSTest();
+    };
+    reader.readAsText(blob);
+}
+
+function checkBlobContents(blob, expected, callback)
+{
+    readBlobAsText(blob, function(text) {
+        self.text = text;
+        shouldBeEqualToString("text", expected);
+        callback();
+    });
+}
+
+function compareBlobs(blob1, blob2, callback)
+{
+    readBlobAsText(blob1, function(text1) {
+        readBlobAsText(blob2, function(text2) {
+            self.text1 = text1;
+            self.text2 = text2;
+            shouldBeEqualToString("text2", text1);
+            callback();
+        });
+    });
+}
+
+function testBlob(callback)
+{
+    debug("Testing Blob");
+
+    // FIXME: Blob, File, and FileList support is incomplete.
+    // http://crbug.com/108012
+    debug("Skipping test");
+    callback();
+    return;
+
+    shouldBeTrue("FileReader != null");
+    evalAndLog("test_content = 'This is a test. This is only a test.'");
+    evalAndLog("test_data = new Blob([test_content])");
+    testValue(test_data, function(result) {
+        self.result = result;
+        shouldBeTrue("test_data !== result");
+        shouldBeEqualToString("Object.prototype.toString.call(result)", "[object Blob]");
+        shouldBe("result.size", "test_data.size");
+        shouldBe("result.type", "test_data.type");
+        checkBlobContents(result, test_content, callback);
+    });
+}
+
+function compareFiles(file1, file2, callback)
+{
+    self.file1 = file1;
+    self.file2 = file2;
+    shouldBeTrue("file1 !== file2");
+    shouldBeEqualToString("Object.prototype.toString.call(file1)", "[object File]");
+    shouldBeEqualToString("Object.prototype.toString.call(file2)", "[object File]");
+    debug("file1.size: " + file1.size);
+    shouldBe("file1.size", "file2.size");
+    debug("file1.type: " + file1.type);
+    shouldBe("file1.type", "file2.type");
+    debug("file1.name: " + file1.name);
+    shouldBe("file1.name", "file2.name");
+    shouldBe("String(file1.lastModifiedDate)", "String(file2.lastModifiedDate)");
+    if (callback) {
+        compareBlobs(file1, file2, callback);
+    }
+}
+
+function testFile(callback)
+{
+    debug("Testing File");
+
+    // FIXME: Blob, File, and FileList support is incomplete.
+    // http://crbug.com/108012
+    debug("Skipping test");
+    callback();
+    return;
+
+    evalAndLog("test_content = fileInput.files[0]");
+
+    self.test_data = test_content;
+    testValue(test_data, function(result) {
+        self.result = result;
+        compareFiles(result, test_data, callback);
+    });
+}
+
+
+function testFileList(callback)
+{
+    debug("Testing FileList");
+
+    // FIXME: Blob, File, and FileList support is incomplete.
+    // http://crbug.com/108012
+    debug("Skipping test");
+    callback();
+    return;
+
+    evalAndLog("test_content = fileInput.files");
+
+    self.test_data = test_content;
+    testValue(test_data, function(result) {
+        self.result = result;
+        shouldBeTrue("test_data !== result");
+        shouldBeEqualToString("Object.prototype.toString.call(result)", "[object FileList]");
+        shouldBe("result.length", "test_data.length");
+        i = 0;
+        function doNext() {
+            if (i >= test_data.length) {
+                callback();
+            } else {
+                debug("comparing file[" + i + "]");
+                compareFiles(result[i], test_data[i++], doNext);
+            }
+        }
+        doNext();
+    });
+}
+
+function testArray(callback) {
+    debug("Testing Array");
+    evalAndLog("test_data = []");
+    evalAndLog("test_data[0] = 'foo'");
+    evalAndLog("test_data[1] = 'bar'");
+    evalAndLog("test_data[10] = true");
+    evalAndLog("test_data[11] = false");
+    evalAndLog("test_data[20] = 123");
+    evalAndLog("test_data[21] = 456");
+    evalAndLog("test_data[30] = null");
+
+    testValue(test_data, function(result) {
+        self.result = result;
+        shouldBeTrue("test_data !== result");
+        shouldBeTrue("test_data.length === result.length");
+        Object.keys(test_data).forEach(
+            function(key) {
+                shouldBe("test_data[" + key + "]", "result[" + key + "]");
+            });
+        callback();
+    });
+}
+
+function testObject(callback) {
+    debug("Testing Object");
+    evalAndLog("test_data = []");
+    evalAndLog("test_data[0] = 'foo'");
+    evalAndLog("test_data[1] = 'bar'");
+    evalAndLog("test_data['a'] = true");
+    evalAndLog("test_data['b'] = false");
+    evalAndLog("test_data['foo'] = 123");
+    evalAndLog("test_data['bar'] = 456");
+    evalAndLog("test_data[''] = null");
+
+    testValue(test_data, function(result) {
+        self.result = result;
+        shouldBeTrue("test_data !== result");
+        shouldBeTrue("arrayCompare(Object.keys(result).sort(), Object.keys(test_data).sort())");
+        Object.keys(test_data).forEach(
+            function(key) {
+                shouldBe("test_data[" + JSON.stringify(key) + "]", "result[" + JSON.stringify(key) + "]");
+            });
+        callback();
+    });
+}
+
+function testTypedArray(callback) {
+    debug("Testing TypedArray");
+
+    function testTypedArrayValue(string, callback) {
+        evalAndLog("value = " + string);
+        test_data = value;
+        testValue(test_data, function(result) {
+            self.result = result;
+            shouldBeTrue("test_data !== result");
+            shouldBe("Object.prototype.toString.call(result)", "Object.prototype.toString.call(test_data)");
+            shouldBeTrue("test_data.length === result.length");
+            for (i = 0; i < test_data.length; ++i) {
+                shouldBeTrue("is(test_data[" + i + "], result[" + i + "])");
+            }
+            debug("");
+            callback();
+        });
+    }
+
+    forEachWithCallback(testTypedArrayValue, [
+        "new Uint8Array([])",
+        "new Uint8Array([0, 1, 254, 255])",
+        "new Uint16Array([0x0000, 0x0001, 0xFFFE, 0xFFFF])",
+        "new Uint32Array([0x00000000, 0x00000001, 0xFFFFFFFE, 0xFFFFFFFF])",
+        "new Int8Array([0, 1, 254, 255])",
+        "new Int16Array([0x0000, 0x0001, 0xFFFE, 0xFFFF])",
+        "new Int32Array([0x00000000, 0x00000001, 0xFFFFFFFE, 0xFFFFFFFF])",
+        "new Uint8ClampedArray([0, 1, 254, 255])",
+        "new Float32Array([-Infinity, -1.5, -1, -0.5, 0, 0.5, 1, 1.5, Infinity, NaN])",
+        "new Float64Array([-Infinity, -Number.MAX_VALUE, -Number.MIN_VALUE, 0, Number.MIN_VALUE, Number.MAX_VALUE, Infinity, NaN])"
+    ], callback);
+}
+
+function testBadTypes()
+{
+    debug("");
+    debug("Test types that can't be cloned:");
+    debug("");
+
+    evalAndLog("transaction = db.transaction('storeName', 'readwrite')");
+    evalAndLog("store = transaction.objectStore('storeName')");
+    transaction.onerror = unexpectedErrorCallback;
+    transaction.onabort = unexpectedAbortCallback;
+    transaction.oncomplete = finishJSTest;
+
+    debug("");
+    debug("Other JavaScript object types:");
+    evalAndExpectException("store.put(new Error, 'key')", "DOMException.DATA_CLONE_ERR");
+    evalAndExpectException("store.put(new Function, 'key')", "DOMException.DATA_CLONE_ERR");
+
+    debug("");
+    debug("Other host object types:");
+    evalAndExpectException("store.put(self, 'key')", "DOMException.DATA_CLONE_ERR");
+    evalAndExpectException("store.put(document, 'key')", "DOMException.DATA_CLONE_ERR");
+    evalAndExpectException("store.put(document.body, 'key')", "DOMException.DATA_CLONE_ERR");
+}
diff --git a/LayoutTests/storage/indexeddb/resources/transaction-complete-with-js-recursion-cross-frame.js b/LayoutTests/storage/indexeddb/resources/transaction-complete-with-js-recursion-cross-frame.js
new file mode 100644 (file)
index 0000000..f09d798
--- /dev/null
@@ -0,0 +1,46 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+var transaction;
+var store;
+var db;
+var body = document.getElementsByTagName("iframe")[0].contentDocument.body;
+
+description("Test that pending transactions are not completed during recursive JS calls until all JS (in all frames) is finished.");
+
+indexedDBTest(prepareDatabase, click);
+function prepareDatabase()
+{
+    db = event.target.result;
+    store = db.createObjectStore('objectStore', null);
+}
+
+function click() {
+    body.onclick = test;
+    var pendingTransaction = evalAndLog("pendingTransaction = db.transaction(['objectStore'], 'readwrite')");
+    pendingTransaction.onerror = unexpectedErrorCallback;
+    pendingTransaction.onabort = unexpectedAbortCallback;
+    pendingTransaction.oncomplete = completeCallback;
+    var event = document.createEvent("MouseEvent");
+    event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+    body.dispatchEvent(event);
+    var store = evalAndLog("store = pendingTransaction.objectStore('objectStore')");
+    shouldBeTrue("store !== undefined");
+    body.onclick = undefined;
+}
+
+function test()
+{
+    debug("Start re-entrant JS");
+    transaction = evalAndLog("transaction = db.transaction(['objectStore'], 'readwrite')");
+    debug("End re-entrant JS");
+}
+
+
+function completeCallback()
+{
+    debug("Pending transaction completed");
+    finishJSTest();
+}
diff --git a/LayoutTests/storage/indexeddb/resources/transaction-complete-with-js-recursion.js b/LayoutTests/storage/indexeddb/resources/transaction-complete-with-js-recursion.js
new file mode 100644 (file)
index 0000000..2b1976a
--- /dev/null
@@ -0,0 +1,47 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+var transaction;
+var store;
+var db;
+var body = document.getElementsByTagName("body")[0];
+
+description("Test that pending transactions are not completed during recursive JS calls until all JS is finished.");
+
+indexedDBTest(prepareDatabase, click);
+function prepareDatabase()
+{
+    db = event.target.result;
+    store = db.createObjectStore('objectStore', null);
+}
+
+function click()
+{
+    body.onclick = test;
+    var pendingTransaction = evalAndLog("pendingTransaction = db.transaction(['objectStore'], 'readwrite')");
+    pendingTransaction.onsuccess = unexpectedErrorCallback;
+    pendingTransaction.onerror = unexpectedErrorCallback;
+    pendingTransaction.oncomplete = completeCallback;
+    var event = document.createEvent("MouseEvent");
+    event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+    body.dispatchEvent(event);
+    var store = evalAndLog("store = pendingTransaction.objectStore('objectStore')");
+    shouldBeTrue("store !== undefined");
+    body.onclick = undefined;
+}
+
+function test()
+{
+    debug("Start re-entrant JS");
+    transaction = evalAndLog("transaction = db.transaction(['objectStore'], 'readwrite')");
+    debug("End re-entrant JS");
+}
+
+
+function completeCallback()
+{
+    testPassed("Pending transaction completed");
+    finishJSTest();
+}
diff --git a/LayoutTests/storage/indexeddb/resources/transaction-crash-in-tasks.js b/LayoutTests/storage/indexeddb/resources/transaction-crash-in-tasks.js
new file mode 100644 (file)
index 0000000..560e9d6
--- /dev/null
@@ -0,0 +1,17 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Regression test for http://webkit.org/b/102283");
+
+test();
+function test() {
+    removeVendorPrefixes();
+    setDBNameFromPath();
+
+    evalAndLog("indexedDB.open(dbname, 2)");
+    evalAndLog("indexedDB.open(dbname, 3)");
+
+    finishJSTest();
+}
diff --git a/LayoutTests/storage/indexeddb/resources/transaction-ordering.js b/LayoutTests/storage/indexeddb/resources/transaction-ordering.js
new file mode 100644 (file)
index 0000000..d7becc5
--- /dev/null
@@ -0,0 +1,57 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Verify Indexed DB transactions are ordered per spec");
+
+indexedDBTest(prepareDatabase, onOpen);
+
+function prepareDatabase(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("store = db.createObjectStore('store')");
+}
+
+function onOpen(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    debug("");
+    debug("Create in order tx1, tx2");
+    evalAndLog("tx1 = db.transaction('store', 'readwrite')");
+    evalAndLog("tx2 = db.transaction('store', 'readwrite')");
+    debug("");
+    debug("Use in order tx2, tx1");
+    evalAndLog("tx2.objectStore('store').get(0)");
+    evalAndLog("tx1.objectStore('store').get(0)");
+    debug("");
+    evalAndLog("order = []");
+
+    tx1.oncomplete = function(evt) {
+        debug("tx1 complete");
+        order.push(1);
+        if (order.length === 2) done();
+    };
+
+    tx2.oncomplete = function(evt) {
+        debug("tx1 complete");
+        order.push(2);
+        if (order.length === 2) done();
+    };
+
+    function done() {
+        preamble();
+        // IndexedDB Spec:
+        // https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#transaction-concept
+        //
+        // If multiple "readwrite" transactions are attempting to
+        // access the same object store (i.e. if they have overlapping
+        // scope), the transaction that was created first must be the
+        // transaction which gets access to the object store first.
+        //
+        shouldBeTrue("areArraysEqual(order, [ 1, 2 ])");
+        finishJSTest();
+    }
+}
diff --git a/LayoutTests/storage/indexeddb/resources/transaction-overlapping.js b/LayoutTests/storage/indexeddb/resources/transaction-overlapping.js
new file mode 100644 (file)
index 0000000..e542109
--- /dev/null
@@ -0,0 +1,75 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Check that transactions that may overlap complete properly.");
+
+indexedDBTest(prepareDatabase, runParallelTransactions);
+
+function prepareDatabase(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    evalAndLog("store = db.createObjectStore('store')");
+    evalAndLog("store.put('value', 'key')");
+}
+
+function runParallelTransactions(evt)
+{
+    preamble(evt);
+    evalAndLog("db = event.target.result");
+    debug("");
+    evalAndLog("transaction1 = db.transaction('store', 'readonly')");
+    transaction1.onabort = unexpectedAbortCallback;
+    transaction1.oncomplete = onTransactionComplete;
+    evalAndLog("transaction2 = db.transaction('store', 'readonly')");
+    transaction1.onabort = unexpectedAbortCallback;
+    transaction2.oncomplete = onTransactionComplete;
+
+    evalAndLog("transaction1GetSuccess = 0");
+    evalAndLog("transaction2GetSuccess = 0");
+
+    function doTransaction1Get() {
+        // NOTE: No logging since execution order is not deterministic.
+        request = transaction1.objectStore('store').get('key');
+        request.onerror = unexpectedErrorCallback;
+        request.onsuccess = function() {
+            ++transaction1GetSuccess;
+            if (!transaction2GetSuccess && transaction1GetSuccess < 10)
+                doTransaction1Get();
+        };
+    }
+
+    function doTransaction2Get() {
+        // NOTE: No logging since execution order is not deterministic.
+        request = transaction2.objectStore('store').get('key');
+        request.onerror = unexpectedErrorCallback;
+        request.onsuccess = function() {
+            ++transaction2GetSuccess;
+            if (!transaction1GetSuccess && transaction2GetSuccess < 10)
+                doTransaction2Get();
+        };
+    }
+
+    doTransaction1Get();
+    doTransaction2Get();
+}
+
+transactionCompletionCount = 0;
+function onTransactionComplete(evt)
+{
+    preamble(evt);
+
+    ++transactionCompletionCount;
+    if (transactionCompletionCount < 2) {
+        debug("first transaction complete, still waiting...");
+        return;
+    }
+
+    shouldBeNonZero("transaction1GetSuccess");
+    shouldBeNonZero("transaction2GetSuccess");
+
+    evalAndLog("db.close()");
+    finishJSTest();
+}
diff --git a/LayoutTests/storage/indexeddb/resources/version-change-event-basic.js b/LayoutTests/storage/indexeddb/resources/version-change-event-basic.js
new file mode 100644 (file)
index 0000000..83d1e99
--- /dev/null
@@ -0,0 +1,48 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+function log(msg) {
+    document.getElementById("logger").innerHTML += msg + "<br>";
+}
+
+var request1 = indexedDB.open("vceb1");
+request1.onupgradeneeded = function(e) {
+    log("First request: " + e.oldVersion + " " + e.newVersion);
+}
+
+var request2 = indexedDB.open("vceb2", 1);
+request2.onupgradeneeded = function(e) {
+    log("Second request: " + e.oldVersion + " " + e.newVersion);
+}
+
+var request3 = indexedDB.open("vceb3", 2);
+request3.onupgradeneeded = function(e) {
+    log("Third request: " + e.oldVersion + " " + e.newVersion);
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+try {
+    var request = indexedDB.open("vceb4", 0);
+} catch (e) {
+    log("0 version: " + e);
+}
+
+try {
+    var request = indexedDB.open("vceb5", -1);
+} catch (e) {
+    log("Negative version: " + e);
+}
+
+try {
+    var request = indexedDB.open("vceb6", "string");
+} catch (e) {
+    log("String version: " + e);
+}
diff --git a/LayoutTests/storage/indexeddb/resources/version-change-event.js b/LayoutTests/storage/indexeddb/resources/version-change-event.js
new file mode 100644 (file)
index 0000000..213334c
--- /dev/null
@@ -0,0 +1,36 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+    importScripts('shared.js');
+}
+
+description("Regression test for WK136583 - ensure the versionchange event has the proper name");
+
+indexedDBTest(prepareDatabase, upgradeDatabase);
+function prepareDatabase(evt)
+{
+    db = event.target.result;
+    evalAndLog("db.onversionchange = onVersionChange");
+    evalAndLog("store = db.createObjectStore('store1')");
+}
+
+function upgradeDatabase(evt)
+{
+    db = evt.target.result;
+    shouldBe("db.version", "1");
+    evalAndLog("request = indexedDB.open(dbname, 2)");
+    evalAndLog("db.onversionchange = onVersionChange");
+    request.onerror = unexpectedErrorCallback;
+    request.onsuccess = finishTest;
+}
+
+function onVersionChange(evt)
+{
+    preamble(evt);
+    shouldBeEqualToString("event.type", "versionchange");
+    db.close();
+}
+
+function finishTest(evt)
+{
+    finishJSTest();
+}
index 3adb317..62ebae5 100644 (file)
@@ -5,550 +5,6 @@
 </head>
 <body>
 <input type="file" id="fileInput" multiple></input>
-<script>
-
-description("Test structured clone permutations in IndexedDB. File/FileList tests require DumpRenderTree.");
-
-if (self.eventSender) {
-    var fileInput = document.getElementById("fileInput");
-    var fileRect = fileInput.getClientRects()[0];
-    var targetX = fileRect.left + fileRect.width / 2;
-    var targetY = fileRect.top + fileRect.height / 2;
-    eventSender.beginDragWithFiles(['resources/test-data.html', 'resources/test-data.txt']);
-    eventSender.mouseMoveTo(targetX, targetY);
-    eventSender.mouseUp();
-}
-
-indexedDBTest(prepareDatabase, startTests);
-function prepareDatabase()
-{
-    db = event.target.result;
-    evalAndLog("store = db.createObjectStore('storeName')");
-    debug("This index is not used, but evaluating key path on each put() call will exercise (de)serialization:");
-    evalAndLog("store.createIndex('indexName', 'dummyKeyPath')");
-}
-
-function startTests()
-{
-    debug("");
-    debug("Running tests...");
-    var tests_to_run = [
-        testUndefined,
-        testNull,
-        testBoolean,
-        testNumber,
-        testString,
-        testBooleanObject,
-        testNumberObject,
-        testStringObject,
-        testDateObject,
-        testRegExpObject,
-        testImageData,
-        testBlob,
-        testFile,
-        testFileList,
-        testArray,
-        testObject,
-        testTypedArray
-    ];
-
-    function nextTest() {
-        debug("");
-        if (tests_to_run.length) {
-            var test = tests_to_run.shift();
-            test(nextTest); // When done, call this again.
-        } else {
-            testBadTypes();
-        }
-    }
-    nextTest();
-}
-
-function forEachWithCallback(testFunction, values, callback)
-{
-    function nextValue() {
-        if (values.length) {
-            testFunction(values.shift(), nextValue);
-        } else {
-            callback();
-        }
-    }
-
-    nextValue();
-}
-
-function testValue(value, callback)
-{
-    // One transaction per test, since some tests require asynchronous
-    // operations to verify the result (e.g. via FileReader)
-    evalAndLog("transaction = db.transaction('storeName', 'readwrite')");
-    transaction.onerror = unexpectedErrorCallback;
-    transaction.onabort = unexpectedAbortCallback;
-    evalAndLog("store = transaction.objectStore('storeName')");
-
-    self.value = value;
-    request = evalAndLog("store.put(value, 'key')");
-    request.onerror = unexpectedErrorCallback;
-    request.onsuccess = function(e) {
-        request = evalAndLog("store.get('key')");
-        request.onerror = unexpectedErrorCallback;
-        request.onsuccess = function(e) {
-            callback(request.result);
-        };
-    };
-}
-
-// Identity testing, sensitive to NaN and -0
-function is(x, y) {
-    if (x === y) {
-        return x !== 0 || 1 / x === 1 / y;
-    }
-    return x !== x && y !== y;
-}
-
-function arrayCompare(a, b) {
-    if (a.length !== b.length) {
-        return false;
-    }
-    for (var i = 0; i < a.length; ++i) {
-        if (!is(a[i], b[i])) {
-            return false;
-        }
-    }
-    return true;
-}
-
-function testPrimitiveValue(string, callback)
-{
-    debug("Testing: " + string);
-    var value = eval("value = (" + string + ")");
-    test_data = value;
-    testValue(test_data, function(result) {
-        self.result = result;
-        shouldBeTrue("is(test_data, result)");
-        debug("");
-        callback();
-    });
-}
-
-function testObjectWithValue(string, callback)
-{
-    debug("Testing: " + string);
-    var value = eval("value = (" + string + ")");
-    test_data = value;
-    testValue(test_data, function(result) {
-        self.result = result;
-        shouldBeEqualToString("typeof result", "object");
-        shouldBe("Object.prototype.toString.call(result)", "Object.prototype.toString.call(test_data)");
-        shouldBeTrue("test_data !== result");
-        shouldBe("result.toString()", "test_data.toString()");
-        shouldBeTrue("is(test_data.valueOf(), result.valueOf())");
-        debug("");
-        callback();
-    });
-}
-
-function testUndefined(callback)
-{
-    testPrimitiveValue("undefined", callback);
-}
-
-function testNull(callback)
-{
-    testPrimitiveValue("null", callback);
-}
-
-function testBoolean(callback)
-{
-    debug("Testing boolean primitives");
-    debug("");
-    forEachWithCallback(testPrimitiveValue, ["true", "false"], callback);
-}
-
-function testBooleanObject(callback)
-{
-    debug("Testing Boolean objects");
-    debug("");
-    forEachWithCallback(testObjectWithValue, [
-        "new Boolean(true)",
-        "new Boolean(false)"
-    ], callback);
-}
-
-function testString(callback)
-{
-    debug("Testing string primitives");
-    debug("");
-    forEachWithCallback(testPrimitiveValue, [
-        "''",
-        "'this is a sample string'",
-        "'null(\\0)'"
-    ], callback);
-}
-
-function testStringObject(callback)
-{
-    debug("Testing String objects");
-    debug("");
-    forEachWithCallback(testObjectWithValue, [
-        "new String()",
-        "new String('this is a sample string')",
-        "new String('null(\\0)')"
-    ], callback);
-}
-
-function testNumber(callback)
-{
-    debug("Testing number primitives");
-    debug("");
-    forEachWithCallback(testPrimitiveValue, [
-        "NaN",
-        "-Infinity",
-        "-Number.MAX_VALUE",
-        "-0xffffffff",
-        "-0x80000000",
-        "-0x7fffffff",
-        "-1",
-        "-Number.MIN_VALUE",
-        "-0",
-        "0",
-        "1",
-        "Number.MIN_VALUE",
-        "0x7fffffff",
-        "0x80000000",
-        "0xffffffff",
-        "Number.MAX_VALUE",
-        "Infinity"
-    ], callback);
-}
-
-function testNumberObject(callback)
-{
-    debug("Testing Number objects");
-    debug("");
-    forEachWithCallback(testObjectWithValue, [
-        "new Number(NaN)",
-        "new Number(-Infinity)",
-        "new Number(-Number.MAX_VALUE)",
-        "new Number(-Number.MIN_VALUE)",
-        "new Number(-0)",
-        "new Number(0)",
-        "new Number(Number.MIN_VALUE)",
-        "new Number(Number.MAX_VALUE)",
-        "new Number(Infinity)"
-    ], callback);
-}
-
-function testDateObject(callback)
-{
-    debug("Testing Date objects");
-    debug("");
-    forEachWithCallback(testObjectWithValue, [
-        "new Date(-1e13)",
-        "new Date(-1e12)",
-        "new Date(-1e9)",
-        "new Date(-1e6)",
-        "new Date(-1e3)",
-        "new Date(0)",
-        "new Date(1e3)",
-        "new Date(1e6)",
-        "new Date(1e9)",
-        "new Date(1e12)",
-        "new Date(1e13)"
-    ], callback);
-}
-
-function testRegExpObject(callback)
-{
-    debug("Testing RegExp objects");
-    debug("");
-    function testRegExp(string, callback) {
-        debug("Testing RegExp: " + string);
-        var value = eval("value = (" + string + ")");
-        test_data = value;
-        testValue(test_data, function(result) {
-            self.result = result;
-            shouldBeTrue("test_data !== result");
-            shouldBeEqualToString("Object.prototype.toString.call(result)", "[object RegExp]");
-            shouldBe("result.toString()", "test_data.toString()");
-            debug("");
-            callback();
-        });
-    }
-
-    forEachWithCallback(testRegExp, [
-        "new RegExp()",
-        "/abc/",
-        "/abc/g",
-        "/abc/i",
-        "/abc/gi",
-        "/abc/m",
-        "/abc/mg",
-        "/abc/mi",
-        "/abc/mgi"
-    ], callback);
-}
-
-function testImageData(callback)
-{
-    debug("Testing ImageData");
-    evalAndLog("canvas = document.createElement('canvas')");
-    evalAndLog("canvas.width = 8");
-    evalAndLog("canvas.height = 8");
-    evalAndLog("test_data = canvas.getContext('2d').getImageData(0, 0, 8, 8)");
-
-    for (var i = 0; i < 256; ++i) {
-        test_data.data[i] = i;
-    }
-
-    testValue(test_data, function(result) {
-        self.result = result;
-        shouldBeTrue("test_data !== result");
-        shouldBeEqualToString("Object.prototype.toString.call(result)", "[object ImageData]");
-        shouldBe("result.width", "test_data.width");
-        shouldBe("result.height", "test_data.height");
-        shouldBe("result.data.length", "test_data.data.length");
-        if (arrayCompare(test_data.data, result.data)) {
-            testPassed("result data matches");
-        } else {
-            testFailed("result data doesn't match");
-        }
-        callback();
-    });
-}
-
-function readBlobAsText(blob, callback)
-{
-    var reader = new FileReader();
-    reader.onload = function(e) {
-        if (e.target.readyState === FileReader.DONE) {
-            callback(e.target.result);
-        }
-    };
-    reader.onerror = function(e) {
-        testFailed("Error reading blob as text: " + e);
-        finishJSTest();
-    };
-    reader.readAsText(blob);
-}
-
-function checkBlobContents(blob, expected, callback)
-{
-    readBlobAsText(blob, function(text) {
-        self.text = text;
-        shouldBeEqualToString("text", expected);
-        callback();
-    });
-}
-
-function compareBlobs(blob1, blob2, callback)
-{
-    readBlobAsText(blob1, function(text1) {
-        readBlobAsText(blob2, function(text2) {
-            self.text1 = text1;
-            self.text2 = text2;
-            shouldBeEqualToString("text2", text1);
-            callback();
-        });
-    });
-}
-
-function testBlob(callback)
-{
-    debug("Testing Blob");
-
-    // FIXME: Blob, File, and FileList support is incomplete.
-    // http://crbug.com/108012
-    debug("Skipping test");
-    callback();
-    return;
-
-    shouldBeTrue("FileReader != null");
-    evalAndLog("test_content = 'This is a test. This is only a test.'");
-    evalAndLog("test_data = new Blob([test_content])");
-    testValue(test_data, function(result) {
-        self.result = result;
-        shouldBeTrue("test_data !== result");
-        shouldBeEqualToString("Object.prototype.toString.call(result)", "[object Blob]");
-        shouldBe("result.size", "test_data.size");
-        shouldBe("result.type", "test_data.type");
-        checkBlobContents(result, test_content, callback);
-    });
-}
-
-function compareFiles(file1, file2, callback)
-{
-    self.file1 = file1;
-    self.file2 = file2;
-    shouldBeTrue("file1 !== file2");
-    shouldBeEqualToString("Object.prototype.toString.call(file1)", "[object File]");
-    shouldBeEqualToString("Object.prototype.toString.call(file2)", "[object File]");
-    debug("file1.size: " + file1.size);
-    shouldBe("file1.size", "file2.size");
-    debug("file1.type: " + file1.type);
-    shouldBe("file1.type", "file2.type");
-    debug("file1.name: " + file1.name);
-    shouldBe("file1.name", "file2.name");
-    shouldBe("String(file1.lastModifiedDate)", "String(file2.lastModifiedDate)");
-    if (callback) {
-        compareBlobs(file1, file2, callback);
-    }
-}
-
-function testFile(callback)
-{
-    debug("Testing File");
-
-    // FIXME: Blob, File, and FileList support is incomplete.
-    // http://crbug.com/108012
-    debug("Skipping test");
-    callback();
-    return;
-
-    evalAndLog("test_content = fileInput.files[0]");
-
-    self.test_data = test_content;
-    testValue(test_data, function(result) {
-        self.result = result;
-        compareFiles(result, test_data, callback);
-    });
-}
-
-
-function testFileList(callback)
-{
-    debug("Testing FileList");
-
-    // FIXME: Blob, File, and FileList support is incomplete.
-    // http://crbug.com/108012
-    debug("Skipping test");
-    callback();
-    return;
-
-    evalAndLog("test_content = fileInput.files");
-
-    self.test_data = test_content;
-    testValue(test_data, function(result) {
-        self.result = result;
-        shouldBeTrue("test_data !== result");
-        shouldBeEqualToString("Object.prototype.toString.call(result)", "[object FileList]");
-        shouldBe("result.length", "test_data.length");
-        i = 0;
-        function doNext() {
-            if (i >= test_data.length) {
-                callback();
-            } else {
-                debug("comparing file[" + i + "]");
-                compareFiles(result[i], test_data[i++], doNext);
-            }
-        }
-        doNext();
-    });
-}
-
-function testArray(callback) {
-    debug("Testing Array");
-    evalAndLog("test_data = []");
-    evalAndLog("test_data[0] = 'foo'");
-    evalAndLog("test_data[1] = 'bar'");
-    evalAndLog("test_data[10] = true");
-    evalAndLog("test_data[11] = false");
-    evalAndLog("test_data[20] = 123");
-    evalAndLog("test_data[21] = 456");
-    evalAndLog("test_data[30] = null");
-
-    testValue(test_data, function(result) {
-        self.result = result;
-        shouldBeTrue("test_data !== result");
-        shouldBeTrue("test_data.length === result.length");
-        Object.keys(test_data).forEach(
-            function(key) {
-                shouldBe("test_data[" + key + "]", "result[" + key + "]");
-            });
-        callback();
-    });
-}
-
-function testObject(callback) {
-    debug("Testing Object");
-    evalAndLog("test_data = []");
-    evalAndLog("test_data[0] = 'foo'");
-    evalAndLog("test_data[1] = 'bar'");
-    evalAndLog("test_data['a'] = true");
-    evalAndLog("test_data['b'] = false");
-    evalAndLog("test_data['foo'] = 123");
-    evalAndLog("test_data['bar'] = 456");
-    evalAndLog("test_data[''] = null");
-
-    testValue(test_data, function(result) {
-        self.result = result;
-        shouldBeTrue("test_data !== result");
-        shouldBeTrue("arrayCompare(Object.keys(result).sort(), Object.keys(test_data).sort())");
-        Object.keys(test_data).forEach(
-            function(key) {
-                shouldBe("test_data[" + JSON.stringify(key) + "]", "result[" + JSON.stringify(key) + "]");
-            });
-        callback();
-    });
-}
-
-function testTypedArray(callback) {
-    debug("Testing TypedArray");
-
-    function testTypedArrayValue(string, callback) {
-        evalAndLog("value = " + string);
-        test_data = value;
-        testValue(test_data, function(result) {
-            self.result = result;
-            shouldBeTrue("test_data !== result");
-            shouldBe("Object.prototype.toString.call(result)", "Object.prototype.toString.call(test_data)");
-            shouldBeTrue("test_data.length === result.length");
-            for (i = 0; i < test_data.length; ++i) {
-                shouldBeTrue("is(test_data[" + i + "], result[" + i + "])");
-            }
-            debug("");
-            callback();
-        });
-    }
-
-    forEachWithCallback(testTypedArrayValue, [
-        "new Uint8Array([])",
-        "new Uint8Array([0, 1, 254, 255])",
-        "new Uint16Array([0x0000, 0x0001, 0xFFFE, 0xFFFF])",
-        "new Uint32Array([0x00000000, 0x00000001, 0xFFFFFFFE, 0xFFFFFFFF])",
-        "new Int8Array([0, 1, 254, 255])",
-        "new Int16Array([0x0000, 0x0001, 0xFFFE, 0xFFFF])",
-        "new Int32Array([0x00000000, 0x00000001, 0xFFFFFFFE, 0xFFFFFFFF])",
-        "new Uint8ClampedArray([0, 1, 254, 255])",
-        "new Float32Array([-Infinity, -1.5, -1, -0.5, 0, 0.5, 1, 1.5, Infinity, NaN])",
-        "new Float64Array([-Infinity, -Number.MAX_VALUE, -Number.MIN_VALUE, 0, Number.MIN_VALUE, Number.MAX_VALUE, Infinity, NaN])"
-    ], callback);
-}
-
-function testBadTypes()
-{
-    debug("");
-    debug("Test types that can't be cloned:");
-    debug("");
-
-    evalAndLog("transaction = db.transaction('storeName', 'readwrite')");
-    evalAndLog("store = transaction.objectStore('storeName')");
-    transaction.onerror = unexpectedErrorCallback;
-    transaction.onabort = unexpectedAbortCallback;
-    transaction.oncomplete = finishJSTest;
-
-    debug("");
-    debug("Other JavaScript object types:");
-    evalAndExpectException("store.put(new Error, 'key')", "DOMException.DATA_CLONE_ERR");
-    evalAndExpectException("store.put(new Function, 'key')", "DOMException.DATA_CLONE_ERR");
-
-    debug("");
-    debug("Other host object types:");
-    evalAndExpectException("store.put(self, 'key')", "DOMException.DATA_CLONE_ERR");
-    evalAndExpectException("store.put(document, 'key')", "DOMException.DATA_CLONE_ERR");
-    evalAndExpectException("store.put(document.body, 'key')", "DOMException.DATA_CLONE_ERR");
-}
-
-</script>
+<script src="resources/structured-clone.js"></script>
 </body>
 </html>
index 9c6d474..d23c653 100644 (file)
@@ -8,50 +8,6 @@
     <body>
     </body>
 </iframe>
-<script>
-
-var transaction;
-var store;
-var db;
-var body = document.getElementsByTagName("iframe")[0].contentDocument.body;
-
-description("Test that pending transactions are not completed during recursive JS calls until all JS (in all frames) is finished.");
-
-indexedDBTest(prepareDatabase, click);
-function prepareDatabase()
-{
-    db = event.target.result;
-    store = db.createObjectStore('objectStore', null);
-}
-
-function click() {
-    body.onclick = test;
-    var pendingTransaction = evalAndLog("pendingTransaction = db.transaction(['objectStore'], 'readwrite')");
-    pendingTransaction.onerror = unexpectedErrorCallback;
-    pendingTransaction.onabort = unexpectedAbortCallback;
-    pendingTransaction.oncomplete = completeCallback;
-    var event = document.createEvent("MouseEvent");
-    event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
-    body.dispatchEvent(event);
-    var store = evalAndLog("store = pendingTransaction.objectStore('objectStore')");
-    shouldBeTrue("store !== undefined");
-    body.onclick = undefined;
-}
-
-function test()
-{
-    debug("Start re-entrant JS");
-    transaction = evalAndLog("transaction = db.transaction(['objectStore'], 'readwrite')");
-    debug("End re-entrant JS");
-}
-
-
-function completeCallback()
-{
-    debug("Pending transaction completed");
-    finishJSTest();
-}
-
-</script>
+<script src="resources/transaction-complete-with-js-recursion-cross-frame.js"></script>
 </body>
 </html>
index f95797e..858f177 100644 (file)
@@ -4,51 +4,6 @@
 <script src="resources/shared.js"></script>
 </head>
 <body>
-<script>
-
-var transaction;
-var store;
-var db;
-var body = document.getElementsByTagName("body")[0];
-
-description("Test that pending transactions are not completed during recursive JS calls until all JS is finished.");
-
-indexedDBTest(prepareDatabase, click);
-function prepareDatabase()
-{
-    db = event.target.result;
-    store = db.createObjectStore('objectStore', null);
-}
-
-function click()
-{
-    body.onclick = test;
-    var pendingTransaction = evalAndLog("pendingTransaction = db.transaction(['objectStore'], 'readwrite')");
-    pendingTransaction.onsuccess = unexpectedErrorCallback;
-    pendingTransaction.onerror = unexpectedErrorCallback;
-    pendingTransaction.oncomplete = completeCallback;
-    var event = document.createEvent("MouseEvent");
-    event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
-    body.dispatchEvent(event);
-    var store = evalAndLog("store = pendingTransaction.objectStore('objectStore')");
-    shouldBeTrue("store !== undefined");
-    body.onclick = undefined;
-}
-
-function test()
-{
-    debug("Start re-entrant JS");
-    transaction = evalAndLog("transaction = db.transaction(['objectStore'], 'readwrite')");
-    debug("End re-entrant JS");
-}
-
-
-function completeCallback()
-{
-    testPassed("Pending transaction completed");
-    finishJSTest();
-}
-
-</script>
+<script src="resources/transaction-complete-with-js-recursion.js"></script>
 </body>
 </html>
index 1fa9993..0626f52 100644 (file)
@@ -1,18 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-
-description("Regression test for http://webkit.org/b/102283");
-
-test();
-function test() {
-    removeVendorPrefixes();
-    setDBNameFromPath();
-
-    evalAndLog("indexedDB.open(dbname, 2)");
-    evalAndLog("indexedDB.open(dbname, 3)");
-
-    finishJSTest();
-}
-</script>
+</head>
+<body>
+<script src="resources/transaction-crash-in-tasks.js"></script>
+</body>
+</html>
index 6c6d6e6..ac5eaab 100644 (file)
@@ -1,60 +1,9 @@
-<!DOCTYPE html>
+<html>
+<head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
-<script>
-
-description("Verify Indexed DB transactions are ordered per spec");
-
-indexedDBTest(prepareDatabase, onOpen);
-
-function prepareDatabase(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("store = db.createObjectStore('store')");
-}
-
-function onOpen(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    debug("");
-    debug("Create in order tx1, tx2");
-    evalAndLog("tx1 = db.transaction('store', 'readwrite')");
-    evalAndLog("tx2 = db.transaction('store', 'readwrite')");
-    debug("");
-    debug("Use in order tx2, tx1");
-    evalAndLog("tx2.objectStore('store').get(0)");
-    evalAndLog("tx1.objectStore('store').get(0)");
-    debug("");
-    evalAndLog("order = []");
-
-    tx1.oncomplete = function(evt) {
-        debug("tx1 complete");
-        order.push(1);
-        if (order.length === 2) done();
-    };
-
-    tx2.oncomplete = function(evt) {
-        debug("tx1 complete");
-        order.push(2);
-        if (order.length === 2) done();
-    };
-
-    function done() {
-        preamble();
-        // IndexedDB Spec:
-        // https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#transaction-concept
-        //
-        // If multiple "readwrite" transactions are attempting to
-        // access the same object store (i.e. if they have overlapping
-        // scope), the transaction that was created first must be the
-        // transaction which gets access to the object store first.
-        //
-        shouldBeTrue("areArraysEqual(order, [ 1, 2 ])");
-        finishJSTest();
-    }
-}
-
-
-</script>
+</head>
+<body>
+<script src="resources/transaction-ordering.js"></script>
+</body>
+</html>
index c6c6c1f..1aa650f 100644 (file)
@@ -1,81 +1,9 @@
-<!DOCTYPE html>
 <html>
 <head>
 <script src="../../resources/js-test.js"></script>
 <script src="resources/shared.js"></script>
 </head>
 <body>
-<script>
-description("Check that transactions that may overlap complete properly.");
-
-indexedDBTest(prepareDatabase, runParallelTransactions);
-
-function prepareDatabase(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    evalAndLog("store = db.createObjectStore('store')");
-    evalAndLog("store.put('value', 'key')");
-}
-
-function runParallelTransactions(evt)
-{
-    preamble(evt);
-    evalAndLog("db = event.target.result");
-    debug("");
-    evalAndLog("transaction1 = db.transaction('store', 'readonly')");
-    transaction1.onabort = unexpectedAbortCallback;
-    transaction1.oncomplete = onTransactionComplete;
-    evalAndLog("transaction2 = db.transaction('store', 'readonly')");
-    transaction1.onabort = unexpectedAbortCallback;
-    transaction2.oncomplete = onTransactionComplete;
-
-    evalAndLog("transaction1GetSuccess = 0");
-    evalAndLog("transaction2GetSuccess = 0");
-
-    function doTransaction1Get() {
-        // NOTE: No logging since execution order is not deterministic.
-        request = transaction1.objectStore('store').get('key');
-        request.onerror = unexpectedErrorCallback;
-        request.onsuccess = function() {
-            ++transaction1GetSuccess;
-            if (!transaction2GetSuccess && transaction1GetSuccess < 10)
-                doTransaction1Get();
-        };
-    }
-
-    function doTransaction2Get() {
-        // NOTE: No logging since execution order is not deterministic.
-        request = transaction2.objectStore('store').get('key');
-        request.onerror = unexpectedErrorCallback;
-        request.onsuccess = function() {
-            ++transaction2GetSuccess;
-            if (!transaction1GetSuccess && transaction2GetSuccess < 10)
-                doTransaction2Get();
-        };
-    }
-
-    doTransaction1Get();
-    doTransaction2Get();
-}
-
-transactionCompletionCount = 0;
-function onTransactionComplete(evt)
-{
-    preamble(evt);
-
-    ++transactionCompletionCount;
-    if (transactionCompletionCount < 2) {
-        debug("first transaction complete, still waiting...");
-        return;
-    }
-
-    shouldBeNonZero("transaction1GetSuccess");
-    shouldBeNonZero("transaction2GetSuccess");
-
-    evalAndLog("db.close()");
-    finishJSTest();
-}
-</script>
+<script src="resources/transaction-overlapping.js"></script>
 </body>
 </html>
index 0a7a81b..4141421 100644 (file)
@@ -1,51 +1,10 @@
+<html>
+<head>
+<script src="../../resources/js-test.js"></script>
+<script src="resources/shared.js"></script>
+</head>
 <body>
 <div id="logger"></div>
-<script>
-
-if (window.testRunner) {
-    testRunner.dumpAsText();
-    testRunner.waitUntilDone();
-}
-
-function log(msg) {
-    document.getElementById("logger").innerHTML += msg + "<br>";
-}
-
-var request1 = indexedDB.open("vceb1");
-request1.onupgradeneeded = function(e) {
-    log("First request: " + e.oldVersion + " " + e.newVersion);
-}
-
-var request2 = indexedDB.open("vceb2", 1);
-request2.onupgradeneeded = function(e) {
-    log("Second request: " + e.oldVersion + " " + e.newVersion);
-}
-
-var request3 = indexedDB.open("vceb3", 2);
-request3.onupgradeneeded = function(e) {
-    log("Third request: " + e.oldVersion + " " + e.newVersion);
-    if (window.testRunner)
-        testRunner.notifyDone();
-}
-
-try {
-    var request = indexedDB.open("vceb4", 0);
-} catch (e) {
-    log("0 version: " + e);
-}
-
-try {
-    var request = indexedDB.open("vceb5", -1);
-} catch (e) {
-    log("Negative version: " + e);
-}
-
-try {
-    var request = indexedDB.open("vceb6", "string");
-} catch (e) {
-    log("String version: " + e);
-}
-
-</script>
+<script src="resources/version-change-event-basic.js"></script>
 </body>
 </html>
index 35836a5..ee0d5e5 100644 (file)
@@ -4,40 +4,6 @@
 <script src="resources/shared.js"></script>
 </head>
 <body>
-<script>
-
-description("Regression test for WK136583 - ensure the versionchange event has the proper name");
-
-indexedDBTest(prepareDatabase, upgradeDatabase);
-function prepareDatabase(evt)
-{
-    db = event.target.result;
-    evalAndLog("db.onversionchange = onVersionChange");
-    evalAndLog("store = db.createObjectStore('store1')");
-}
-
-function upgradeDatabase(evt)
-{
-    db = evt.target.result;
-    shouldBe("db.version", "1");
-    evalAndLog("request = indexedDB.open(dbname, 2)");
-    evalAndLog("db.onversionchange = onVersionChange");
-    request.onerror = unexpectedErrorCallback;
-    request.onsuccess = finishTest;
-}
-
-function onVersionChange(evt)
-{
-    preamble(evt);
-    shouldBeEqualToString("event.type", "versionchange");
-    db.close();
-}
-
-function finishTest(evt)
-{
-    finishJSTest();
-}
-
-</script>
+<script src="resources/version-change-event.js"></script>
 </body>
 </html>