tor-browser

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

general.any.js (5923B)


      1 // META: global=window,worker,shadowrealm
      2 // META: script=../resources/recording-streams.js
      3 'use strict';
      4 
      5 test(() => {
      6 
      7  const rs = new ReadableStream();
      8  const ws = new WritableStream();
      9 
     10  assert_false(rs.locked, 'sanity check: the ReadableStream must not start locked');
     11  assert_false(ws.locked, 'sanity check: the WritableStream must not start locked');
     12 
     13  rs.pipeTo(ws);
     14 
     15  assert_true(rs.locked, 'the ReadableStream must become locked');
     16  assert_true(ws.locked, 'the WritableStream must become locked');
     17 
     18 }, 'Piping must lock both the ReadableStream and WritableStream');
     19 
     20 promise_test(() => {
     21 
     22  const rs = new ReadableStream({
     23    start(controller) {
     24      controller.close();
     25    }
     26  });
     27  const ws = new WritableStream();
     28 
     29  return rs.pipeTo(ws).then(() => {
     30    assert_false(rs.locked, 'the ReadableStream must become unlocked');
     31    assert_false(ws.locked, 'the WritableStream must become unlocked');
     32  });
     33 
     34 }, 'Piping finishing must unlock both the ReadableStream and WritableStream');
     35 
     36 promise_test(t => {
     37 
     38  const fakeRS = Object.create(ReadableStream.prototype);
     39  const ws = new WritableStream();
     40 
     41  return promise_rejects_js(t, TypeError, ReadableStream.prototype.pipeTo.apply(fakeRS, [ws]),
     42    'pipeTo should reject with a TypeError');
     43 
     44 }, 'pipeTo must check the brand of its ReadableStream this value');
     45 
     46 promise_test(t => {
     47 
     48  const rs = new ReadableStream();
     49  const fakeWS = Object.create(WritableStream.prototype);
     50 
     51  return promise_rejects_js(t, TypeError, ReadableStream.prototype.pipeTo.apply(rs, [fakeWS]),
     52    'pipeTo should reject with a TypeError');
     53 
     54 }, 'pipeTo must check the brand of its WritableStream argument');
     55 
     56 promise_test(t => {
     57 
     58  const rs = new ReadableStream();
     59  const ws = new WritableStream();
     60 
     61  rs.getReader();
     62 
     63  assert_true(rs.locked, 'sanity check: the ReadableStream starts locked');
     64  assert_false(ws.locked, 'sanity check: the WritableStream does not start locked');
     65 
     66  return promise_rejects_js(t, TypeError, rs.pipeTo(ws)).then(() => {
     67    assert_false(ws.locked, 'the WritableStream must still be unlocked');
     68  });
     69 
     70 }, 'pipeTo must fail if the ReadableStream is locked, and not lock the WritableStream');
     71 
     72 promise_test(t => {
     73 
     74  const rs = new ReadableStream();
     75  const ws = new WritableStream();
     76 
     77  ws.getWriter();
     78 
     79  assert_false(rs.locked, 'sanity check: the ReadableStream does not start locked');
     80  assert_true(ws.locked, 'sanity check: the WritableStream starts locked');
     81 
     82  return promise_rejects_js(t, TypeError, rs.pipeTo(ws)).then(() => {
     83    assert_false(rs.locked, 'the ReadableStream must still be unlocked');
     84  });
     85 
     86 }, 'pipeTo must fail if the WritableStream is locked, and not lock the ReadableStream');
     87 
     88 promise_test(() => {
     89 
     90  const CHUNKS = 10;
     91 
     92  const rs = new ReadableStream({
     93    start(c) {
     94      for (let i = 0; i < CHUNKS; ++i) {
     95        c.enqueue(i);
     96      }
     97      c.close();
     98    }
     99  });
    100 
    101  const written = [];
    102  const ws = new WritableStream({
    103    write(chunk) {
    104      written.push(chunk);
    105    },
    106    close() {
    107      written.push('closed');
    108    }
    109  }, new CountQueuingStrategy({ highWaterMark: CHUNKS }));
    110 
    111  return rs.pipeTo(ws).then(() => {
    112    const targetValues = [];
    113    for (let i = 0; i < CHUNKS; ++i) {
    114      targetValues.push(i);
    115    }
    116    targetValues.push('closed');
    117 
    118    assert_array_equals(written, targetValues, 'the correct values must be written');
    119 
    120    // Ensure both readable and writable are closed by the time the pipe finishes.
    121    return Promise.all([
    122      rs.getReader().closed,
    123      ws.getWriter().closed
    124    ]);
    125  });
    126 
    127  // NOTE: no requirement on *when* the pipe finishes; that is left to implementations.
    128 
    129 }, 'Piping from a ReadableStream from which lots of chunks are synchronously readable');
    130 
    131 promise_test(t => {
    132 
    133  let controller;
    134  const rs = recordingReadableStream({
    135    start(c) {
    136      controller = c;
    137    }
    138  });
    139 
    140  const ws = recordingWritableStream();
    141 
    142  const pipePromise = rs.pipeTo(ws).then(() => {
    143    assert_array_equals(ws.events, ['write', 'Hello', 'close']);
    144  });
    145 
    146  t.step_timeout(() => {
    147    controller.enqueue('Hello');
    148    t.step_timeout(() => controller.close(), 10);
    149  }, 10);
    150 
    151  return pipePromise;
    152 
    153 }, 'Piping from a ReadableStream for which a chunk becomes asynchronously readable after the pipeTo');
    154 
    155 for (const preventAbort of [true, false]) {
    156  promise_test(() => {
    157 
    158    const rs = new ReadableStream({
    159      pull() {
    160        return Promise.reject(undefined);
    161      }
    162    });
    163 
    164    return rs.pipeTo(new WritableStream(), { preventAbort }).then(
    165        () => assert_unreached('pipeTo promise should be rejected'),
    166        value => assert_equals(value, undefined, 'rejection value should be undefined'));
    167 
    168  }, `an undefined rejection from pull should cause pipeTo() to reject when preventAbort is ${preventAbort}`);
    169 }
    170 
    171 for (const preventCancel of [true, false]) {
    172  promise_test(() => {
    173 
    174    const rs = new ReadableStream({
    175      pull(controller) {
    176        controller.enqueue(0);
    177      }
    178    });
    179 
    180    const ws = new WritableStream({
    181      write() {
    182        return Promise.reject(undefined);
    183      }
    184    });
    185 
    186    return rs.pipeTo(ws, { preventCancel }).then(
    187         () => assert_unreached('pipeTo promise should be rejected'),
    188        value => assert_equals(value, undefined, 'rejection value should be undefined'));
    189 
    190  }, `an undefined rejection from write should cause pipeTo() to reject when preventCancel is ${preventCancel}`);
    191 }
    192 
    193 promise_test(t => {
    194  const rs = new ReadableStream();
    195  const ws = new WritableStream();
    196  return promise_rejects_js(t, TypeError, rs.pipeTo(ws, {
    197    get preventAbort() {
    198      ws.getWriter();
    199    }
    200  }), 'pipeTo should reject');
    201 }, 'pipeTo() should reject if an option getter grabs a writer');
    202 
    203 promise_test(t => {
    204  const rs = new ReadableStream({
    205    start(controller) {
    206      controller.close();
    207    }
    208  });
    209  const ws = new WritableStream();
    210 
    211  return rs.pipeTo(ws, null);
    212 }, 'pipeTo() promise should resolve if null is passed');