tor-browser

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

general.any.js (8333B)


      1 // META: global=window,worker,shadowrealm
      2 'use strict';
      3 
      4 test(() => {
      5  const ws = new WritableStream({});
      6  const writer = ws.getWriter();
      7  writer.releaseLock();
      8 
      9  assert_throws_js(TypeError, () => writer.desiredSize, 'desiredSize should throw a TypeError');
     10 }, 'desiredSize on a released writer');
     11 
     12 test(() => {
     13  const ws = new WritableStream({});
     14 
     15  const writer = ws.getWriter();
     16 
     17  assert_equals(writer.desiredSize, 1, 'desiredSize should be 1');
     18 }, 'desiredSize initial value');
     19 
     20 promise_test(() => {
     21  const ws = new WritableStream({});
     22 
     23  const writer = ws.getWriter();
     24 
     25  writer.close();
     26 
     27  return writer.closed.then(() => {
     28    assert_equals(writer.desiredSize, 0, 'desiredSize should be 0');
     29  });
     30 }, 'desiredSize on a writer for a closed stream');
     31 
     32 test(() => {
     33  const ws = new WritableStream({
     34    start(c) {
     35      c.error();
     36    }
     37  });
     38 
     39  const writer = ws.getWriter();
     40  assert_equals(writer.desiredSize, null, 'desiredSize should be null');
     41 }, 'desiredSize on a writer for an errored stream');
     42 
     43 test(() => {
     44  const ws = new WritableStream({});
     45 
     46  const writer = ws.getWriter();
     47  writer.close();
     48  writer.releaseLock();
     49 
     50  ws.getWriter();
     51 }, 'ws.getWriter() on a closing WritableStream');
     52 
     53 promise_test(() => {
     54  const ws = new WritableStream({});
     55 
     56  const writer = ws.getWriter();
     57  return writer.close().then(() => {
     58    writer.releaseLock();
     59 
     60    ws.getWriter();
     61  });
     62 }, 'ws.getWriter() on a closed WritableStream');
     63 
     64 test(() => {
     65  const ws = new WritableStream({});
     66 
     67  const writer = ws.getWriter();
     68  writer.abort();
     69  writer.releaseLock();
     70 
     71  ws.getWriter();
     72 }, 'ws.getWriter() on an aborted WritableStream');
     73 
     74 promise_test(() => {
     75  const ws = new WritableStream({
     76    start(c) {
     77      c.error();
     78    }
     79  });
     80 
     81  const writer = ws.getWriter();
     82  return writer.closed.then(
     83    v => assert_unreached('writer.closed fulfilled unexpectedly with: ' + v),
     84    () => {
     85      writer.releaseLock();
     86 
     87      ws.getWriter();
     88    }
     89  );
     90 }, 'ws.getWriter() on an errored WritableStream');
     91 
     92 promise_test(() => {
     93  const ws = new WritableStream({});
     94 
     95  const writer = ws.getWriter();
     96  writer.releaseLock();
     97 
     98  return writer.closed.then(
     99    v => assert_unreached('writer.closed fulfilled unexpectedly with: ' + v),
    100    closedRejection => {
    101      assert_equals(closedRejection.name, 'TypeError', 'closed promise should reject with a TypeError');
    102      return writer.ready.then(
    103        v => assert_unreached('writer.ready fulfilled unexpectedly with: ' + v),
    104        readyRejection => assert_equals(readyRejection, closedRejection,
    105          'ready promise should reject with the same error')
    106      );
    107    }
    108  );
    109 }, 'closed and ready on a released writer');
    110 
    111 promise_test(t => {
    112  let thisObject = null;
    113  // Calls to Sink methods after the first are implicitly ignored. Only the first value that is passed to the resolver
    114  // is used.
    115  class Sink {
    116    start() {
    117      // Called twice
    118      t.step(() => {
    119        assert_equals(this, thisObject, 'start should be called as a method');
    120      });
    121    }
    122 
    123    write() {
    124      t.step(() => {
    125        assert_equals(this, thisObject, 'write should be called as a method');
    126      });
    127    }
    128 
    129    close() {
    130      t.step(() => {
    131        assert_equals(this, thisObject, 'close should be called as a method');
    132      });
    133    }
    134 
    135    abort() {
    136      t.step(() => {
    137        assert_equals(this, thisObject, 'abort should be called as a method');
    138      });
    139    }
    140  }
    141 
    142  const theSink = new Sink();
    143  thisObject = theSink;
    144  const ws = new WritableStream(theSink);
    145 
    146  const writer = ws.getWriter();
    147 
    148  writer.write('a');
    149  const closePromise = writer.close();
    150 
    151  const ws2 = new WritableStream(theSink);
    152  const writer2 = ws2.getWriter();
    153  const abortPromise = writer2.abort();
    154 
    155  return Promise.all([
    156    closePromise,
    157    abortPromise
    158  ]);
    159 }, 'WritableStream should call underlying sink methods as methods');
    160 
    161 promise_test(t => {
    162  function functionWithOverloads() {}
    163  functionWithOverloads.apply = t.unreached_func('apply() should not be called');
    164  functionWithOverloads.call = t.unreached_func('call() should not be called');
    165  const underlyingSink = {
    166    start: functionWithOverloads,
    167    write: functionWithOverloads,
    168    close: functionWithOverloads,
    169    abort: functionWithOverloads
    170  };
    171  // Test start(), write(), close().
    172  const ws1 = new WritableStream(underlyingSink);
    173  const writer1 = ws1.getWriter();
    174  writer1.write('a');
    175  writer1.close();
    176 
    177  // Test abort().
    178  const abortError = new Error();
    179  abortError.name = 'abort error';
    180 
    181  const ws2 = new WritableStream(underlyingSink);
    182  const writer2 = ws2.getWriter();
    183  writer2.abort(abortError);
    184 
    185  // Test abort() with a close underlying sink method present. (Historical; see
    186  // https://github.com/whatwg/streams/issues/620#issuecomment-263483953 for what used to be
    187  // tested here. But more coverage can't hurt.)
    188  const ws3 = new WritableStream({
    189    start: functionWithOverloads,
    190    write: functionWithOverloads,
    191    close: functionWithOverloads
    192  });
    193  const writer3 = ws3.getWriter();
    194  writer3.abort(abortError);
    195 
    196  return writer1.closed
    197      .then(() => promise_rejects_exactly(t, abortError, writer2.closed, 'writer2.closed should be rejected'))
    198      .then(() => promise_rejects_exactly(t, abortError, writer3.closed, 'writer3.closed should be rejected'));
    199 }, 'methods should not not have .apply() or .call() called');
    200 
    201 promise_test(() => {
    202  const strategy = {
    203    size() {
    204      if (this !== undefined) {
    205        throw new Error('size called as a method');
    206      }
    207      return 1;
    208    }
    209  };
    210 
    211  const ws = new WritableStream({}, strategy);
    212  const writer = ws.getWriter();
    213  return writer.write('a');
    214 }, 'WritableStream\'s strategy.size should not be called as a method');
    215 
    216 promise_test(() => {
    217  const ws = new WritableStream();
    218  const writer1 = ws.getWriter();
    219  assert_equals(undefined, writer1.releaseLock(), 'releaseLock() should return undefined');
    220  const writer2 = ws.getWriter();
    221  assert_equals(undefined, writer1.releaseLock(), 'no-op releaseLock() should return undefined');
    222  // Calling releaseLock() on writer1 should not interfere with writer2. If it did, then the ready promise would be
    223  // rejected.
    224  return writer2.ready;
    225 }, 'redundant releaseLock() is no-op');
    226 
    227 promise_test(() => {
    228  const events = [];
    229  const ws = new WritableStream();
    230  const writer = ws.getWriter();
    231  return writer.ready.then(() => {
    232    // Force the ready promise back to a pending state.
    233    const writerPromise = writer.write('dummy');
    234    const readyPromise = writer.ready.catch(() => events.push('ready'));
    235    const closedPromise = writer.closed.catch(() => events.push('closed'));
    236    writer.releaseLock();
    237    return Promise.all([readyPromise, closedPromise]).then(() => {
    238      assert_array_equals(events, ['ready', 'closed'], 'ready promise should fire before closed promise');
    239      // Stop the writer promise hanging around after the test has finished.
    240      return Promise.all([
    241        writerPromise,
    242        ws.abort()
    243      ]);
    244    });
    245  });
    246 }, 'ready promise should fire before closed on releaseLock');
    247 
    248 test(() => {
    249  class Subclass extends WritableStream {
    250    extraFunction() {
    251      return true;
    252    }
    253  }
    254  assert_equals(
    255      Object.getPrototypeOf(Subclass.prototype), WritableStream.prototype,
    256      'Subclass.prototype\'s prototype should be WritableStream.prototype');
    257  assert_equals(Object.getPrototypeOf(Subclass), WritableStream,
    258                'Subclass\'s prototype should be WritableStream');
    259  const sub = new Subclass();
    260  assert_true(sub instanceof WritableStream,
    261              'Subclass object should be an instance of WritableStream');
    262  assert_true(sub instanceof Subclass,
    263              'Subclass object should be an instance of Subclass');
    264  const lockedGetter = Object.getOwnPropertyDescriptor(
    265      WritableStream.prototype, 'locked').get;
    266  assert_equals(lockedGetter.call(sub), sub.locked,
    267                'Subclass object should pass brand check');
    268  assert_true(sub.extraFunction(),
    269              'extraFunction() should be present on Subclass object');
    270 }, 'Subclassing WritableStream should work');
    271 
    272 test(() => {
    273  const ws = new WritableStream();
    274  assert_false(ws.locked, 'stream should not be locked');
    275  ws.getWriter();
    276  assert_true(ws.locked, 'stream should be locked');
    277 }, 'the locked getter should return true if the stream has a writer');