tor-browser

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

async-disposable-stack-use-dispose.js (4795B)


      1 // |jit-test| skip-if: !getBuildConfiguration("explicit-resource-management"); --enable-explicit-resource-management
      2 
      3 load(libdir + "asserts.js");
      4 
      5 {
      6  const disposed = [];
      7  const stack = new AsyncDisposableStack();
      8  async function testDisposalsWithAsyncDisposableStack() {
      9    const obj = {
     10      [Symbol.asyncDispose]() {
     11        disposed.push(1);
     12      },
     13    };
     14    stack.use(obj);
     15    assertEq(stack.disposed, false);
     16    assertEq(await stack.disposeAsync(), undefined);
     17  }
     18  testDisposalsWithAsyncDisposableStack();
     19  drainJobQueue();
     20  assertEq(stack.disposed, true);
     21  assertArrayEq(disposed, [1]);
     22 
     23  // `use` should throw if the stack is already disposed.
     24  assertThrowsInstanceOf(() => stack.use({ [Symbol.asyncDispose]: () => {} }), ReferenceError);
     25 }
     26 
     27 {
     28  const disposed = [];
     29  const stack = new AsyncDisposableStack();
     30  async function testAsyncDisposableStackMultipleDispose() {
     31    for (let i = 0; i < 5; i++) {
     32      stack.use({
     33        [Symbol.dispose]() {
     34          disposed.push(i);
     35        },
     36      });
     37    }
     38    assertEq(stack.disposed, false);
     39    await stack.disposeAsync();
     40 
     41    // Calling again shouldn't do anything.
     42    await stack.disposeAsync();
     43  }
     44  testAsyncDisposableStackMultipleDispose();
     45  drainJobQueue();
     46  assertEq(stack.disposed, true);
     47  assertArrayEq(disposed, [4, 3, 2, 1, 0]);
     48 }
     49 
     50 {
     51  const disposed = [];
     52  const stack = new AsyncDisposableStack();
     53  async function testAsyncDisposableStackUseWithFallback() {
     54    stack.use({
     55      [Symbol.asyncDispose]() {
     56        disposed.push(1);
     57      }
     58    });
     59    stack.use({
     60      [Symbol.dispose]() {
     61        disposed.push(2);
     62      }
     63    });
     64    stack.use({
     65      [Symbol.asyncDispose]: undefined,
     66      [Symbol.dispose]() {
     67        disposed.push(3);
     68      }
     69    });
     70    stack.use({
     71      [Symbol.asyncDispose]: null,
     72      [Symbol.dispose]() {
     73        disposed.push(4);
     74      }
     75    });
     76    stack.use({
     77      [Symbol.asyncDispose]() {
     78        disposed.push(5);
     79      },
     80      [Symbol.dispose]() {
     81        // This shouldn't be called because @@asyncDispose exists.
     82        disposed.push(6);
     83      }
     84    });
     85    assertEq(stack.disposed, false);
     86    await stack.disposeAsync();
     87  }
     88  testAsyncDisposableStackUseWithFallback();
     89  drainJobQueue();
     90  assertEq(stack.disposed, true);
     91  assertArrayEq(disposed, [5, 4, 3, 2, 1]);
     92 }
     93 
     94 {
     95  const disposed = [];
     96  const stack = new AsyncDisposableStack();
     97  for (let i = 0; i < 5; i++) {
     98    stack.use({
     99      [Symbol.asyncDispose]() {
    100        disposed.push(i);
    101      },
    102    });
    103  }
    104  assertEq(stack.disposed, false);
    105  async function testAsyncDisposableStackWithUsingDecl() {
    106    {
    107      await using stk = stack;
    108      stk.use({
    109        [Symbol.asyncDispose]() {
    110          disposed.push(5);
    111        },
    112      });
    113      stk.use({
    114        [Symbol.dispose]() {
    115          disposed.push(6);
    116        }
    117      });
    118    }
    119    assertEq(stack.disposed, true);
    120    {
    121      // This should be no-op.
    122      await using stk2 = stack;
    123    }
    124    assertEq(stack.disposed, true);
    125  }
    126  testAsyncDisposableStackWithUsingDecl();
    127  drainJobQueue();
    128  assertArrayEq(disposed, [6, 5, 4, 3, 2, 1, 0]);
    129 }
    130 
    131 {
    132  const disposed = [];
    133  const stack = new AsyncDisposableStack();
    134  async function testAsyncDisposableStackWithNullUndefineds() {
    135    stack.use(undefined);
    136    stack.use(null);
    137    stack.use({
    138      [Symbol.asyncDispose]() {
    139        disposed.push(1);
    140      }
    141    });
    142    await stack.disposeAsync();
    143  }
    144  testAsyncDisposableStackWithNullUndefineds();
    145  drainJobQueue();
    146  assertArrayEq(disposed, [1]);
    147  assertEq(stack.disposed, true);
    148 }
    149 
    150 {
    151  const disposed = [];
    152  const stack = new AsyncDisposableStack();
    153  let error;
    154  stack.use({
    155    [Symbol.asyncDispose]() {
    156      disposed.push(1);
    157 
    158      // This method is called during disposal, and before the
    159      // disposal process is started the stack's state is set to disposed.
    160      // Thus, calling stack use here again would throw.
    161      stack.use({
    162        [Symbol.asyncDispose]() {
    163          disposed.push(2);
    164        },
    165      });
    166    }
    167  });
    168  stack.disposeAsync().catch((e) => {
    169    error = e;
    170  });
    171  drainJobQueue();
    172  assertEq(error instanceof ReferenceError, true);
    173  assertArrayEq(disposed, [1]);
    174  assertEq(stack.disposed, true);
    175 }
    176 
    177 {
    178  assertThrowsInstanceOf(() => {
    179    const stack = new AsyncDisposableStack();
    180    stack.use(1);
    181  }, TypeError);
    182 }
    183 
    184 {
    185  assertThrowsInstanceOf(() => {
    186    const stack = new AsyncDisposableStack();
    187    stack.use({
    188      [Symbol.asyncDispose]: undefined
    189    });
    190  }, TypeError);
    191 
    192  assertThrowsInstanceOf(() => {
    193    const stack = new AsyncDisposableStack();
    194    stack.use({
    195      [Symbol.asyncDispose]: null
    196    });
    197  }, TypeError);
    198 
    199  assertThrowsInstanceOf(() => {
    200    const stack = new AsyncDisposableStack();
    201    stack.use({
    202      [Symbol.asyncDispose]: 1
    203    });
    204  }, TypeError);
    205 }