tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

transaction-deactivation-timing.any.js (5138B)


      1 // META: title=IndexedDB Transaction Deactivation Timing
      2 // META: global=window,worker
      3 // META: script=resources/support.js
      4 
      5 // Spec: https://w3c.github.io/IndexedDB/#dom-idbdatabase-transaction
      6 
      7 'use strict';
      8 
      9 indexeddb_test(
     10    (t, db, tx) => {
     11      db.createObjectStore('store');
     12    },
     13    (t, db) => {
     14      const tx = db.transaction('store', 'readonly');
     15      const release_tx = keep_alive(tx, 'store');
     16      assert_true(
     17          is_transaction_active(tx, 'store'),
     18          'Transaction should be active after creation');
     19 
     20      setTimeout(
     21          t.step_func(() => {
     22            assert_false(
     23                is_transaction_active(tx, 'store'),
     24                'Transaction should be inactive in next task');
     25            release_tx();
     26            t.done();
     27          }),
     28          0);
     29    },
     30    'New transactions are deactivated before next task');
     31 
     32 indexeddb_test(
     33    (t, db, tx) => {
     34      db.createObjectStore('store');
     35    },
     36    (t, db) => {
     37      const tx = db.transaction('store', 'readonly');
     38      const release_tx = keep_alive(tx, 'store');
     39      assert_true(
     40          is_transaction_active(tx, 'store'),
     41          'Transaction should be active after creation');
     42 
     43      Promise.resolve().then(t.step_func(() => {
     44        assert_true(
     45            is_transaction_active(tx, 'store'),
     46            'Transaction should be active in microtask checkpoint');
     47        release_tx();
     48        t.done();
     49      }));
     50    },
     51    'New transactions are not deactivated until after the microtask checkpoint');
     52 
     53 indexeddb_test(
     54    (t, db, tx) => {
     55      db.createObjectStore('store');
     56    },
     57    (t, db) => {
     58      let tx;
     59      let release_tx;
     60 
     61      Promise.resolve().then(t.step_func(() => {
     62        tx = db.transaction('store', 'readonly');
     63        release_tx = keep_alive(tx, 'store');
     64        assert_true(
     65            is_transaction_active(tx, 'store'),
     66            'Transaction should be active after creation');
     67      }));
     68 
     69      setTimeout(
     70          t.step_func(() => {
     71            assert_false(
     72                is_transaction_active(tx, 'store'),
     73                'Transaction should be inactive in next task');
     74            release_tx();
     75            t.done();
     76          }),
     77          0);
     78    },
     79    'New transactions from microtask are deactivated before next task');
     80 
     81 indexeddb_test(
     82    (t, db, tx) => {
     83      db.createObjectStore('store');
     84    },
     85    (t, db) => {
     86      let tx;
     87      let release_tx;
     88 
     89      Promise.resolve().then(t.step_func(() => {
     90        tx = db.transaction('store', 'readonly');
     91        release_tx = keep_alive(tx, 'store');
     92        assert_true(
     93            is_transaction_active(tx, 'store'),
     94            'Transaction should be active after creation');
     95      }));
     96 
     97      Promise.resolve().then(t.step_func(() => {
     98        assert_true(
     99            is_transaction_active(tx, 'store'),
    100            'Transaction should be active in microtask checkpoint');
    101        release_tx();
    102        t.done();
    103      }));
    104    },
    105    'New transactions from microtask are still active through the ' +
    106        'microtask checkpoint');
    107 
    108 
    109 indexeddb_test(
    110    (t, db, tx) => {
    111      db.createObjectStore('store');
    112    },
    113    (t, db) => {
    114      // This transaction serves as the source of an event seen by multiple
    115      // listeners. A DOM event with multiple listeners could be used instead,
    116      // but not via dispatchEvent() because (drumroll...) that happens
    117      // synchronously so microtasks don't run between steps.
    118      const tx = db.transaction('store', 'readonly');
    119      assert_true(
    120          is_transaction_active(tx, 'store'),
    121          'Transaction should be active after creation');
    122 
    123      const request = tx.objectStore('store').get(0);
    124      let new_tx;
    125      let first_listener_ran = false;
    126      let microtasks_ran = false;
    127      request.addEventListener('success', t.step_func(() => {
    128        first_listener_ran = true;
    129        assert_true(
    130            is_transaction_active(tx, 'store'),
    131            'Transaction should be active in callback');
    132 
    133        // We check to see if t transaction is active across unrelated event
    134        // dispatch steps.
    135        new_tx = db.transaction('store', 'readonly');
    136        assert_true(
    137            is_transaction_active(new_tx, 'store'),
    138            'New transaction should be active after creation');
    139 
    140        Promise.resolve().then(t.step_func(() => {
    141          microtasks_ran = true;
    142          assert_true(
    143              is_transaction_active(new_tx, 'store'),
    144              'New transaction is still active in microtask checkpoint');
    145        }));
    146      }));
    147      request.addEventListener('success', t.step_func(() => {
    148        assert_true(first_listener_ran, 'first listener ran first');
    149        assert_true(microtasks_ran, 'microtasks ran before second listener');
    150        assert_true(
    151            is_transaction_active(tx, 'store'),
    152            'Transaction should be active in callback');
    153        assert_false(
    154            is_transaction_active(new_tx, 'store'),
    155            'New transaction should be inactive in unrelated callback');
    156        t.done();
    157      }));
    158    },
    159    'Deactivation of new transactions happens at end of invocation');