| <!DOCTYPE html> |
| <title>IndexedDB: Verify transaction activation behavior around microtasks</title> |
| <script src="../../resources/testharness.js"></script> |
| <script src="../../resources/testharnessreport.js"></script> |
| <script src="resources/testharness-helpers.js"></script> |
| <script> |
| |
| function isTransactionActive(tx, storeName) { |
| try { |
| tx.objectStore(storeName).get(0); |
| return true; |
| } catch (ex) { |
| // The exception could be TransactionInactiveError or InvalidStateError |
| // depending on the test and whether the transaction has committed yet. |
| return false; |
| } |
| } |
| |
| indexeddb_test( |
| function(t, db) { |
| db.createObjectStore('store'); |
| }, |
| function(t, db) { |
| Promise.resolve().then(t.step_func(function() { |
| var tx = db.transaction('store'); |
| var request = tx.objectStore('store').get(0); |
| request.onerror = t.unreached_func('request should not fail'); |
| request.onsuccess = t.step_func(function() { |
| assert_true(isTransactionActive(tx, 'store'), |
| 'Transaction should be active during event dispatch'); |
| setTimeout(t.step_func(function() { |
| assert_false(isTransactionActive(tx, 'store'), |
| 'Transaction should be inactive once control returns to event loop'); |
| t.done(); |
| }), 0); |
| }); |
| })); |
| }, |
| 'Transactions created in microtasks are deactivated when control returns to the event loop' |
| ); |
| |
| indexeddb_test( |
| function(t, db) { |
| db.createObjectStore('store'); |
| }, |
| function(t, db) { |
| var aesAlgorithmKeyGen = {name: "AES-CBC", length: 128}; |
| crypto.subtle.generateKey(aesAlgorithmKeyGen, false, ["encrypt"]).then(t.step_func(function() { |
| var tx = db.transaction('store'); |
| var request = tx.objectStore('store').get(0); |
| request.onerror = t.unreached_func('request should not fail'); |
| request.onsuccess = t.step_func(function() { |
| assert_true(isTransactionActive(tx, 'store'), |
| 'Transaction should be active during event dispatch'); |
| setTimeout(t.step_func(function() { |
| assert_false(isTransactionActive(tx, 'store'), |
| 'Transaction should be inactive once control returns to event loop'); |
| t.done(); |
| }), 0); |
| }); |
| })); |
| }, |
| 'Transactions created in microtasks resolved by host behavior are deactivated when control returns to the event loop' |
| ); |
| |
| indexeddb_test( |
| function(t, db) { |
| db.createObjectStore('store'); |
| }, |
| function(t, db) { |
| var tx; |
| Promise.resolve().then(function() { |
| tx = db.transaction('store'); |
| assert_true(isTransactionActive(tx, 'store'), |
| 'Transaction should be active when created'); |
| }).then(t.step_func(function() { |
| assert_true(isTransactionActive(tx, 'store'), |
| 'Transaction should be active until control returns to event loop'); |
| setTimeout(t.step_func(function() { |
| assert_false(isTransactionActive(tx, 'store'), |
| 'Transaction should be inactive once control returns to event loop'); |
| t.done(); |
| }), 0); |
| })); |
| }, |
| 'Transactions created in microtasks remain active in subsequent microtasks' |
| ); |
| |
| indexeddb_test( |
| function(t, db) { |
| db.createObjectStore('store'); |
| }, |
| function(t, db) { |
| var tx = db.transaction('store'); |
| var request = tx.objectStore('store').get(0); |
| request.onerror = t.unreached_func('request should not fail'); |
| request.onsuccess = t.step_func(function() { |
| assert_true(isTransactionActive(tx, 'store'), |
| 'Transaction should be active during event dispatch'); |
| Promise.resolve().then(t.step_func(function() { |
| assert_true(isTransactionActive(tx, 'store'), |
| 'Microtasks are run as part of event dispatch, so transaction should still be active'); |
| setTimeout(t.step_func(function() { |
| assert_false(isTransactionActive(tx, 'store'), |
| 'Transaction should be inactive once control returns to the event loop'); |
| t.done(); |
| }), 0); |
| })); |
| }); |
| }, |
| 'Within request event dispatch, transactions remain active across microtasks' |
| ); |
| |
| </script> |