| <!DOCTYPE html> | |
| <meta charset=utf-8> | |
| <title>Transaction active flag is set during event dispatch</title> | |
| <link rel="help" href="https://w3c.github.io/IndexedDB/#fire-success-event"> | |
| <link rel="help" href="https://w3c.github.io/IndexedDB/#fire-error-event"> | |
| <script src=/resources/testharness.js></script> | |
| <script src=/resources/testharnessreport.js></script> | |
| <script src=support.js></script> | |
| <script> | |
| indexeddb_test( | |
| (t, db, tx) => { | |
| db.createObjectStore('store'); | |
| }, | |
| (t, db) => { | |
| const tx = db.transaction('store'); | |
| const release_tx = keep_alive(tx, 'store'); | |
| assert_true(is_transaction_active(tx, 'store'), | |
| 'Transaction should be active after creation'); | |
| const request = tx.objectStore('store').get(0); | |
| request.onerror = t.unreached_func('request should succeed'); | |
| request.onsuccess = () => { | |
| assert_true(is_transaction_active(tx, 'store'), | |
| 'Transaction should be active during success handler'); | |
| let saw_handler_promise = false; | |
| Promise.resolve().then(t.step_func(() => { | |
| saw_handler_promise = true; | |
| assert_true(is_transaction_active(tx, 'store'), | |
| 'Transaction should be active in handler\'s microtasks'); | |
| })); | |
| setTimeout(t.step_func(() => { | |
| assert_true(saw_handler_promise); | |
| assert_false(is_transaction_active(tx, 'store'), | |
| 'Transaction should be inactive in next task'); | |
| release_tx(); | |
| t.done(); | |
| }), 0); | |
| }; | |
| }, | |
| 'Transactions are active during success handlers'); | |
| indexeddb_test( | |
| (t, db, tx) => { | |
| db.createObjectStore('store'); | |
| }, | |
| (t, db) => { | |
| const tx = db.transaction('store'); | |
| const release_tx = keep_alive(tx, 'store'); | |
| assert_true(is_transaction_active(tx, 'store'), | |
| 'Transaction should be active after creation'); | |
| const request = tx.objectStore('store').get(0); | |
| request.onerror = t.unreached_func('request should succeed'); | |
| request.addEventListener('success', () => { | |
| assert_true(is_transaction_active(tx, 'store'), | |
| 'Transaction should be active during success listener'); | |
| let saw_listener_promise = false; | |
| Promise.resolve().then(t.step_func(() => { | |
| saw_listener_promise = true; | |
| assert_true(is_transaction_active(tx, 'store'), | |
| 'Transaction should be active in listener\'s microtasks'); | |
| })); | |
| setTimeout(t.step_func(() => { | |
| assert_true(saw_listener_promise); | |
| assert_false(is_transaction_active(tx, 'store'), | |
| 'Transaction should be inactive in next task'); | |
| release_tx(); | |
| t.done(); | |
| }), 0); | |
| }); | |
| }, | |
| 'Transactions are active during success listeners'); | |
| indexeddb_test( | |
| (t, db, tx) => { | |
| db.createObjectStore('store'); | |
| }, | |
| (t, db) => { | |
| const tx = db.transaction('store', 'readwrite'); | |
| const release_tx = keep_alive(tx, 'store'); | |
| assert_true(is_transaction_active(tx, 'store'), | |
| 'Transaction should be active after creation'); | |
| tx.objectStore('store').put(0, 0); | |
| const request = tx.objectStore('store').add(0, 0); | |
| request.onsuccess = t.unreached_func('request should fail'); | |
| request.onerror = e => { | |
| e.preventDefault(); | |
| assert_true(is_transaction_active(tx, 'store'), | |
| 'Transaction should be active during error handler'); | |
| let saw_handler_promise = false; | |
| Promise.resolve().then(t.step_func(() => { | |
| saw_handler_promise = true; | |
| assert_true(is_transaction_active(tx, 'store'), | |
| 'Transaction should be active in handler\'s microtasks'); | |
| })); | |
| setTimeout(t.step_func(() => { | |
| assert_true(saw_handler_promise); | |
| assert_false(is_transaction_active(tx, 'store'), | |
| 'Transaction should be inactive in next task'); | |
| release_tx(); | |
| t.done(); | |
| }), 0); | |
| }; | |
| }, | |
| 'Transactions are active during error handlers'); | |
| indexeddb_test( | |
| (t, db, tx) => { | |
| db.createObjectStore('store'); | |
| }, | |
| (t, db) => { | |
| const tx = db.transaction('store', 'readwrite'); | |
| const release_tx = keep_alive(tx, 'store'); | |
| assert_true(is_transaction_active(tx, 'store'), | |
| 'Transaction should be active after creation'); | |
| tx.objectStore('store').put(0, 0); | |
| const request = tx.objectStore('store').add(0, 0); | |
| request.onsuccess = t.unreached_func('request should fail'); | |
| request.addEventListener('error', e => { | |
| e.preventDefault(); | |
| assert_true(is_transaction_active(tx, 'store'), | |
| 'Transaction should be active during error listener'); | |
| let saw_listener_promise = false; | |
| Promise.resolve().then(t.step_func(() => { | |
| saw_listener_promise = true; | |
| assert_true(is_transaction_active(tx, 'store'), | |
| 'Transaction should be active in listener\'s microtasks'); | |
| })); | |
| setTimeout(t.step_func(() => { | |
| assert_true(saw_listener_promise); | |
| assert_false(is_transaction_active(tx, 'store'), | |
| 'Transaction should be inactive in next task'); | |
| release_tx(); | |
| t.done(); | |
| }), 0); | |
| }); | |
| }, | |
| 'Transactions are active during error listeners'); | |
| </script> |