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