tor-browser

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

bad-underlying-sources.any.js (9590B)


      1 // META: global=window,worker,shadowrealm
      2 'use strict';
      3 
      4 
      5 test(() => {
      6 
      7  const theError = new Error('a unique string');
      8 
      9  assert_throws_exactly(theError, () => {
     10    new ReadableStream({
     11      get start() {
     12        throw theError;
     13      }
     14    });
     15  }, 'constructing the stream should re-throw the error');
     16 
     17 }, 'Underlying source start: throwing getter');
     18 
     19 
     20 test(() => {
     21 
     22  const theError = new Error('a unique string');
     23 
     24  assert_throws_exactly(theError, () => {
     25    new ReadableStream({
     26      start() {
     27        throw theError;
     28      }
     29    });
     30  }, 'constructing the stream should re-throw the error');
     31 
     32 }, 'Underlying source start: throwing method');
     33 
     34 
     35 test(() => {
     36 
     37  const theError = new Error('a unique string');
     38  assert_throws_exactly(theError, () => new ReadableStream({
     39    get pull() {
     40      throw theError;
     41    }
     42  }), 'constructor should throw');
     43 
     44 }, 'Underlying source: throwing pull getter (initial pull)');
     45 
     46 
     47 promise_test(t => {
     48 
     49  const theError = new Error('a unique string');
     50  const rs = new ReadableStream({
     51    pull() {
     52      throw theError;
     53    }
     54  });
     55 
     56  return promise_rejects_exactly(t, theError, rs.getReader().closed);
     57 
     58 }, 'Underlying source: throwing pull method (initial pull)');
     59 
     60 
     61 promise_test(t => {
     62 
     63  const theError = new Error('a unique string');
     64 
     65  let counter = 0;
     66  const rs = new ReadableStream({
     67    get pull() {
     68      ++counter;
     69      if (counter === 1) {
     70        return c => c.enqueue('a');
     71      }
     72 
     73      throw theError;
     74    }
     75  });
     76  const reader = rs.getReader();
     77 
     78  return Promise.all([
     79    reader.read().then(r => {
     80      assert_object_equals(r, { value: 'a', done: false }, 'the first chunk read should be correct');
     81    }),
     82    reader.read().then(r => {
     83      assert_object_equals(r, { value: 'a', done: false }, 'the second chunk read should be correct');
     84      assert_equals(counter, 1, 'counter should be 1');
     85    })
     86  ]);
     87 
     88 }, 'Underlying source pull: throwing getter (second pull does not result in a second get)');
     89 
     90 promise_test(t => {
     91 
     92  const theError = new Error('a unique string');
     93 
     94  let counter = 0;
     95  const rs = new ReadableStream({
     96    pull(c) {
     97      ++counter;
     98      if (counter === 1) {
     99        c.enqueue('a');
    100        return;
    101      }
    102 
    103      throw theError;
    104    }
    105  });
    106  const reader = rs.getReader();
    107 
    108  return Promise.all([
    109    reader.read().then(r => {
    110      assert_object_equals(r, { value: 'a', done: false }, 'the chunk read should be correct');
    111    }),
    112    promise_rejects_exactly(t, theError, reader.closed)
    113  ]);
    114 
    115 }, 'Underlying source pull: throwing method (second pull)');
    116 
    117 test(() => {
    118 
    119  const theError = new Error('a unique string');
    120  assert_throws_exactly(theError, () => new ReadableStream({
    121    get cancel() {
    122      throw theError;
    123    }
    124  }), 'constructor should throw');
    125 
    126 }, 'Underlying source cancel: throwing getter');
    127 
    128 promise_test(t => {
    129 
    130  const theError = new Error('a unique string');
    131  const rs = new ReadableStream({
    132    cancel() {
    133      throw theError;
    134    }
    135  });
    136 
    137  return promise_rejects_exactly(t, theError, rs.cancel());
    138 
    139 }, 'Underlying source cancel: throwing method');
    140 
    141 promise_test(() => {
    142 
    143  let controller;
    144  const rs = new ReadableStream({
    145    start(c) {
    146      controller = c;
    147    }
    148  });
    149 
    150  rs.cancel();
    151  assert_throws_js(TypeError, () => controller.enqueue('a'), 'Calling enqueue after canceling should throw');
    152 
    153  return rs.getReader().closed;
    154 
    155 }, 'Underlying source: calling enqueue on an empty canceled stream should throw');
    156 
    157 promise_test(() => {
    158 
    159  let controller;
    160  const rs = new ReadableStream({
    161    start(c) {
    162      c.enqueue('a');
    163      c.enqueue('b');
    164      controller = c;
    165    }
    166  });
    167 
    168  rs.cancel();
    169  assert_throws_js(TypeError, () => controller.enqueue('c'), 'Calling enqueue after canceling should throw');
    170 
    171  return rs.getReader().closed;
    172 
    173 }, 'Underlying source: calling enqueue on a non-empty canceled stream should throw');
    174 
    175 promise_test(() => {
    176 
    177  return new ReadableStream({
    178    start(c) {
    179      c.close();
    180      assert_throws_js(TypeError, () => c.enqueue('a'), 'call to enqueue should throw a TypeError');
    181    }
    182  }).getReader().closed;
    183 
    184 }, 'Underlying source: calling enqueue on a closed stream should throw');
    185 
    186 promise_test(t => {
    187 
    188  const theError = new Error('boo');
    189  const closed = new ReadableStream({
    190    start(c) {
    191      c.error(theError);
    192      assert_throws_js(TypeError, () => c.enqueue('a'), 'call to enqueue should throw the error');
    193    }
    194  }).getReader().closed;
    195 
    196  return promise_rejects_exactly(t, theError, closed);
    197 
    198 }, 'Underlying source: calling enqueue on an errored stream should throw');
    199 
    200 promise_test(() => {
    201 
    202  return new ReadableStream({
    203    start(c) {
    204      c.close();
    205      assert_throws_js(TypeError, () => c.close(), 'second call to close should throw a TypeError');
    206    }
    207  }).getReader().closed;
    208 
    209 }, 'Underlying source: calling close twice on an empty stream should throw the second time');
    210 
    211 promise_test(() => {
    212 
    213  let startCalled = false;
    214  let readCalled = false;
    215  const reader = new ReadableStream({
    216    start(c) {
    217      c.enqueue('a');
    218      c.close();
    219      assert_throws_js(TypeError, () => c.close(), 'second call to close should throw a TypeError');
    220      startCalled = true;
    221    }
    222  }).getReader();
    223 
    224  return Promise.all([
    225    reader.read().then(r => {
    226      assert_object_equals(r, { value: 'a', done: false }, 'read() should read the enqueued chunk');
    227      readCalled = true;
    228    }),
    229    reader.closed.then(() => {
    230      assert_true(startCalled);
    231      assert_true(readCalled);
    232    })
    233  ]);
    234 
    235 }, 'Underlying source: calling close twice on a non-empty stream should throw the second time');
    236 
    237 promise_test(() => {
    238 
    239  let controller;
    240  let startCalled = false;
    241  const rs = new ReadableStream({
    242    start(c) {
    243      controller = c;
    244      startCalled = true;
    245    }
    246  });
    247 
    248  rs.cancel();
    249  assert_throws_js(TypeError, () => controller.close(), 'Calling close after canceling should throw');
    250 
    251  return rs.getReader().closed.then(() => {
    252    assert_true(startCalled);
    253  });
    254 
    255 }, 'Underlying source: calling close on an empty canceled stream should throw');
    256 
    257 promise_test(() => {
    258 
    259  let controller;
    260  let startCalled = false;
    261  const rs = new ReadableStream({
    262    start(c) {
    263      controller = c;
    264      c.enqueue('a');
    265      startCalled = true;
    266    }
    267  });
    268 
    269  rs.cancel();
    270  assert_throws_js(TypeError, () => controller.close(), 'Calling close after canceling should throw');
    271 
    272  return rs.getReader().closed.then(() => {
    273    assert_true(startCalled);
    274  });
    275 
    276 }, 'Underlying source: calling close on a non-empty canceled stream should throw');
    277 
    278 promise_test(() => {
    279 
    280  const theError = new Error('boo');
    281  let startCalled = false;
    282 
    283  const closed = new ReadableStream({
    284    start(c) {
    285      c.error(theError);
    286      assert_throws_js(TypeError, () => c.close(), 'call to close should throw a TypeError');
    287      startCalled = true;
    288    }
    289  }).getReader().closed;
    290 
    291  return closed.catch(e => {
    292    assert_true(startCalled);
    293    assert_equals(e, theError, 'closed should reject with the error');
    294  });
    295 
    296 }, 'Underlying source: calling close after error should throw');
    297 
    298 promise_test(() => {
    299 
    300  const theError = new Error('boo');
    301  let startCalled = false;
    302 
    303  const closed = new ReadableStream({
    304    start(c) {
    305      c.error(theError);
    306      c.error();
    307      startCalled = true;
    308    }
    309  }).getReader().closed;
    310 
    311  return closed.catch(e => {
    312    assert_true(startCalled);
    313    assert_equals(e, theError, 'closed should reject with the error');
    314  });
    315 
    316 }, 'Underlying source: calling error twice should not throw');
    317 
    318 promise_test(() => {
    319 
    320  let startCalled = false;
    321 
    322  const closed = new ReadableStream({
    323    start(c) {
    324      c.close();
    325      c.error();
    326      startCalled = true;
    327    }
    328  }).getReader().closed;
    329 
    330  return closed.then(() => assert_true(startCalled));
    331 
    332 }, 'Underlying source: calling error after close should not throw');
    333 
    334 promise_test(() => {
    335 
    336  let startCalled = false;
    337  const firstError = new Error('1');
    338  const secondError = new Error('2');
    339 
    340  const closed = new ReadableStream({
    341    start(c) {
    342      c.error(firstError);
    343      startCalled = true;
    344      return Promise.reject(secondError);
    345    }
    346  }).getReader().closed;
    347 
    348  return closed.catch(e => {
    349    assert_true(startCalled);
    350    assert_equals(e, firstError, 'closed should reject with the first error');
    351  });
    352 
    353 }, 'Underlying source: calling error and returning a rejected promise from start should cause the stream to error ' +
    354   'with the first error');
    355 
    356 promise_test(() => {
    357 
    358  let startCalled = false;
    359  const firstError = new Error('1');
    360  const secondError = new Error('2');
    361 
    362  const closed = new ReadableStream({
    363    pull(c) {
    364      c.error(firstError);
    365      startCalled = true;
    366      return Promise.reject(secondError);
    367    }
    368  }).getReader().closed;
    369 
    370  return closed.catch(e => {
    371    assert_true(startCalled);
    372    assert_equals(e, firstError, 'closed should reject with the first error');
    373  });
    374 
    375 }, 'Underlying source: calling error and returning a rejected promise from pull should cause the stream to error ' +
    376   'with the first error');
    377 
    378 const error1 = { name: 'error1' };
    379 
    380 promise_test(t => {
    381 
    382  let pullShouldThrow = false;
    383  const rs = new ReadableStream({
    384    pull(controller) {
    385      if (pullShouldThrow) {
    386        throw error1;
    387      }
    388      controller.enqueue(0);
    389    }
    390  }, new CountQueuingStrategy({highWaterMark: 1}));
    391  const reader = rs.getReader();
    392  return Promise.resolve().then(() => {
    393    pullShouldThrow = true;
    394    return Promise.all([
    395      reader.read(),
    396      promise_rejects_exactly(t, error1, reader.closed, '.closed promise should reject')
    397    ]);
    398  });
    399 
    400 }, 'read should not error if it dequeues and pull() throws');