2 * Any copyright is dedicated to the Public Domain.
3 * http://creativecommons.org/publicdomain/zero/1.0/
6 /* exported testGenerator */
7 var testGenerator = testSteps();
9 // helper function that ensures that ArrayBuffer instances are meaningfully
10 // displayed (not just as 'object ArrayBuffer')
11 // TODO better move to helpers.js?
12 function showKey(key) {
13 if (key instanceof Array) {
14 return key.map(x => showKey(x)).toString();
16 if (key instanceof ArrayBuffer) {
17 return "ArrayBuffer([" + new Uint8Array(key).toString() + "])";
19 return key.toString();
22 function* testSteps() {
23 const dbname = this.window ? window.location.pathname : "Splendid Test";
25 let openRequest = indexedDB.open(dbname, 1);
26 openRequest.onerror = errorHandler;
27 openRequest.onupgradeneeded = grabEventAndContinueHandler;
28 openRequest.onsuccess = unexpectedSuccessHandler;
29 let event = yield undefined;
30 let db = event.target.result;
33 let store = db.createObjectStore("store");
34 let enc = new TextEncoder();
36 // Test simple inserts
37 // Note: the keys must be in order
55 new Date("1750-01-02"),
56 new Date("1800-12-31T12:34:56.001"),
64 new Date("1971-01-01"),
65 new Date("1971-01-01T01:01:01Z"),
66 new Date("1971-01-01T01:01:01.001Z"),
67 new Date("1971-01-01T01:01:01.01Z"),
68 new Date("1971-01-01T01:01:01.1Z"),
69 new Date("1980-02-02"),
70 new Date("3333-03-19T03:33:33.333"),
126 // Note: enc.encode returns an Uint8Array, which is a valid key, but when
127 // converting it back and forth, the result will be a plain ArrayBuffer,
128 // which is expected in comparisons below
129 // TODO is it ok that the information that the original key was an
130 // Uint8Array is lost?
132 Uint8Array.from([0]).buffer,
133 Uint8Array.from([0, 0]).buffer,
134 Uint8Array.from([0, 1]).buffer,
135 Uint8Array.from([0, 1, 0]).buffer,
136 enc.encode("abc").buffer,
137 enc.encode("abcd").buffer,
138 enc.encode("xyz").buffer,
139 Uint8Array.from([0x80]).buffer,
149 [2, 3.0000000000001],
164 ["abc\x00", "\x00\x01"],
165 ["abc\x00", "\x00def"],
169 // see comment on scalar ArrayBuffers above
170 [new ArrayBuffer(0)],
171 [new ArrayBuffer(0), "abc"],
172 [new ArrayBuffer(0), new ArrayBuffer(0)],
173 [new ArrayBuffer(0), enc.encode("abc").buffer],
174 [enc.encode("abc").buffer],
175 [enc.encode("abc").buffer, new ArrayBuffer(0)],
176 [enc.encode("abc").buffer, enc.encode("xyz").buffer],
177 [enc.encode("xyz").buffer],
190 for (var i = 0; i < keys.length; ++i) {
192 is(indexedDB.cmp(keyI, keyI), 0, i + " compared to self");
194 function doCompare(keyI) {
195 for (var j = i - 1; j >= i - 10 && j >= 0; --j) {
196 is(indexedDB.cmp(keyI, keys[j]), 1, i + " compared to " + j);
197 is(indexedDB.cmp(keys[j], keyI), -1, j + " compared to " + i);
202 store.add(i, keyI).onsuccess = function(e) {
204 indexedDB.cmp(e.target.result, keyI),
206 "Returned key should cmp as equal; index = " +
211 showKey(e.target.result)
214 compareKeys(e.target.result, keyI),
215 "Returned key should actually be equal; index = " +
220 showKey(e.target.result)
224 // Test that -0 compares the same as 0
227 let req = store.add(i, -0);
228 req.addEventListener("error", new ExpectError("ConstraintError", true));
229 req.onsuccess = unexpectedSuccessHandler;
231 } else if (Array.isArray(keyI) && keyI.length === 1 && keyI[0] === 0) {
233 let req = store.add(i, [-0]);
234 req.addEventListener("error", new ExpectError("ConstraintError", true));
235 req.onsuccess = unexpectedSuccessHandler;
240 store.openCursor().onsuccess = grabEventAndContinueHandler;
241 for (i = 0; i < keys.length; ++i) {
242 event = yield undefined;
243 let cursor = event.target.result;
245 indexedDB.cmp(cursor.key, keys[i]),
247 "Read back key should cmp as equal; index = " +
255 compareKeys(cursor.key, keys[i]),
256 "Read back key should actually be equal; index = " +
263 is(cursor.value, i, "Stored with right value");
267 event = yield undefined;
268 is(event.target.result, null, "no more results expected");
270 // Note that nan is defined below as '0 / 0'.
295 // ATTENTION, the following key allocates 2GB of memory and might cause
296 // subtle failures in some environments, see bug 1796753. We might
297 // want to have some common way between IndexeDB mochitests and
298 // xpcshell tests how to access AppConstants in order to dynamically
299 // exclude this key from some environments, rather than disabling the
300 // entire xpcshell variant of this test for ASAN/TSAN.
301 "new Uint8Array(2147483647)",
304 function checkInvalidKeyException(ex, i, callText) {
305 let suffix = ` during ${callText} with invalid key ${i}: ${invalidKeys[i]}`;
306 // isInstance() is not available in mochitest, and we use this JS also as mochitest.
307 // eslint-disable-next-line mozilla/use-isInstance
308 ok(ex instanceof DOMException, "Threw DOMException" + suffix);
309 is(ex.name, "DataError", "Threw right DOMException" + suffix);
310 is(ex.code, 0, "Threw with right code" + suffix);
313 for (i = 0; i < invalidKeys.length; ++i) {
314 let key_fn = Function(
315 `"use strict"; var nan = 0 / 0; let k = (${invalidKeys[i]}); return k;`
321 // If we cannot instantiate the key, we are most likely on a 32 Bit
322 // platform with insufficient memory. Just skip it.
323 info("Key instantiation failed, skipping");
327 indexedDB.cmp(key, 1);
328 ok(false, "didn't throw");
330 checkInvalidKeyException(ex, i, "cmp(key, 1)");
333 indexedDB.cmp(1, key);
334 ok(false, "didn't throw2");
336 checkInvalidKeyException(ex, i, "cmp(1, key)");
340 ok(false, "didn't throw3");
342 checkInvalidKeyException(ex, i, "store.put(1, key)");
346 openRequest.onsuccess = grabEventAndContinueHandler;