/**
* 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();
}