summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2021-02-16 13:46:51 +0100
committerFlorian Dold <florian@dold.me>2021-02-16 13:47:01 +0100
commit987f22de02648485ec6f1d3c1558abcfa6d624a0 (patch)
tree5883ed1ae4a2debaff8795acadadf8d4b0e2e5be /packages
parentdb59275b6b43f8fa7f36899ae81cb7139a2e80cb (diff)
downloadwallet-core-987f22de02648485ec6f1d3c1558abcfa6d624a0.tar.gz
wallet-core-987f22de02648485ec6f1d3c1558abcfa6d624a0.tar.bz2
wallet-core-987f22de02648485ec6f1d3c1558abcfa6d624a0.zip
next batch of test cases and fixes
Diffstat (limited to 'packages')
-rw-r--r--packages/idb-bridge/src/MemoryBackend.ts58
-rw-r--r--packages/idb-bridge/src/bridge-idb.ts75
-rw-r--r--packages/idb-bridge/src/idb-wpt-ported/idbindex_get.test.ts177
-rw-r--r--packages/idb-bridge/src/idb-wpt-ported/idbobjectstore_add.test.ts218
-rw-r--r--packages/idb-bridge/src/idb-wpt-ported/wptsupport.ts4
-rw-r--r--packages/idb-bridge/src/util/valueToKey.ts2
6 files changed, 508 insertions, 26 deletions
diff --git a/packages/idb-bridge/src/MemoryBackend.ts b/packages/idb-bridge/src/MemoryBackend.ts
index 9a9527729..7107756a0 100644
--- a/packages/idb-bridge/src/MemoryBackend.ts
+++ b/packages/idb-bridge/src/MemoryBackend.ts
@@ -27,10 +27,7 @@ import {
StoreLevel,
RecordStoreResponse,
} from "./backend-interface";
-import {
- structuredClone,
- structuredRevive,
-} from "./util/structuredClone";
+import { structuredClone, structuredRevive } from "./util/structuredClone";
import {
InvalidStateError,
InvalidAccessError,
@@ -42,11 +39,7 @@ import { compareKeys } from "./util/cmp";
import { StoreKeyResult, makeStoreKeyValue } from "./util/makeStoreKeyValue";
import { getIndexKeys } from "./util/getIndexKeys";
import { openPromise } from "./util/openPromise";
-import {
- IDBKeyRange,
- IDBTransactionMode,
- IDBValidKey,
-} from "./idbtypes";
+import { IDBKeyRange, IDBTransactionMode, IDBValidKey } from "./idbtypes";
import { BridgeIDBKeyRange } from "./bridge-idb";
type Key = IDBValidKey;
@@ -488,10 +481,10 @@ export class MemoryBackend implements Backend {
objectStores: string[],
mode: IDBTransactionMode,
): Promise<DatabaseTransaction> {
+ const transactionCookie = `tx-${this.transactionIdCounter++}`;
if (this.enableTracing) {
- console.log(`TRACING: beginTransaction`);
+ console.log(`TRACING: beginTransaction ${transactionCookie}`);
}
- const transactionCookie = `tx-${this.transactionIdCounter++}`;
const myConn = this.connections[conn.connectionCookie];
if (!myConn) {
throw Error("connection not found");
@@ -556,7 +549,7 @@ export class MemoryBackend implements Backend {
async close(conn: DatabaseConnection): Promise<void> {
if (this.enableTracing) {
- console.log(`TRACING: close`);
+ console.log(`TRACING: close (${conn.connectionCookie})`);
}
const myConn = this.connections[conn.connectionCookie];
if (!myConn) {
@@ -640,7 +633,7 @@ export class MemoryBackend implements Backend {
if (this.enableTracing) {
console.log(`TRACING: deleteIndex(${indexName})`);
}
- const myConn = this.connections[btx.transactionCookie];
+ const myConn = this.connectionsByTransaction[btx.transactionCookie];
if (!myConn) {
throw Error("unknown connection");
}
@@ -670,9 +663,11 @@ export class MemoryBackend implements Backend {
deleteObjectStore(btx: DatabaseTransaction, name: string): void {
if (this.enableTracing) {
- console.log(`TRACING: deleteObjectStore(${name})`);
+ console.log(
+ `TRACING: deleteObjectStore(${name}) in ${btx.transactionCookie}`,
+ );
}
- const myConn = this.connections[btx.transactionCookie];
+ const myConn = this.connectionsByTransaction[btx.transactionCookie];
if (!myConn) {
throw Error("unknown connection");
}
@@ -714,7 +709,7 @@ export class MemoryBackend implements Backend {
console.log(`TRACING: renameObjectStore(?, ${oldName}, ${newName})`);
}
- const myConn = this.connections[btx.transactionCookie];
+ const myConn = this.connectionsByTransaction[btx.transactionCookie];
if (!myConn) {
throw Error("unknown connection");
}
@@ -846,7 +841,15 @@ export class MemoryBackend implements Backend {
objectStoreMapEntry.store.originalData;
storeData.forEach((v, k) => {
- this.insertIntoIndex(newIndex, k, v.value, indexProperties);
+ try {
+ this.insertIntoIndex(newIndex, k, v.value, indexProperties);
+ } catch (e) {
+ if (e instanceof DataError) {
+ // We don't propagate this error here.
+ return;
+ }
+ throw e;
+ }
});
}
@@ -1404,6 +1407,16 @@ export class MemoryBackend implements Backend {
const autoIncrement =
schema.objectStores[storeReq.objectStoreName].autoIncrement;
const keyPath = schema.objectStores[storeReq.objectStoreName].keyPath;
+
+ if (
+ keyPath !== null &&
+ keyPath !== undefined &&
+ storeReq.key !== undefined
+ ) {
+ // If in-line keys are used, a key can't be explicitly specified.
+ throw new DataError();
+ }
+
let storeKeyResult: StoreKeyResult;
const revivedValue = structuredRevive(storeReq.value);
try {
@@ -1463,7 +1476,16 @@ export class MemoryBackend implements Backend {
}
const indexProperties =
schema.objectStores[storeReq.objectStoreName].indexes[indexName];
- this.insertIntoIndex(index, key, value, indexProperties);
+ try {
+ this.insertIntoIndex(index, key, value, indexProperties);
+ } catch (e) {
+ if (e instanceof DataError) {
+ // https://www.w3.org/TR/IndexedDB-2/#object-store-storage-operation
+ // Do nothing
+ } else {
+ throw e;
+ }
+ }
}
return { key };
diff --git a/packages/idb-bridge/src/bridge-idb.ts b/packages/idb-bridge/src/bridge-idb.ts
index f519b9c24..f518b4768 100644
--- a/packages/idb-bridge/src/bridge-idb.ts
+++ b/packages/idb-bridge/src/bridge-idb.ts
@@ -58,6 +58,7 @@ import {
import { fakeDOMStringList } from "./util/fakeDOMStringList";
import FakeEvent from "./util/FakeEvent";
import FakeEventTarget from "./util/FakeEventTarget";
+import { makeStoreKeyValue } from "./util/makeStoreKeyValue";
import { normalizeKeyPath } from "./util/normalizeKeyPath";
import { openPromise } from "./util/openPromise";
import queueTask from "./util/queueTask";
@@ -605,7 +606,17 @@ export class BridgeIDBDatabase extends FakeEventTarget implements IDBDatabase {
throw new TypeError();
}
const transaction = confirmActiveVersionchangeTransaction(this);
- transaction._objectStoresCache.delete(name);
+ const backendTx = transaction._backendTransaction;
+ if (!backendTx) {
+ throw Error("invariant violated");
+ }
+ this._backend.deleteObjectStore(backendTx, name);
+ const os = transaction._objectStoresCache.get(name);
+ if (os) {
+ os._deleted = true;
+ transaction._objectStoresCache.delete(name);
+ }
+
}
public _internalTransaction(
@@ -866,7 +877,9 @@ export class BridgeIDBFactory {
event2.eventPath = [request];
request.dispatchEvent(event2);
} else {
- console.log(`dispatching success event, _active=${transaction._active}`);
+ console.log(
+ `dispatching success event, _active=${transaction._active}`,
+ );
const event2 = new FakeEvent("success", {
bubbles: false,
cancelable: false,
@@ -1064,8 +1077,23 @@ export class BridgeIDBIndex implements IDBIndex {
});
}
- public get(key: BridgeIDBKeyRange | IDBValidKey) {
+
+ private _confirmIndexExists() {
+ const storeSchema = this._schema.objectStores[this._objectStore._name];
+ if (!storeSchema) {
+ throw new InvalidStateError();
+ }
+ if (!storeSchema.indexes[this._name]) {
+ throw new InvalidStateError();
+ }
+ }
+
+ get(key: BridgeIDBKeyRange | IDBValidKey) {
confirmActiveTransaction(this);
+ this._confirmIndexExists();
+ if (this._deleted) {
+ throw new InvalidStateError();
+ }
if (!(key instanceof BridgeIDBKeyRange)) {
key = BridgeIDBKeyRange._valueToKeyRange(key);
@@ -1384,6 +1412,7 @@ export class BridgeIDBObjectStore implements IDBObjectStore {
);
}
+
public _store(value: any, key: IDBValidKey | undefined, overwrite: boolean) {
if (BridgeIDBFactory.enableTracing) {
console.log(`TRACE: IDBObjectStore._store`);
@@ -1391,6 +1420,22 @@ export class BridgeIDBObjectStore implements IDBObjectStore {
if (this._transaction.mode === "readonly") {
throw new ReadOnlyError();
}
+
+ const { keyPath, autoIncrement } = this._schema.objectStores[this._name];
+
+ if (key !== null && key !== undefined) {
+ valueToKey(key);
+ }
+
+ // We only call this to synchronously verify the request.
+ makeStoreKeyValue(
+ value,
+ key,
+ 1,
+ autoIncrement,
+ keyPath,
+ );
+
const operation = async () => {
const { btx } = this._confirmActiveTransaction();
const result = await this._backend.storeRecord(btx, {
@@ -1411,6 +1456,9 @@ export class BridgeIDBObjectStore implements IDBObjectStore {
if (arguments.length === 0) {
throw new TypeError();
}
+ if (this._deleted) {
+ throw new InvalidStateError("tried to call 'put' on a deleted object store");
+ }
return this._store(value, key, true);
}
@@ -1418,6 +1466,9 @@ export class BridgeIDBObjectStore implements IDBObjectStore {
if (arguments.length === 0) {
throw new TypeError();
}
+ if (!this._schema.objectStores[this._name]) {
+ throw new InvalidStateError("object store does not exist");
+ }
return this._store(value, key, false);
}
@@ -1425,7 +1476,9 @@ export class BridgeIDBObjectStore implements IDBObjectStore {
if (arguments.length === 0) {
throw new TypeError();
}
-
+ if (this._deleted) {
+ throw new InvalidStateError("tried to call 'delete' on a deleted object store");
+ }
if (this._transaction.mode === "readonly") {
throw new ReadOnlyError();
}
@@ -1458,6 +1511,10 @@ export class BridgeIDBObjectStore implements IDBObjectStore {
throw new TypeError();
}
+ if (this._deleted) {
+ throw new InvalidStateError("tried to call 'delete' on a deleted object store");
+ }
+
let keyRange: BridgeIDBKeyRange;
if (key instanceof BridgeIDBKeyRange) {
@@ -1541,6 +1598,9 @@ export class BridgeIDBObjectStore implements IDBObjectStore {
range?: IDBKeyRange | IDBValidKey,
direction: IDBCursorDirection = "next",
) {
+ if (this._deleted) {
+ throw new InvalidStateError("tried to call 'openCursor' on a deleted object store");
+ }
if (range === null) {
range = undefined;
}
@@ -1572,6 +1632,9 @@ export class BridgeIDBObjectStore implements IDBObjectStore {
range?: BridgeIDBKeyRange | IDBValidKey,
direction?: IDBCursorDirection,
) {
+ if (this._deleted) {
+ throw new InvalidStateError("tried to call 'openKeyCursor' on a deleted object store");
+ }
if (range === null) {
range = undefined;
}
@@ -2091,7 +2154,9 @@ export class BridgeIDBTransaction
request.dispatchEvent(event);
} catch (err) {
if (BridgeIDBFactory.enableTracing) {
- console.log("TRACING: caught error in transaction success event handler");
+ console.log(
+ "TRACING: caught error in transaction success event handler",
+ );
}
this._abort("AbortError");
this._active = false;
diff --git a/packages/idb-bridge/src/idb-wpt-ported/idbindex_get.test.ts b/packages/idb-bridge/src/idb-wpt-ported/idbindex_get.test.ts
new file mode 100644
index 000000000..8a8cb3129
--- /dev/null
+++ b/packages/idb-bridge/src/idb-wpt-ported/idbindex_get.test.ts
@@ -0,0 +1,177 @@
+import test from "ava";
+import { BridgeIDBKeyRange, BridgeIDBRequest } from "..";
+import { IDBDatabase } from "../idbtypes";
+import { createdb } from "./wptsupport";
+
+// IDBIndex.get() - returns the record
+test("WPT idbindex_get.htm", async (t) => {
+ await new Promise<void>((resolve, reject) => {
+ var db: any, index: any;
+ const record = { key: 1, indexedProperty: "data" };
+
+ var open_rq = createdb(t);
+ open_rq.onupgradeneeded = function (e: any) {
+ db = e.target.result;
+ var objStore = db.createObjectStore("store", { keyPath: "key" });
+ index = objStore.createIndex("index", "indexedProperty");
+
+ objStore.add(record);
+ };
+
+ open_rq.onsuccess = function (e) {
+ var rq = db
+ .transaction("store")
+ .objectStore("store")
+ .index("index")
+ .get(record.indexedProperty);
+
+ rq.onsuccess = function (e: any) {
+ t.deepEqual(e.target.result.key, record.key);
+ resolve();
+ };
+ };
+ });
+ t.pass();
+});
+
+// IDBIndex.get() - returns the record where the index contains duplicate values
+test("WPT idbindex_get2.htm", async (t) => {
+ await new Promise<void>((resolve, reject) => {
+ var db: any;
+ const records = [
+ { key: 1, indexedProperty: "data" },
+ { key: 2, indexedProperty: "data" },
+ { key: 3, indexedProperty: "data" },
+ ];
+
+ var open_rq = createdb(t);
+ open_rq.onupgradeneeded = function (e: any) {
+ db = e.target.result;
+ var objStore = db.createObjectStore("test", { keyPath: "key" });
+ objStore.createIndex("index", "indexedProperty");
+
+ for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+ };
+
+ open_rq.onsuccess = function (e) {
+ var rq = db
+ .transaction("test")
+ .objectStore("test")
+ .index("index")
+ .get("data");
+
+ rq.onsuccess = function (e: any) {
+ t.deepEqual(e.target.result.key, records[0].key);
+ resolve();
+ };
+ };
+ });
+ t.pass();
+});
+
+// IDBIndex.get() - attempt to retrieve a record that doesn't exist
+test("WPT idbindex_get3.htm", async (t) => {
+ await new Promise<void>((resolve, reject) => {
+ var db: any;
+ var open_rq = createdb(t);
+ open_rq.onupgradeneeded = function (e: any) {
+ db = e.target.result;
+ var rq = db
+ .createObjectStore("test", { keyPath: "key" })
+ .createIndex("index", "indexedProperty")
+ .get(1);
+
+ rq.onsuccess = function (e: any) {
+ t.deepEqual(e.target.result, undefined);
+ resolve();
+ };
+ };
+ });
+ t.pass();
+});
+
+// IDBIndex.get() - returns the record with the first key in the range
+test("WPT idbindex_get4.htm", async (t) => {
+ await new Promise<void>((resolve, reject) => {
+ var db: any;
+
+ var open_rq = createdb(t);
+
+ open_rq.onupgradeneeded = function (e: any) {
+ db = e.target.result;
+ var store = db.createObjectStore("store", { keyPath: "key" });
+ store.createIndex("index", "indexedProperty");
+
+ for (var i = 0; i < 10; i++) {
+ store.add({ key: i, indexedProperty: "data" + i });
+ }
+ };
+
+ open_rq.onsuccess = function (e) {
+ var rq = db
+ .transaction("store")
+ .objectStore("store")
+ .index("index")
+ .get(BridgeIDBKeyRange.bound("data4", "data7"));
+
+ rq.onsuccess = function (e: any) {
+ t.deepEqual(e.target.result.key, 4);
+ t.deepEqual(e.target.result.indexedProperty, "data4");
+ setTimeout(function () {
+ resolve();
+ }, 4);
+ };
+ };
+ });
+ t.pass();
+});
+
+// IDBIndex.get() - throw DataError when using invalid key
+test("WPT idbindex_get5.htm", async (t) => {
+ await new Promise<void>((resolve, reject) => {
+ var db: any;
+
+ var open_rq = createdb(t);
+ open_rq.onupgradeneeded = function (e: any) {
+ db = e.target.result;
+
+ var index = db
+ .createObjectStore("test", { keyPath: "key" })
+ .createIndex("index", "indexedProperty");
+ t.throws(
+ function () {
+ index.get(NaN);
+ },
+ { name: "DataError" },
+ );
+ resolve();
+ };
+ });
+ t.pass();
+});
+
+// IDBIndex.get() - throw InvalidStateError when the index is deleted
+test("WPT idbindex_get6.htm", async (t) => {
+ await new Promise<void>((resolve, reject) => {
+ var db: any;
+
+ var open_rq = createdb(t);
+ open_rq.onupgradeneeded = function (e: any) {
+ db = e.target.result;
+ var store = db.createObjectStore("store", { keyPath: "key" });
+ var index = store.createIndex("index", "indexedProperty");
+
+ store.add({ key: 1, indexedProperty: "data" });
+ store.deleteIndex("index");
+
+ t.throws(
+ function () {
+ index.get("data");
+ },
+ { name: "InvalidStateError" },
+ );
+ resolve();
+ };
+ });
+ t.pass();
+});
diff --git a/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore_add.test.ts b/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore_add.test.ts
index b0c1de2d7..b8fdb5ac3 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore_add.test.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore_add.test.ts
@@ -1,4 +1,5 @@
import test from "ava";
+import { BridgeIDBRequest } from "..";
import { IDBDatabase } from "../idbtypes";
import { createdb } from "./wptsupport";
@@ -228,7 +229,8 @@ test("WPT idbobjectstore_add7.htm", async (t) => {
t.pass();
});
-// IDBObjectStore.add() - object store has autoIncrement:true and the key path is an object attribute
+// IDBObjectStore.add() - object store has autoIncrement:true and the key path
+// is an object attribute
test("WPT idbobjectstore_add8.htm", async (t) => {
await new Promise<void>((resolve, reject) => {
var db: any;
@@ -268,3 +270,217 @@ test("WPT idbobjectstore_add8.htm", async (t) => {
});
t.pass();
});
+
+// IDBObjectStore.add() - Attempt to add a record that does not meet the
+// constraints of an object store's inline key requirements
+test("WPT idbobjectstore_add9.htm", async (t) => {
+ await new Promise<void>((resolve, reject) => {
+ const record = { key: 1, property: "data" };
+
+ var open_rq = createdb(t);
+ open_rq.onupgradeneeded = function (e: any) {
+ var rq,
+ db = e.target.result,
+ objStore = db.createObjectStore("store", { keyPath: "key" });
+
+ t.throws(
+ function () {
+ rq = objStore.add(record, 1);
+ },
+ { name: "DataError" },
+ );
+ t.deepEqual(rq, undefined);
+ resolve();
+ };
+ });
+ t.pass();
+});
+
+// IDBObjectStore.add() - Attempt to call 'add' without an key parameter when the
+// object store uses out-of-line keys.
+test("WPT idbobjectstore_add10.htm", async (t) => {
+ await new Promise<void>((resolve, reject) => {
+ var db: any;
+ const record = { property: "data" };
+
+ var open_rq = createdb(t);
+ open_rq.onupgradeneeded = function (e: any) {
+ db = e.target.result;
+
+ var rq,
+ objStore = db.createObjectStore("store");
+
+ t.throws(
+ function () {
+ rq = objStore.add(record);
+ },
+ { name: "DataError" },
+ );
+
+ t.deepEqual(rq, undefined);
+ resolve();
+ };
+ });
+ t.pass();
+});
+
+// IDBObjectStore.add() - Attempt to add a record where the record's key
+// does not meet the constraints of a valid key
+test("WPT idbobjectstore_add11.htm", async (t) => {
+ await new Promise<void>((resolve, reject) => {
+ var db: any;
+ const record = { key: { value: 1 }, property: "data" };
+
+ var open_rq = createdb(t);
+ open_rq.onupgradeneeded = function (e: any) {
+ db = e.target.result;
+
+ var rq,
+ objStore = db.createObjectStore("store", { keyPath: "key" });
+
+ t.throws(
+ function () {
+ rq = objStore.add(record);
+ },
+ { name: "DataError" },
+ );
+
+ t.deepEqual(rq, undefined);
+ resolve();
+ };
+ });
+ t.pass();
+});
+
+// IDBObjectStore.add() - Attempt to add a record where the
+// record's in-line key is not defined
+test("WPT idbobjectstore_add12.htm", async (t) => {
+ await new Promise<void>((resolve, reject) => {
+ var db: any;
+ const record = { property: "data" };
+
+ var open_rq = createdb(t);
+ open_rq.onupgradeneeded = function (e: any) {
+ db = e.target.result;
+
+ var rq,
+ objStore = db.createObjectStore("store", { keyPath: "key" });
+ t.throws(
+ function () {
+ rq = objStore.add(record);
+ },
+ { name: "DataError" },
+ );
+ t.deepEqual(rq, undefined);
+ resolve();
+ };
+ });
+ t.pass();
+});
+
+// IDBObjectStore.add() - Attempt to add a record where the out of line
+// key provided does not meet the constraints of a valid key
+test("WPT idbobjectstore_add13.htm", async (t) => {
+ await new Promise<void>((resolve, reject) => {
+ var db: any;
+ const record = { property: "data" };
+
+ var open_rq = createdb(t);
+ open_rq.onupgradeneeded = function (e: any) {
+ db = e.target.result;
+
+ var rq,
+ objStore = db.createObjectStore("store");
+
+ t.throws(
+ function () {
+ rq = objStore.add(record, { value: 1 });
+ },
+ { name: "DataError" },
+ );
+
+ t.deepEqual(rq, undefined);
+ resolve();
+ };
+ });
+ t.pass();
+});
+
+// IDBObjectStore.add() - Add a record where a value
+// being indexed does not meet the constraints of a valid key
+test("WPT idbobjectstore_add14.htm", async (t) => {
+ await new Promise<void>((resolve, reject) => {
+ var db: any;
+ const record = { key: 1, indexedProperty: { property: "data" } };
+
+ var open_rq = createdb(t);
+ open_rq.onupgradeneeded = function (e: any) {
+ db = e.target.result;
+
+ var rq,
+ objStore = db.createObjectStore("store", { keyPath: "key" });
+
+ objStore.createIndex("index", "indexedProperty");
+
+ rq = objStore.add(record);
+
+ t.assert(rq instanceof BridgeIDBRequest);
+ rq.onsuccess = function () {
+ resolve();
+ };
+ };
+ });
+ t.pass();
+});
+
+// IDBObjectStore.add() - If the transaction this IDBObjectStore belongs
+// to has its mode set to readonly, throw ReadOnlyError
+test("WPT idbobjectstore_add15.htm", async (t) => {
+ await new Promise<void>((resolve, reject) => {
+ var db: any;
+
+ var open_rq = createdb(t);
+ open_rq.onupgradeneeded = function (event: any) {
+ db = event.target.result;
+ db.createObjectStore("store", { keyPath: "pKey" });
+ };
+
+ open_rq.onsuccess = function (event) {
+ var txn = db.transaction("store");
+ var ostore = txn.objectStore("store");
+ t.throws(
+ function () {
+ ostore.add({ pKey: "primaryKey_0" });
+ },
+ { name: "ReadOnlyError" },
+ );
+ resolve();
+ };
+ });
+ t.pass();
+});
+
+// IDBObjectStore.add() - If the object store has been
+// deleted, the implementation must throw a DOMException of type InvalidStateError
+test("WPT idbobjectstore_add16.htm", async (t) => {
+ await new Promise<void>((resolve, reject) => {
+ var db: any;
+ let ostore: any;
+
+ var open_rq = createdb(t);
+ open_rq.onupgradeneeded = function (event: any) {
+ db = event.target.result;
+ ostore = db.createObjectStore("store", { keyPath: "pKey" });
+ db.deleteObjectStore("store");
+
+ t.throws(
+ function () {
+ ostore.add({ pKey: "primaryKey_0" });
+ },
+ { name: "InvalidStateError" },
+ );
+ resolve();
+ };
+ });
+ t.pass();
+});
diff --git a/packages/idb-bridge/src/idb-wpt-ported/wptsupport.ts b/packages/idb-bridge/src/idb-wpt-ported/wptsupport.ts
index 92e78a685..5716a7ae5 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/wptsupport.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/wptsupport.ts
@@ -5,7 +5,9 @@ import { MemoryBackend } from "../MemoryBackend";
import { compareKeys } from "../util/cmp";
BridgeIDBFactory.enableTracing = true;
-const idbFactory = new BridgeIDBFactory(new MemoryBackend());
+const backend = new MemoryBackend();
+backend.enableTracing = true;
+const idbFactory = new BridgeIDBFactory(backend);
const self = {
indexedDB: idbFactory,
diff --git a/packages/idb-bridge/src/util/valueToKey.ts b/packages/idb-bridge/src/util/valueToKey.ts
index cfef779fe..c65604df1 100644
--- a/packages/idb-bridge/src/util/valueToKey.ts
+++ b/packages/idb-bridge/src/util/valueToKey.ts
@@ -17,7 +17,7 @@
import { IDBValidKey } from "..";
import { DataError } from "./errors";
-// https://w3c.github.io/IndexedDB/#convert-a-value-to-a-input
+// https://www.w3.org/TR/IndexedDB-2/#convert-a-value-to-a-key
export function valueToKey(
input: any,
seen?: Set<object>,