• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
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>
7</head>
8<body>
9<p id="description"></p>
10<div id="console"></div>
11<script>
12
13description("Test IndexedDB's cursor skips deleted entries.");
14if (window.layoutTestController)
15    layoutTestController.waitUntilDone();
16
17var 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'];
21
22test();
23
24function test()
25{
26    request = evalAndLog("webkitIndexedDB.open('cursor-skip-deleted')");
27    request.onsuccess = openSuccess;
28    request.onerror = unexpectedErrorCallback;
29}
30
31function openSuccess()
32{
33    var db = evalAndLog("db = event.target.result");
34
35    request = evalAndLog("db.setVersion('new version')");
36    request.onsuccess = setVersionSuccess;
37    request.onerror = unexpectedErrorCallback;
38}
39
40function setVersionSuccess()
41{
42    debug("setVersionSuccess():");
43    window.trans = evalAndLog("trans = event.target.result");
44    shouldBeTrue("trans !== null");
45    trans.onabort = unexpectedAbortCallback;
46    trans.oncomplete = basicCursorTest;
47
48    deleteAllObjectStores(db);
49
50    var objectStore = evalAndLog("objectStore = db.createObjectStore('store', {keyPath: 'id'})");
51    evalAndLog("objectStore.createIndex('nameIndex', 'name')");
52    resetObjectStore(function() {});
53}
54
55var silentErrorHandler = function() { event.preventDefault(); }
56
57function resetObjectStore(callback)
58{
59    debug("\nresetObjectStore():");
60    if (callback === undefined)
61        callback = function () {};
62
63    var objectStore = trans.objectStore('store');
64    for (var i = 0; i < names.length; i++)
65        objectStore.delete(i).onerror = silentErrorHandler;
66    for (var i = 0; i < names.length; i++)
67        objectStore.add({id: i, name: names[i]}).onerror = unexpectedErrorCallback;
68
69    debug("");
70    callback();
71}
72
73function contains(arr, obj)
74{
75    for (var i = 0; i < arr.length; i++) {
76        if (arr[i] == obj)
77            return true;
78    }
79    return false;
80}
81
82var cursor;
83var deleted;
84var seen;
85
86function testCursor(deleteList, createCursorCommand, callback)
87{
88    debug("\ntestCursor():");
89    deleted = [];
90    seen = [];
91
92    // Create the cursor.
93    request = evalAndLog(createCursorCommand);
94
95    request.onerror = unexpectedErrorCallback;
96    request.onsuccess = function () {
97        if (event.target.result == null) {
98            // Make sure we have seen every non-deleted item.
99            for (var i = 0; i < names.length; i++) {
100                if (contains(deleted, i))
101                    continue;
102
103                if (!contains(seen, i))
104                    testFailed("Cursor did not see item with id: " + i);
105            }
106
107            // Make sure we used every rule in |deleteList|.
108            for (var i = 0; i < deleteList.length; i++) {
109                if (!contains(seen, deleteList[i].id))
110                    testFailed("deleteList rule with id: " + deleteList[i].id + " was never used.");
111            }
112
113            debug("");
114            callback();
115            return;
116        }
117
118        cursor = event.target.result;
119        debug(event.target.result.value.id + ": " + event.target.result.value.name);
120        seen.push(event.target.result.value.id);
121
122        // Make sure we don't see any deleted items.
123        if (contains(deleted, event.target.result.value.id))
124            testFailed("Cursor hit previously deleted element.");
125
126        for (var i = 0; i < deleteList.length; i++) {
127            if (event.target.result.value.id == deleteList[i].id) {
128                // Delete objects targeted by this id.
129                var targets = deleteList[i].targets;
130                for (var j = 0; j < targets.length; j++) {
131                    deleted.push(targets[j]);
132                    request = evalAndLog("request = trans.objectStore('store').delete(" + targets[j] + ")");
133                    request.onerror = unexpectedErrorCallback;
134                    if (j == targets.length - 1)
135                        request.onsuccess = function() { cursor.continue(); }
136                }
137                return;
138            }
139        }
140
141        cursor.continue();
142    }
143}
144
145function basicCursorTest()
146{
147    debug("basicCursorTest()");
148
149    evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
150    trans.onabort = unexpectedAbortCallback;
151    trans.oncomplete = transactionComplete;
152
153    var deletes = [{id: 1, targets: [0]},
154                   {id: 2, targets: [names.length - 1]},
155                   {id: 3, targets: [5,6,7]},
156                   {id: 10, targets: [10]},
157                   {id: 12, targets: [13]},
158                   {id: 15, targets: [14]},
159                   {id: 20, targets: [17,18]}
160                   ];
161
162    testCursor(deletes, "trans.objectStore('store').openCursor(webkitIDBKeyRange.lowerBound(0))", function() { resetObjectStore(reverseCursorTest); });
163}
164
165function reverseCursorTest()
166{
167    debug("reverseCursorTest():");
168
169    var deletes = [{id: 24, targets: [names.length - 1]},
170                   {id: 23, targets: [0]},
171                   {id: 22, targets: [20, 19, 18]},
172                   {id: 15, targets: [15]},
173                   {id: 13, targets: [12]},
174                   {id: 10, targets: [11]},
175                   {id: 5, targets: [7,8]}
176                   ];
177
178
179    testCursor(deletes, "trans.objectStore('store').openCursor(webkitIDBKeyRange.lowerBound(0), webkitIDBCursor.PREV)", function() { resetObjectStore(indexCursorTest); });
180}
181
182function indexCursorTest()
183{
184    debug("indexCursorTest():");
185
186    var deletes = [{id: 1, targets: [0]},
187                   {id: 2, targets: [names.length - 1]},
188                   {id: 3, targets: [5,6,7]},
189                   {id: 10, targets: [10]},
190                   {id: 12, targets: [13]},
191                   {id: 15, targets: [14]},
192                   {id: 20, targets: [17,18]}
193                   ];
194
195    testCursor(deletes, "trans.objectStore('store').index('nameIndex').openCursor(webkitIDBKeyRange.lowerBound('Alpha'))", function() { });
196}
197
198function transactionComplete()
199{
200    debug("transactionComplete():");
201    done();
202}
203
204var successfullyParsed = true;
205
206</script>
207</body>
208</html>
209