Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / LayoutTests / storage / indexeddb / resources / key-generator.js
blob489310933725fb2b18a5e6899f637171a33b3be3
1 if (this.importScripts) {
2     importScripts('../../../resources/js-test.js');
3     importScripts('shared.js');
6 description("Test IndexedDB's key generator behavior.");
8 function test()
10     runTests();
13 var tests = [];
14 function defineTest(description, verchange, optional) {
15   tests.push(
16     {
17       description: description,
18       verchange: verchange,
19       optional: optional
20     }
21   );
24 function runTests() {
26     function nextTest() {
27         if (!tests.length) {
28             testAcrossConnections();
29             return;
30         }
32         var test = tests.shift();
33         debug("");
34         debug(test.description);
36         indexedDBTest(prepareDatabase, onSuccess);
37         function prepareDatabase()
38         {
39             db = event.target.result;
40             trans = event.target.transaction;
41             trans.onabort = unexpectedAbortCallback;
42             test.verchange(db, trans);
43         }
44         function onSuccess() {
45             db = event.target.result;
47             function finishTest() {
48                 evalAndLog("db.close()");
49                 nextTest();
50             }
52             if (test.optional) {
53                 test.optional(db, finishTest);
54             } else {
55                 finishTest();
56             }
57         };
58     }
60     nextTest();
63 function check(store, key, expected) {
64     self.store = store;
65     request = evalAndLog("request = store.get(" + JSON.stringify(key) + ")");
66     request.onerror = unexpectedErrorCallback;
67     request.onsuccess = function (e) {
68         self.expected = expected;
69         if (JSON.stringify(event.target.result) === JSON.stringify(expected)) {
70             testPassed("Got " + JSON.stringify(event.target.result) + " for key: " + JSON.stringify(key));
71         } else {
72             testFailed("Got " + JSON.stringify(event.target.result) + " for key: " + JSON.stringify(key) +
73                 " expected: " + JSON.stringify(expected));
74         }
75     };
78 defineTest(
79     'Verify that each object store has an independent key generator.',
80     function (db, trans) {
81         evalAndLog("store1 = db.createObjectStore('store1', { autoIncrement: true })");
82         evalAndLog("store1.put('a')");
83         check(store1, 1, 'a');
84         evalAndLog("store2 = db.createObjectStore('store2', { autoIncrement: true })");
85         evalAndLog("store2.put('a')");
86         check(store2, 1, 'a');
87         evalAndLog("store1.put('b')");
88         check(store1, 2, 'b');
89         evalAndLog("store2.put('b')");
90         check(store2, 2, 'b');
91     }
94 defineTest(
95     'Verify that the key generator is not updated if insertion fails',
96     function (db, trans) {
97         trans.onerror = function(e) { e.preventDefault() };
98         evalAndLog("store = db.createObjectStore('store1', { autoIncrement: true })");
99         evalAndLog("index = store.createIndex('index1', 'ix', { unique: true })");
100         evalAndLog("store.put({ ix: 'a'})");
101         check(store, 1, {ix: 'a'});
102         evalAndLog("store.put({ ix: 'a'})");
103         evalAndLog("store.put({ ix: 'b'})");
104         check(store, 2, {ix: 'b'});
105     }
108 defineTest(
109     'Verify that the key generator is not affected by item removal (delete or clear).',
110     function (db, trans) {
111         evalAndLog("store = db.createObjectStore('store1', { autoIncrement: true })");
112         evalAndLog("store.put('a')");
113         check(store, 1, 'a');
114         evalAndLog("store.delete(1)");
115         evalAndLog("store.put('b')");
116         check(store, 2, 'b');
117         evalAndLog("store.clear()");
118         evalAndLog("store.put('c')");
119         check(store, 3, 'c');
120         evalAndLog("store.delete(IDBKeyRange.lowerBound(0))");
121         evalAndLog("store.put('d')");
122         check(store, 4, 'd');
123     }
126 defineTest(
127     'Verify that the key generator is only set if and only if a numeric key greater than the last generated key is used.',
128     function (db, trans) {
129         evalAndLog("store = db.createObjectStore('store1', { autoIncrement: true })");
130         evalAndLog("store.put('a')");
131         check(store, 1, 'a');
132         evalAndLog("store.put('b', 3)");
133         check(store, 3, 'b');
134         evalAndLog("store.put('c')");
135         check(store, 4, 'c');
136         evalAndLog("store.put('d', -10)");
137         check(store, -10, 'd');
138         evalAndLog("store.put('e')");
139         check(store, 5, 'e');
140         evalAndLog("store.put('f', 6.00001)");
141         check(store, 6.00001, 'f');
142         evalAndLog("store.put('g')");
143         check(store, 7, 'g');
144         evalAndLog("store.put('f', 8.9999)");
145         check(store, 8.9999, 'f');
146         evalAndLog("store.put('g')");
147         check(store, 9, 'g');
148         evalAndLog("store.put('h', 'foo')");
149         check(store, 'foo', 'h');
150         evalAndLog("store.put('i')");
151         check(store, 10, 'i');
152         evalAndLog("store.put('j', [1000])");
153         check(store, [1000], 'j');
154         evalAndLog("store.put('k')");
155         check(store, 11, 'k');
157         // FIXME: Repeat this test, but with a keyPath and inline key.
158     }
161 defineTest(
162     'Verify that aborting a transaction resets the key generator state.',
163     function (db, trans) {
164         db.createObjectStore('store', { autoIncrement: true });
165     },
167     function (db, callback) {
168         evalAndLog("trans1 = db.transaction(['store'], 'readwrite')");
169         evalAndLog("store_t1 = trans1.objectStore('store')");
170         evalAndLog("store_t1.put('a')");
171         check(store_t1, 1, 'a');
172         evalAndLog("store_t1.put('b')");
173         check(store_t1, 2, 'b');
175         // Schedule the abort as a task (not run it synchronously)
176         store_t1.get(0).onsuccess = function () {
177             debug('aborting...');
178             evalAndLog("trans1.abort()");
179             trans1.onabort = function () {
180                 debug('aborted!');
182                 evalAndLog("trans2 = db.transaction(['store'], 'readwrite')");
183                 evalAndLog("store_t2 = trans2.objectStore('store')");
184                 evalAndLog("store_t2.put('c')");
185                 check(store_t2, 1, 'c');
186                 evalAndLog("store_t2.put('d')");
187                 check(store_t2, 2, 'd');
189                 trans2.oncomplete = callback;
190             };
191         };
192     }
195 defineTest(
196     'Verify that keys above 2^53 result in errors.',
197     function (db, trans) {
198         db.createObjectStore('store', { autoIncrement: true });
199     },
201     function (db, callback) {
202         evalAndLog("trans1 = db.transaction(['store'], 'readwrite')");
203         evalAndLog("store_t1 = trans1.objectStore('store')");
204         evalAndLog("store_t1.put('a')");
205         check(store_t1, 1, 'a');
206         evalAndLog("store_t1.put('b', 9007199254740992)");
207         check(store_t1, 9007199254740992, 'b');
208         request = evalAndLog("store_t1.put('c')");
209         request.onsuccess = unexpectedSuccessCallback;
210         request.onerror = function () {
211             debug("Error event fired auto-incrementing past 2^53 (as expected)");
212             shouldBe("event.target.error.name", "'ConstraintError'");
213             evalAndLog("event.preventDefault()");
214         };
215         evalAndLog("store_t1.put('d', 2)");
216         check(store_t1, 2, 'd');
218         trans1.oncomplete = callback;
219     }
222 function testAcrossConnections()
224     debug("");
225     debug("Ensure key generator state is maintained across connections:");
226     indexedDBTest(prepareDatabase, doFirstWrite);
227     function prepareDatabase()
228     {
229         db = event.target.result;
230         evalAndLog("db.createObjectStore('store', {autoIncrement: true})");
231     };
233     function doFirstWrite() {
234         debug("");
235         evalAndLog("trans = db.transaction('store', 'readwrite')");
236         trans.onabort = unexpectedAbortCallback;
237         evalAndLog("request = trans.objectStore('store').put('value1')");
238         request.onerror = unexpectedErrorCallback;
239         request.onsuccess = function() {
240             shouldBe("request.result", "1");
241             evalAndLog("trans.objectStore('store').clear()");
242         };
243         trans.oncomplete = closeAndReopen;
244     }
246     function closeAndReopen() {
247         evalAndLog("db.close()");
248         debug("");
249         evalAndLog("request = indexedDB.open(dbname)");
250         request.onsuccess = function () {
251             evalAndLog("db = request.result");
252             doSecondWrite();
253         };
254     }
256     function doSecondWrite() {
257         evalAndLog("trans = db.transaction('store', 'readwrite')");
258         trans.onabort = unexpectedAbortCallback;
259         evalAndLog("request = trans.objectStore('store').put('value2')");
260         request.onerror = unexpectedErrorCallback;
261         request.onsuccess = function() {
262             shouldBe("request.result", "2");
263         };
264         trans.oncomplete = function() {
265             debug("");
266             finishJSTest();
267         };
268     };
271 test();