/** * Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ /* exported testGenerator */ 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; for (let autoincrement of [true, false]) { for (let keypath of [false, true, "missing", "invalid"]) { for (let method of ["put", "add"]) { for (let explicit of [true, false, undefined, "invalid"]) { for (let existing of [true, false]) { let speccedNoKey = (!keypath || 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, }); let test = " for test " + JSON.stringify({ autoincrement, keypath, method, explicit: explicit === undefined ? "undefined" : explicit, 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 let 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(); }