/** * Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ var testGenerator = testSteps(); function testSteps() { const name = this.window ? window.location.pathname : "Splendid Test"; let openRequest = indexedDB.open(name, 1); openRequest.onerror = errorHandler; openRequest.onupgradeneeded = grabEventAndContinueHandler; openRequest.onsuccess = unexpectedSuccessHandler; let event = yield undefined; let db = event.target.result; let trans = event.target.transaction; for each (let autoincrement in [true, false]) { for each (let keypath in [false, true, "missing", "invalid"]) { for each (let method in ["put", "add"]) { for each (let explicit in [true, false, undefined, "invalid"]) { for each (let existing in [true, false]) { let speccedNoKey = (keypath == false || keypath == "missing") && !explicit; // We can't do 'existing' checks if we use autogenerated key if (speccedNoKey && autoincrement && existing) { continue; } // Create store if (db.objectStoreNames.contains("mystore")) db.deleteObjectStore("mystore"); let store = db.createObjectStore("mystore", { autoIncrement: autoincrement, keyPath: (keypath ? "id" : null) }); test = " for test " + JSON.stringify({ autoincrement: autoincrement, keypath: keypath, method: method, explicit: explicit === undefined ? "undefined" : explicit, existing: existing }); // Insert "existing" data if needed if (existing) { if (keypath) store.add({ existing: "data", id: 5 }).onsuccess = grabEventAndContinueHandler; else store.add({ existing: "data" }, 5).onsuccess = grabEventAndContinueHandler; let e = yield undefined; is(e.type, "success", "success inserting existing" + test); is(e.target.result, 5, "inserted correct key" + test); } // Set up value to be inserted let value = { theObj: true }; if (keypath === true) { value.id = 5; } else if (keypath === "invalid") { value.id = /x/; } // Which arguments are passed to function args = [value]; if (explicit === true) { args.push(5); } else if (explicit === undefined) { args.push(undefined); } else if (explicit === "invalid") { args.push(/x/); } let expected = expectedResult(method, keypath, explicit, autoincrement, existing); let valueJSON = JSON.stringify(value); ok(true, "making call" + test); // Make function call for throwing functions if (expected === "throw") { try { store[method].apply(store, args); ok(false, "should have thrown" + test); } catch (ex) { ok(true, "did throw" + test); ok(ex instanceof DOMException, "Got a DOMException" + test); is(ex.name, "DataError", "expect a DataError" + test); is(ex.code, 0, "expect zero" + test); is(JSON.stringify(value), valueJSON, "call didn't modify value" + test); } continue; } // Make non-throwing function call let req = store[method].apply(store, args); is(JSON.stringify(value), valueJSON, "call didn't modify value" + test); req.onsuccess = req.onerror = grabEventAndContinueHandler; let e = yield undefined; // Figure out what key we used let key = 5; if (autoincrement && speccedNoKey) { key = 1; } // Adjust value if expected if (autoincrement && keypath && speccedNoKey) { value.id = key; } // Check result if (expected === "error") { is(e.type, "error", "write should fail" + test); e.preventDefault(); e.stopPropagation(); continue; } is(e.type, "success", "write should succeed" + test); is(e.target.result, key, "write should return correct key" + test); store.get(key).onsuccess = grabEventAndContinueHandler; e = yield undefined; is(e.type, "success", "read back should succeed" + test); is(JSON.stringify(e.target.result), JSON.stringify(value), "read back should return correct value" + test); } } } } } function expectedResult(method, keypath, explicit, autoincrement, existing) { if (keypath && explicit) return "throw"; if (!keypath && !explicit && !autoincrement) return "throw"; if (keypath == "invalid") return "throw"; if (keypath == "missing" && !autoincrement) return "throw"; if (explicit == "invalid") return "throw"; if (method == "add" && existing) return "error"; return "success"; } openRequest.onsuccess = grabEventAndContinueHandler; yield undefined; finishTest(); yield undefined; }