diff options
Diffstat (limited to 'packages/idb-bridge/src/idb-wpt-ported')
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; + } +} |