tor-browser

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

flush.any.js (4570B)


      1 // META: global=window,worker,shadowrealm
      2 // META: script=../resources/test-utils.js
      3 'use strict';
      4 
      5 promise_test(() => {
      6  let flushCalled = false;
      7  const ts = new TransformStream({
      8    transform() { },
      9    flush() {
     10      flushCalled = true;
     11    }
     12  });
     13 
     14  return ts.writable.getWriter().close().then(() => {
     15    return assert_true(flushCalled, 'closing the writable triggers the transform flush immediately');
     16  });
     17 }, 'TransformStream flush is called immediately when the writable is closed, if no writes are queued');
     18 
     19 promise_test(() => {
     20  let flushCalled = false;
     21  let resolveTransform;
     22  const ts = new TransformStream({
     23    transform() {
     24      return new Promise(resolve => {
     25        resolveTransform = resolve;
     26      });
     27    },
     28    flush() {
     29      flushCalled = true;
     30      return new Promise(() => {}); // never resolves
     31    }
     32  }, undefined, { highWaterMark: 1 });
     33 
     34  const writer = ts.writable.getWriter();
     35  writer.write('a');
     36  writer.close();
     37  assert_false(flushCalled, 'closing the writable does not immediately call flush if writes are not finished');
     38 
     39  let rsClosed = false;
     40  ts.readable.getReader().closed.then(() => {
     41    rsClosed = true;
     42  });
     43 
     44  return delay(0).then(() => {
     45    assert_false(flushCalled, 'closing the writable does not asynchronously call flush if writes are not finished');
     46    resolveTransform();
     47    return delay(0);
     48  }).then(() => {
     49    assert_true(flushCalled, 'flush is eventually called');
     50    assert_false(rsClosed, 'if flushPromise does not resolve, the readable does not become closed');
     51  });
     52 }, 'TransformStream flush is called after all queued writes finish, once the writable is closed');
     53 
     54 promise_test(() => {
     55  let c;
     56  const ts = new TransformStream({
     57    start(controller) {
     58      c = controller;
     59    },
     60    transform() {
     61    },
     62    flush() {
     63      c.enqueue('x');
     64      c.enqueue('y');
     65    }
     66  });
     67 
     68  const reader = ts.readable.getReader();
     69 
     70  const writer = ts.writable.getWriter();
     71  writer.write('a');
     72  writer.close();
     73  return reader.read().then(result1 => {
     74    assert_equals(result1.value, 'x', 'the first chunk read is the first one enqueued in flush');
     75    assert_equals(result1.done, false, 'the first chunk read is the first one enqueued in flush');
     76 
     77    return reader.read().then(result2 => {
     78      assert_equals(result2.value, 'y', 'the second chunk read is the second one enqueued in flush');
     79      assert_equals(result2.done, false, 'the second chunk read is the second one enqueued in flush');
     80    });
     81  });
     82 }, 'TransformStream flush gets a chance to enqueue more into the readable');
     83 
     84 promise_test(() => {
     85  let c;
     86  const ts = new TransformStream({
     87    start(controller) {
     88      c = controller;
     89    },
     90    transform() {
     91    },
     92    flush() {
     93      c.enqueue('x');
     94      c.enqueue('y');
     95      return delay(0);
     96    }
     97  });
     98 
     99  const reader = ts.readable.getReader();
    100 
    101  const writer = ts.writable.getWriter();
    102  writer.write('a');
    103  writer.close();
    104 
    105  return Promise.all([
    106    reader.read().then(result1 => {
    107      assert_equals(result1.value, 'x', 'the first chunk read is the first one enqueued in flush');
    108      assert_equals(result1.done, false, 'the first chunk read is the first one enqueued in flush');
    109 
    110      return reader.read().then(result2 => {
    111        assert_equals(result2.value, 'y', 'the second chunk read is the second one enqueued in flush');
    112        assert_equals(result2.done, false, 'the second chunk read is the second one enqueued in flush');
    113      });
    114    }),
    115    reader.closed.then(() => {
    116      assert_true(true, 'readable reader becomes closed');
    117    })
    118  ]);
    119 }, 'TransformStream flush gets a chance to enqueue more into the readable, and can then async close');
    120 
    121 const error1 = new Error('error1');
    122 error1.name = 'error1';
    123 
    124 promise_test(t => {
    125  const ts = new TransformStream({
    126    flush(controller) {
    127      controller.error(error1);
    128    }
    129  });
    130  return promise_rejects_exactly(t, error1, ts.writable.getWriter().close(), 'close() should reject');
    131 }, 'error() during flush should cause writer.close() to reject');
    132 
    133 promise_test(async t => {
    134  let flushed = false;
    135  const ts = new TransformStream({
    136    flush() {
    137      flushed = true;
    138    },
    139    cancel: t.unreached_func('cancel should not be called')
    140  });
    141  const closePromise = ts.writable.close();
    142  await delay(0);
    143  const cancelPromise = ts.readable.cancel(error1);
    144  await Promise.all([closePromise, cancelPromise]);
    145  assert_equals(flushed, true, 'transformer.flush() should be called');
    146 }, 'closing the writable side should call transformer.flush() and a parallel readable.cancel() should not reject');