Modern IDB: storage/indexeddb/cursor-continue-validity.html fails.
[WebKit-https.git] / LayoutTests / storage / indexeddb / resources / cursor-continue-validity.js
1 if (this.importScripts) {
2     importScripts('../../../resources/js-test.js');
3     importScripts('shared.js');
4 }
5
6 description("Test IndexedDB's IDBCursor.continue() behavior when called beyond normal scope.");
7
8 var date = new Date();
9
10 // we set this pretty high because we get different behavior depending
11 // if we're in a pre-fetched state or not
12 self.testLength = 25;
13
14 indexedDBTest(prepareDatabase);
15 function prepareDatabase()
16 {
17     db = event.target.result;
18     self.trans = evalAndLog("trans = event.target.transaction");
19     shouldBeNonNull("trans");
20     trans.onabort = unexpectedAbortCallback;
21
22     self.objectStore = evalAndLog("db.createObjectStore('someObjectStore')");
23     self.indexObject = evalAndLog("objectStore.createIndex('someIndex', 'x')");
24     self.nextToAdd = 0;
25     addData();
26 }
27
28 function addData()
29 {
30     for (var i=0; i<self.testLength; i++) {
31         evalAndLog("objectStore.add({'x': " + i + " }, " + i + ")");
32     }
33     evalAndLog("continueTest()");
34 }
35
36 function continueTest()
37 {
38     debug("");
39     debug("Checking objectStore");
40     debug("====================");
41     var request = evalAndLog("indexObject.openCursor(null, 'next')");
42     evalAndLog("self.continueValue = 0");
43     request.onsuccess = evalAndLogCallback("doubleContinueCallback()");
44     request.onerror = unexpectedErrorCallback;
45     self.stage = 0;
46 }
47
48 function doubleContinueCallback()
49 {
50     evalAndLog("cursor = event.target.result");
51     if (cursor) {
52         debug("Checking value at " + self.continueValue);
53         // data should be valid before calling continue()
54         shouldBe("cursor.key", "" + self.continueValue);
55         shouldBe("cursor.value.x", "" + self.continueValue);
56
57         // Data should not change during iteration, even if continue() is called and extra time.
58         evalAndLog("cursor.continue()");
59         shouldBe("cursor.key", "" + self.continueValue);
60         shouldBe("cursor.value.x", "" + self.continueValue);
61
62         // Even if continue is called more than once, the value still shouldn't change.
63         evalAndExpectException("cursor.continue()", "DOMException.INVALID_STATE_ERR");
64         shouldBe("cursor.key", "" + self.continueValue);
65         shouldBe("cursor.value.x", "" + self.continueValue);
66         evalAndLog("self.continueValue++;");
67     } else {
68         evalAndLog("continueIndexTest()");
69     }
70 }
71
72 function continueIndexTest()
73 {
74     debug("");
75     debug("Checking index");
76     debug("==============");
77     var request = evalAndLog("indexObject.openCursor(null, 'next')");
78     evalAndLog("self.continueValue = 0");
79     request.onsuccess = doubleContinueIndexCallback;
80     request.onerror = unexpectedErrorCallback;
81     self.stage = 0;
82 }
83
84 function doubleContinueIndexCallback()
85 {
86     evalAndLog("cursor = event.target.result");
87     if (cursor) {
88         debug("Checking value at " + self.continueValue);
89         // data should be valid before calling continue()
90         shouldBe("cursor.key", "" + self.continueValue);
91         shouldBe("cursor.value.x", "" + self.continueValue);
92
93         // Data should not change during iteration, even if continue() is called and extra time.
94         evalAndLog("cursor.continue()");
95         shouldBe("cursor.key", "" + self.continueValue);
96         shouldBe("cursor.value.x", "" + self.continueValue);
97
98         // Even if continue is called more than once, the value still shouldn't change.
99         evalAndExpectException("cursor.continue()", "DOMException.INVALID_STATE_ERR");
100         shouldBe("cursor.key", "" + self.continueValue);
101         shouldBe("cursor.value.x", "" + self.continueValue);
102         evalAndLog("self.continueValue++;");
103     } else {
104         evalAndLog("testModifyContinueOrder()");
105     }
106
107 }
108
109 // Note: This mutates the data
110 function testModifyContinueOrder()
111 {
112     debug("");
113     debug("Checking modification");
114     debug("=====================");
115     var request = evalAndLog("indexObject.openCursor(null, 'next')");
116     evalAndLog("self.continueValue = 0");
117     request.onsuccess = modifyContinueOrderCallback;
118     request.onerror = unexpectedErrorCallback;
119     self.stage = 0;
120 }
121
122 function modifyContinueOrderCallback()
123 {
124     cursor = evalAndLog("cursor = event.target.result");
125
126     self.continueValue++;
127     if (cursor) {
128         debug("");
129         debug("Index key is: " + cursor.key);
130         debug("Primary key is: " + cursor.primaryKey);
131         debug("Value.x is: " + cursor.value.x);
132         debug("Continue value: " + self.continueValue);
133
134         // we sprinkle these checks across the dataset, to sample
135         // behavior against pre-fetching. Make sure to use prime
136         // numbers for these checks to avoid overlap.
137         if (self.continueValue % 2 == 0) {
138             // it's ok to call update() and then continue..
139             debug("New Index key for primary key " + cursor.primaryKey + " is " + (100 + self.continueValue));
140             evalAndLog("cursor.update({ x: 100 + self.continueValue })");
141             evalAndLog("cursor.continue()");
142         } else if (self.continueValue % 3 == 0) {
143             // it's ok to call delete() and then continue
144             debug("Deleting primary key " + cursor.primaryKey + " which currently has Index key " + cursor.key);
145             evalAndLog("cursor.delete()");
146             evalAndLog("cursor.continue()");
147         } else if (self.continueValue % 5 == 0) {
148             // it's NOT ok to call continue and then update
149             evalAndLog("cursor.continue()");
150             debug("Expecting exception setting new Index key for primary key " + cursor.primaryKey + " to " + (100 + self.continueValue));
151             evalAndExpectException("cursor.update({ x: 100 + self.continueValue})",
152                                    "DOMException.INVALID_STATE_ERR");
153         } else if (self.continueValue % 7 == 0) {
154             // it's NOT ok to call continue and then delete
155             evalAndLog("cursor.continue()");
156             debug("Expecting exception deleting primary key " + cursor.primaryKey + " which currently has Index key " + cursor.key);
157             evalAndExpectException("cursor.delete()",
158                                    "DOMException.INVALID_STATE_ERR");
159         } else {
160             evalAndLog("cursor.continue()");
161         }
162
163     } else {
164         finishJSTest();
165     }
166 }