3 <link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
4 <script src="../../fast/js/resources/js-test-pre.js"></script>
5 <script src="../../fast/js/resources/js-test-post-function.js"></script>
6 <script src="resources/shared.js"></script>
9 <p id="description"></p>
10 <div id="console"></div>
13 description("Test IndexedDB's cursor skips deleted entries.");
14 if (window.layoutTestController)
15 layoutTestController.waitUntilDone();
17 var names = ['Alpha', 'Bravo', 'Charlie', 'Delta', 'Echo', 'Foxtrot', 'Golf',
18 'Hotel', 'India', 'Juliet', 'Kilo', 'Lima', 'Mike', 'November',
19 'Oscar', 'Papa', 'Quebec', 'Romeo', 'Sierra', 'Tango', 'Uniform',
20 'Victor', 'Whiskey', 'X-ray', 'Yankee', 'Zulu'];
26 result = evalAndLog("webkitIndexedDB.open('name')");
28 result.onsuccess = openSuccess;
29 result.onerror = unexpectedErrorCallback;
32 function openSuccess()
34 verifySuccessEvent(event);
35 var db = evalAndLog("db = event.result");
37 result = evalAndLog("db.setVersion('new version')");
39 result.onsuccess = setVersionSuccess;
40 result.onerror = unexpectedErrorCallback;
43 function setVersionSuccess()
45 debug("setVersionSuccess():");
46 verifySuccessEvent(event);
47 window.trans = evalAndLog("trans = event.result");
48 shouldBeTrue("trans !== null");
49 trans.onabort = unexpectedAbortCallback;
50 trans.oncomplete = basicCursorTest;
52 deleteAllObjectStores(db, createAndPopulateObjectStore);
55 function createAndPopulateObjectStore()
57 debug("createAndPopulateObjectStore():");
59 var objectStore = evalAndLog("objectStore = db.createObjectStore('store', {keyPath: 'id'})");
60 evalAndLog("objectStore.createIndex('nameIndex', 'name')");
61 resetObjectStore(function() {});
64 var silentErrorHandler = function() { event.preventDefault(); }
66 function resetObjectStore(callback)
68 debug("\nresetObjectStore():");
69 if (callback === undefined)
70 callback = function () {};
72 var objectStore = trans.objectStore('store');
73 for (var i = 0; i < names.length; i++)
74 objectStore.delete(i).onerror = silentErrorHandler;
75 for (var i = 0; i < names.length; i++)
76 objectStore.add({id: i, name: names[i]}).onerror = unexpectedErrorCallback;
82 function contains(arr, obj)
84 for (var i = 0; i < arr.length; i++) {
95 function testCursor(deleteList, createCursorCommand, callback)
97 debug("\ntestCursor():");
101 // Create the cursor.
102 request = evalAndLog(createCursorCommand);
103 verifyResult(request);
105 request.onerror = unexpectedErrorCallback;
106 request.onsuccess = function () {
107 if (event.result == null) {
108 // Make sure we have seen every non-deleted item.
109 for (var i = 0; i < names.length; i++) {
110 if (contains(deleted, i))
113 if (!contains(seen, i))
114 testFailed("Cursor did not see item with id: " + i);
117 // Make sure we used every rule in |deleteList|.
118 for (var i = 0; i < deleteList.length; i++) {
119 if (!contains(seen, deleteList[i].id))
120 testFailed("deleteList rule with id: " + deleteList[i].id + " was never used.");
128 cursor = event.result;
129 debug(event.result.value.id + ": " + event.result.value.name);
130 seen.push(event.result.value.id);
132 // Make sure we don't see any deleted items.
133 if (contains(deleted, event.result.value.id))
134 testFailed("Cursor hit previously deleted element.");
136 for (var i = 0; i < deleteList.length; i++) {
137 if (event.result.value.id == deleteList[i].id) {
138 // Delete objects targeted by this id.
139 var targets = deleteList[i].targets;
140 for (var j = 0; j < targets.length; j++) {
141 deleted.push(targets[j]);
142 request = evalAndLog("request = trans.objectStore('store').delete(" + targets[j] + ")");
143 request.onerror = unexpectedErrorCallback;
144 if (j == targets.length - 1)
145 request.onsuccess = function() { cursor.continue(); }
155 function basicCursorTest()
157 debug("basicCursorTest()");
159 evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
160 trans.onabort = unexpectedAbortCallback;
161 trans.oncomplete = transactionComplete;
163 var deletes = [{id: 1, targets: [0]},
164 {id: 2, targets: [names.length - 1]},
165 {id: 3, targets: [5,6,7]},
166 {id: 10, targets: [10]},
167 {id: 12, targets: [13]},
168 {id: 15, targets: [14]},
169 {id: 20, targets: [17,18]}
172 testCursor(deletes, "trans.objectStore('store').openCursor(webkitIDBKeyRange.lowerBound(0))", function() { resetObjectStore(reverseCursorTest); });
175 function reverseCursorTest()
177 debug("reverseCursorTest():");
179 var deletes = [{id: 24, targets: [names.length - 1]},
180 {id: 23, targets: [0]},
181 {id: 22, targets: [20, 19, 18]},
182 {id: 15, targets: [15]},
183 {id: 13, targets: [12]},
184 {id: 10, targets: [11]},
185 {id: 5, targets: [7,8]}
189 testCursor(deletes, "trans.objectStore('store').openCursor(webkitIDBKeyRange.lowerBound(0), webkitIDBCursor.PREV)", function() { resetObjectStore(indexCursorTest); });
192 function indexCursorTest()
194 debug("indexCursorTest():");
196 var deletes = [{id: 1, targets: [0]},
197 {id: 2, targets: [names.length - 1]},
198 {id: 3, targets: [5,6,7]},
199 {id: 10, targets: [10]},
200 {id: 12, targets: [13]},
201 {id: 15, targets: [14]},
202 {id: 20, targets: [17,18]}
205 testCursor(deletes, "trans.objectStore('store').index('nameIndex').openCursor(webkitIDBKeyRange.lowerBound('Alpha'))", function() { });
208 function transactionComplete()
210 debug("transactionComplete():");
214 var successfullyParsed = true;