aboutsummaryrefslogtreecommitdiff
path: root/packages/idb-bridge/src/idb-wpt-ported
diff options
context:
space:
mode:
Diffstat (limited to 'packages/idb-bridge/src/idb-wpt-ported')
-rw-r--r--packages/idb-bridge/src/idb-wpt-ported/event-dispatch-active-flag.test.ts57
-rw-r--r--packages/idb-bridge/src/idb-wpt-ported/idbobjectstore-add-put-exception-order.test.ts1
-rw-r--r--packages/idb-bridge/src/idb-wpt-ported/idbtransaction-oncomplete.test.ts49
-rw-r--r--packages/idb-bridge/src/idb-wpt-ported/wptsupport.ts64
4 files changed, 169 insertions, 2 deletions
diff --git a/packages/idb-bridge/src/idb-wpt-ported/event-dispatch-active-flag.test.ts b/packages/idb-bridge/src/idb-wpt-ported/event-dispatch-active-flag.test.ts
new file mode 100644
index 000000000..f5668c90b
--- /dev/null
+++ b/packages/idb-bridge/src/idb-wpt-ported/event-dispatch-active-flag.test.ts
@@ -0,0 +1,57 @@
+import test from "ava";
+import { BridgeIDBRequest } from "..";
+import {
+ createdb,
+ indexeddb_test,
+ is_transaction_active,
+ keep_alive,
+} from "./wptsupport";
+
+test("WPT test abort-in-initial-upgradeneeded.htm", async (t) => {
+ // Transactions are active during success handlers
+ await indexeddb_test(
+ t,
+ (done, db, tx) => {
+ db.createObjectStore("store");
+ },
+ (done, db) => {
+ const tx = db.transaction("store");
+ const release_tx = keep_alive(t, tx, "store");
+
+ t.assert(
+ is_transaction_active(t, tx, "store"),
+ "Transaction should be active after creation",
+ );
+
+ const request = tx.objectStore("store").get(4242);
+ (request as BridgeIDBRequest)._debugName = "req-main";
+ request.onerror = () => t.fail("request should succeed");
+ request.onsuccess = () => {
+
+ t.true(
+ is_transaction_active(t, tx, "store"),
+ "Transaction should be active during success handler",
+ );
+
+ let saw_handler_promise = false;
+ Promise.resolve().then(() => {
+ saw_handler_promise = true;
+ t.true(
+ is_transaction_active(t, tx, "store"),
+ "Transaction should be active in handler's microtasks",
+ );
+ });
+
+ setTimeout(() => {
+ t.true(saw_handler_promise);
+ t.false(
+ is_transaction_active(t, tx, "store"),
+ "Transaction should be inactive in next task",
+ );
+ release_tx();
+ done();
+ }, 0);
+ };
+ },
+ );
+});
diff --git a/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore-add-put-exception-order.test.ts b/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore-add-put-exception-order.test.ts
index 77c4a9391..a3aead9db 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore-add-put-exception-order.test.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore-add-put-exception-order.test.ts
@@ -40,7 +40,6 @@ async function t2(t: ExecutionContext, method: string): Promise<void> {
const store = db.createObjectStore("s");
},
(done, db) => {
- (db as any)._debugName = method;
const tx = db.transaction("s", "readonly");
const store = tx.objectStore("s");
diff --git a/packages/idb-bridge/src/idb-wpt-ported/idbtransaction-oncomplete.test.ts b/packages/idb-bridge/src/idb-wpt-ported/idbtransaction-oncomplete.test.ts
new file mode 100644
index 000000000..8e0b43877
--- /dev/null
+++ b/packages/idb-bridge/src/idb-wpt-ported/idbtransaction-oncomplete.test.ts
@@ -0,0 +1,49 @@
+import test from "ava";
+import { createdb } from "./wptsupport";
+
+// IDBTransaction - complete event
+test("WPT idbtransaction-oncomplete.htm", async (t) => {
+ await new Promise<void>((resolve, reject) => {
+ var db: any;
+ var store: any;
+ let open_rq = createdb(t);
+ let stages: any[] = [];
+
+ open_rq.onupgradeneeded = function (e: any) {
+ stages.push("upgradeneeded");
+
+ db = e.target.result;
+ store = db.createObjectStore("store");
+
+ e.target.transaction.oncomplete = function () {
+ stages.push("complete");
+ };
+ };
+
+ open_rq.onsuccess = function (e) {
+ stages.push("success");
+
+ // Making a totally new transaction to check
+ db
+ .transaction("store")
+ .objectStore("store")
+ .count().onsuccess = function (e: any) {
+ t.deepEqual(stages, ["upgradeneeded", "complete", "success"]);
+ resolve();
+ };
+ // XXX: Make one with real transactions, not only open() versionchange one
+
+ /*db.transaction.objectStore('store').openCursor().onsuccess = function(e) {
+ stages.push("opencursor1");
+ }
+ store.openCursor().onsuccess = function(e) {
+ stages.push("opencursor2");
+ }
+ e.target.transaction.objectStore('store').openCursor().onsuccess = function(e) {
+ stages.push("opencursor3");
+ }
+ */
+ };
+ });
+ 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 6777dc122..9ec46c765 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/wptsupport.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/wptsupport.ts
@@ -1,5 +1,5 @@
import test, { ExecutionContext } from "ava";
-import { BridgeIDBFactory } from "..";
+import { BridgeIDBFactory, BridgeIDBRequest } from "..";
import {
IDBDatabase,
IDBIndex,
@@ -480,3 +480,65 @@ export function indexeddb_test(
}
});
}
+
+/**
+ * Keeps the passed transaction alive indefinitely (by making requests
+ * against the named store). Returns a function that asserts that the
+ * transaction has not already completed and then ends the request loop so that
+ * the transaction may autocommit and complete.
+ */
+export function keep_alive(
+ t: ExecutionContext,
+ tx: IDBTransaction,
+ store_name: string,
+) {
+ let completed = false;
+ tx.addEventListener("complete", () => {
+ completed = true;
+ });
+
+ let keepSpinning = true;
+ let spinCount = 0;
+
+ function spin() {
+ console.log("spinning");
+ if (!keepSpinning) return;
+ const request = tx.objectStore(store_name).get(0);
+ (request as BridgeIDBRequest)._debugName = `req-spin-${spinCount}`;
+ spinCount++;
+ request.onsuccess = spin;
+ }
+ spin();
+
+ return () => {
+ t.log("stopping spin");
+ t.false(completed, "Transaction completed while kept alive");
+ keepSpinning = false;
+ };
+}
+
+// Checks to see if the passed transaction is active (by making
+// requests against the named store).
+export function is_transaction_active(
+ t: ExecutionContext,
+ tx: IDBTransaction,
+ store_name: string,
+) {
+ try {
+ const request = tx.objectStore(store_name).get(0);
+ request.onerror = (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ };
+ return true;
+ } catch (ex) {
+ console.log(ex.stack);
+ t.deepEqual(
+ ex.name,
+ "TransactionInactiveError",
+ "Active check should either not throw anything, or throw " +
+ "TransactionInactiveError",
+ );
+ return false;
+ }
+}