| Index: LayoutTests/storage/indexeddb/microtasks.html
|
| diff --git a/LayoutTests/storage/indexeddb/microtasks.html b/LayoutTests/storage/indexeddb/microtasks.html
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..42954d850c42c45e6f03bc9c08758c616349d216
|
| --- /dev/null
|
| +++ b/LayoutTests/storage/indexeddb/microtasks.html
|
| @@ -0,0 +1,108 @@
|
| +<!DOCTYPE html>
|
| +<title>IndexedDB: Verify transaction activation behavior around microtasks</title>
|
| +<script src="../../resources/testharness.js"></script>
|
| +<script src="../../resources/testharnessreport.js"></script>
|
| +<script>
|
| +
|
| +function idb_test(description, onUpgrade, onOpen) {
|
| + var t = async_test(description);
|
| + t.step(function() {
|
| + var dbName = 'db' + location.pathname + '-' + description;
|
| + var deleteRequest = indexedDB.deleteDatabase(dbName);
|
| + deleteRequest.onerror = t.unreached_func('deleteDatabase should not fail');
|
| + deleteRequest.onsuccess = t.step_func(function(e) {
|
| + var openRequest = indexedDB.open(dbName);
|
| + openRequest.onerror = t.unreached_func('open should not fail');
|
| + openRequest.onupgradeneeded = t.step_func(function(e) {
|
| + onUpgrade(t, openRequest.result);
|
| + });
|
| + openRequest.onsuccess = t.step_func(function(e) {
|
| + onOpen(t, openRequest.result);
|
| + });
|
| + });
|
| + });
|
| +}
|
| +
|
| +function isTransactionActive(tx, storeName) {
|
| + try {
|
| + tx.objectStore(storeName).get(0);
|
| + return true;
|
| + } catch (ex) {
|
| + assert_equals(ex.name, 'TransactionInactiveError',
|
| + 'Failure should be due to inactive transaction');
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +idb_test(
|
| + 'Transactions created in microtasks are deactivated when control returns to the event loop',
|
| + 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(function() {
|
| + assert_false(isTransactionActive(tx, 'store'),
|
| + 'Transaction should be inactive once control returns to event loop');
|
| + t.done();
|
| + }, 0);
|
| + });
|
| + }));
|
| + }
|
| +);
|
| +
|
| +idb_test(
|
| + 'Transactions created in microtasks remain active in subsequent microtasks',
|
| + 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(function() {
|
| + assert_false(isTransactionActive(tx, 'store'),
|
| + 'Transaction should be inactive once control returns to event loop');
|
| + t.done();
|
| + }, 0);
|
| + }));
|
| + }
|
| +);
|
| +
|
| +idb_test(
|
| + 'Within request event dispatch, transactions remain active across microtasks',
|
| + 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(function() {
|
| + assert_false(isTransactionActive(tx, 'store'),
|
| + 'Transaction should be inactive once control returns to the event loop');
|
| + t.done();
|
| + }, 0);
|
| + }));
|
| + });
|
| + }
|
| +);
|
| +
|
| +</script>
|
|
|