Title: [106165] trunk/LayoutTests
Revision
106165
Author
jsb...@chromium.org
Date
2012-01-27 16:04:52 -0800 (Fri, 27 Jan 2012)

Log Message

IndexedDB does not update r/w index cursors that are mutated during iteration
https://bugs.webkit.org/show_bug.cgi?id=59822

Added tests to verify that index cursors see updates made to an object store while
iterating, assuming the cursor and updates occur within the same transaction.

Reviewed by Tony Chang.

* storage/indexeddb/mozilla/cursor-mutation-expected.txt: Added.
* storage/indexeddb/mozilla/cursor-mutation.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (106164 => 106165)


--- trunk/LayoutTests/ChangeLog	2012-01-27 23:42:04 UTC (rev 106164)
+++ trunk/LayoutTests/ChangeLog	2012-01-28 00:04:52 UTC (rev 106165)
@@ -1,3 +1,16 @@
+2012-01-27  Joshua Bell  <jsb...@chromium.org>
+
+        IndexedDB does not update r/w index cursors that are mutated during iteration
+        https://bugs.webkit.org/show_bug.cgi?id=59822
+
+        Added tests to verify that index cursors see updates made to an object store while
+        iterating, assuming the cursor and updates occur within the same transaction.
+
+        Reviewed by Tony Chang.
+
+        * storage/indexeddb/mozilla/cursor-mutation-expected.txt: Added.
+        * storage/indexeddb/mozilla/cursor-mutation.html: Added.
+
 2012-01-27  Raymond Toy  <r...@google.com>
 
         Round time to sample frame

Added: trunk/LayoutTests/storage/indexeddb/mozilla/cursor-mutation-expected.txt (0 => 106165)


--- trunk/LayoutTests/storage/indexeddb/mozilla/cursor-mutation-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/mozilla/cursor-mutation-expected.txt	2012-01-28 00:04:52 UTC (rev 106165)
@@ -0,0 +1,138 @@
+Test IndexedDB's cursor mutation
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB
+PASS indexedDB == null is false
+IDBDatabaseException = window.IDBDatabaseException || window.webkitIDBDatabaseException
+PASS IDBDatabaseException == null is false
+IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction
+PASS IDBTransaction == null is false
+
+indexedDB.deleteDatabase(name)
+indexedDB.open(name)
+db = event.target.result
+db.setVersion('1')
+
+setupObjectStoreAndCreateIndex():
+trans = request.result
+objectStore = db.createObjectStore('foo', { keyPath: 'ss' })
+index = objectStore.createIndex('name', 'name', { unique: true })
+objectStoreData = [
+        { ss: '237-23-7732', name: 'Bob' },
+        { ss: '237-23-7733', name: 'Ann' },
+        { ss: '237-23-7734', name: 'Ron' },
+        { ss: '237-23-7735', name: 'Sue' },
+        { ss: '237-23-7736', name: 'Joe' },
+        { ss: '237-23-7737', name: 'Pat' }
+    ]
+objectStore.add(objectStoreData[0])
+objectStore.add(objectStoreData[1])
+objectStore.add(objectStoreData[2])
+objectStore.add(objectStoreData[3])
+objectStore.add(objectStoreData[4])
+trans._oncomplete_ = checkCursorResults
+
+setupCursor():
+count = 0
+sawAdded = false
+sawRemoved = false
+request = objectStore.openCursor()
+
+iterateCursor():
+cursor = event.target.result
+PASS cursor.value.name is "Bob"
+sawRemoved = true
+count++
+cursor.continue()
+
+iterateCursor():
+cursor = event.target.result
+PASS cursor.value.name is "Ann"
+count++
+cursor.continue()
+
+iterateCursor():
+cursor = event.target.result
+PASS cursor.value.name is "Ron"
+count++
+cursor.continue()
+
+iterateCursor():
+cursor = event.target.result
+PASS cursor.value.name is "Sue"
+count++
+cursor.continue()
+
+iterateCursor():
+cursor = event.target.result
+PASS cursor.value.name is "Joe"
+count++
+cursor.continue()
+
+iterateCursor():
+cursor = event.target.result
+
+checkCursorResults():
+PASS count is objectStoreData.length - 1
+PASS sawAdded is false
+PASS sawRemoved is true
+
+setupMutatingCursor():
+count = 0
+sawAdded = false
+sawRemoved = false
+[objectStoreDataNameSort is an array of indexes into objectStoreData in alphabetical order by name]
+objectStoreDataNameSort = [ 1, 4, 5, 2, 3 ]
+
+trans = db.transaction('foo', IDBTransaction.READ_WRITE)
+objectStore = trans.objectStore('foo')
+request = objectStore.index('name').openCursor()
+trans._oncomplete_ = checkMutatingCursorResults
+
+iterateMutatingCursor():
+cursor = event.target.result
+PASS cursor.value.name is "Ann"
+count++
+
+Mutating the object store:
+Removing Bob
+request = objectStore.delete(objectStoreData[0].ss)
+
+addFinalData():
+Adding Pat
+request = objectStore.add(objectStoreData[objectStoreData.length - 1])
+
+iterateMutatingCursor():
+cursor = event.target.result
+PASS cursor.value.name is "Joe"
+count++
+
+iterateMutatingCursor():
+cursor = event.target.result
+PASS cursor.value.name is "Pat"
+sawAdded = true
+count++
+
+iterateMutatingCursor():
+cursor = event.target.result
+PASS cursor.value.name is "Ron"
+count++
+
+iterateMutatingCursor():
+cursor = event.target.result
+PASS cursor.value.name is "Sue"
+count++
+
+iterateMutatingCursor():
+cursor = event.target.result
+
+checkMutatingCursorResults():
+PASS count is objectStoreData.length - 1
+PASS sawAdded is true
+PASS sawRemoved is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/storage/indexeddb/mozilla/cursor-mutation.html (0 => 106165)


--- trunk/LayoutTests/storage/indexeddb/mozilla/cursor-mutation.html	                        (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/mozilla/cursor-mutation.html	2012-01-28 00:04:52 UTC (rev 106165)
@@ -0,0 +1,199 @@
+<!DOCTYPE html>
+<!--
+  original test: http://mxr.mozilla.org/mozilla2.0/source/dom/indexedDB/test/test_cursor_mutation.html?force=1
+  license of original test:
+    " Any copyright is dedicated to the Public Domain.
+      http://creativecommons.org/publicdomain/zero/1.0/ "
+-->
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+
+description("Test IndexedDB's cursor mutation");
+if (window.layoutTestController)
+    layoutTestController.waitUntilDone();
+
+function test()
+{
+    indexedDB = evalAndLog("indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB");
+    shouldBeFalse("indexedDB == null");
+    IDBDatabaseException = evalAndLog("IDBDatabaseException = window.IDBDatabaseException || window.webkitIDBDatabaseException");
+    shouldBeFalse("IDBDatabaseException == null");
+    IDBTransaction = evalAndLog("IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction");
+    shouldBeFalse("IDBTransaction == null");
+
+    debug("");
+    name = 'cursor-mutation';
+    request = evalAndLog("indexedDB.deleteDatabase(name)");
+    request._onerror_ = unexpectedErrorCallback;
+    request._onsuccess_ = function () {
+        request = evalAndLog("indexedDB.open(name)");
+        request._onerror_ = unexpectedErrorCallback;
+        request._onsuccess_ = function () {
+            evalAndLog("db = event.target.result");
+            request = evalAndLog("db.setVersion('1')");
+            request._onerror_ = unexpectedErrorCallback;
+            request._onsuccess_ = setupObjectStoreAndCreateIndex;          
+        };
+    };
+}
+
+function setupObjectStoreAndCreateIndex()
+{
+    debug("");
+    debug("setupObjectStoreAndCreateIndex():");
+
+    trans = evalAndLog("trans = request.result");
+
+    objectStore = evalAndLog("objectStore = db.createObjectStore('foo', { keyPath: 'ss' })");
+    index = evalAndLog("index = objectStore.createIndex('name', 'name', { unique: true })");
+    objectStoreData = evalAndLog("objectStoreData = [\n" + 
+         // To be removed.
+"        { ss: '237-23-7732', name: 'Bob' },\n" + 
+
+         // Always present.
+"        { ss: '237-23-7733', name: 'Ann' },\n" +
+"        { ss: '237-23-7734', name: 'Ron' },\n" +
+"        { ss: '237-23-7735', name: 'Sue' },\n" +
+"        { ss: '237-23-7736', name: 'Joe' },\n" +
+
+         // To be added.
+"        { ss: '237-23-7737', name: 'Pat' }\n" +
+"    ]");
+
+    for (i = 0; i < objectStoreData.length - 1; i++) {
+        evalAndLog("objectStore.add(objectStoreData[" + i + "])");
+    }
+
+    evalAndLog("trans._oncomplete_ = checkCursorResults");
+    setupCursor();
+}
+
+function setupCursor()
+{
+    debug("");
+    debug("setupCursor():");
+
+    count = evalAndLog("count = 0");
+    sawAdded = evalAndLog("sawAdded = false");
+    sawRemoved = evalAndLog("sawRemoved = false");
+
+    request = evalAndLog("request = objectStore.openCursor()");
+    request._onerror_ = unexpectedErrorCallback;
+    request._onsuccess_ = iterateCursor;
+}
+
+function iterateCursor()
+{
+    debug("");
+    debug("iterateCursor():");
+    cursor = evalAndLog("cursor = event.target.result");
+    if (cursor) {
+        shouldBeEqualToString("cursor.value.name", objectStoreData[count].name);
+        if (cursor.value.name == objectStoreData[0].name) {
+            sawRemoved = evalAndLog("sawRemoved = true");
+        }
+        if (cursor.value.name == objectStoreData[objectStoreData.length - 1].name) {
+            sawAdded = evalAndLog("sawAdded = true");
+        }
+        evalAndLog("count++");
+        evalAndLog("cursor.continue()");
+    }
+}
+
+function checkCursorResults()
+{
+    debug("");
+    debug("checkCursorResults():");
+    shouldBe("count", "objectStoreData.length - 1");
+    shouldBe("sawAdded", "false");
+    shouldBe("sawRemoved", "true");
+
+    setupMutatingCursor();
+}
+
+function setupMutatingCursor()
+{
+    debug("");
+    debug("setupMutatingCursor():");
+   
+    count = evalAndLog("count = 0");
+    sawAdded = evalAndLog("sawAdded = false");
+    sawRemoved = evalAndLog("sawRemoved = false");
+    debug("[objectStoreDataNameSort is an array of indexes into objectStoreData in alphabetical order by name]");
+    objectStoreDataNameSort = evalAndLog("objectStoreDataNameSort = [ 1, 4, 5, 2, 3 ]");
+
+    debug("");
+
+    trans = evalAndLog("trans = db.transaction('foo', IDBTransaction.READ_WRITE)");
+    objectStore = evalAndLog("objectStore = trans.objectStore('foo')");
+    request = evalAndLog("request = objectStore.index('name').openCursor()");
+    request._onerror_ = unexpectedErrorCallback;
+    request._onsuccess_ = iterateMutatingCursor;
+    evalAndLog("trans._oncomplete_ = checkMutatingCursorResults");
+}
+
+function iterateMutatingCursor()
+{
+    debug("");
+    debug("iterateMutatingCursor():");
+    cursor = evalAndLog("cursor = event.target.result");
+    if (cursor) {
+        shouldBeEqualToString("cursor.value.name", objectStoreData[objectStoreDataNameSort[count]].name);
+        if (cursor.value.name == objectStoreData[0].name) {
+            sawRemoved = evalAndLog("sawRemoved = true");
+        }
+        if (cursor.value.name == objectStoreData[objectStoreData.length - 1].name) {
+            sawAdded = evalAndLog("sawAdded = true");
+        }
+        evalAndLog("count++");
+
+        if (count == 1) {
+            debug("");
+            debug("Mutating the object store:");
+
+            debug("Removing " + objectStoreData[0].name);
+            request = evalAndLog("request = objectStore.delete(objectStoreData[0].ss)");
+            request._onerror_ = unexpectedErrorCallback;
+            request._onsuccess_ = addFinalData;
+
+        } else {
+            cursor.continue();
+        }
+    }
+}
+
+function addFinalData()
+{
+    debug("");
+    debug("addFinalData():");
+    debug("Adding " + objectStoreData[objectStoreData.length - 1].name);
+    request = evalAndLog("request = objectStore.add(objectStoreData[objectStoreData.length - 1])");
+    request._onerror_ = unexpectedErrorCallback;
+    request._onsuccess_ = function () {
+        cursor.continue();
+    }
+}
+
+function checkMutatingCursorResults()
+{
+    debug("");
+    debug("checkMutatingCursorResults():");
+    shouldBe("count", "objectStoreData.length - 1");
+    shouldBe("sawAdded", "true");
+    shouldBe("sawRemoved", "false");
+    done();
+}
+
+test();
+
+</script>
+</body>
+</html>
+
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to