abb26be015c8ad37c1667def4b6b04b06970f897
[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         // we sprinkle these checks across the dataset, to sample
129         // behavior against pre-fetching. Make sure to use prime
130         // numbers for these checks to avoid overlap.
131         if (self.continueValue % 2 == 0) {
132             // it's ok to call update() and then continue..
133             evalAndLog("cursor.update({ x: 100 + self.continueValue })");
134             evalAndLog("cursor.continue()");
135         } else if (self.continueValue % 3 == 0) {
136             // it's ok to call delete() and then continue
137             evalAndLog("cursor.delete()");
138             evalAndLog("cursor.continue()");
139         } else if (self.continueValue % 5 == 0) {
140             // it's NOT ok to call continue and then update
141             evalAndLog("cursor.continue()");
142             evalAndExpectException("cursor.update({ x: 100 + self.continueValue})",
143                                    "DOMException.INVALID_STATE_ERR");
144         } else if (self.continueValue % 7 == 0) {
145             // it's NOT ok to call continue and then delete
146             evalAndLog("cursor.continue()");
147             evalAndExpectException("cursor.delete()",
148                                    "DOMException.INVALID_STATE_ERR");
149         } else {
150             evalAndLog("cursor.continue()");
151         }
152
153     } else {
154         finishJSTest();
155     }
156 }