tor-browser

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

general.any.js (100296B)


      1 // META: global=window,worker,shadowrealm
      2 // META: script=../resources/rs-utils.js
      3 // META: script=../resources/test-utils.js
      4 'use strict';
      5 
      6 const error1 = new Error('error1');
      7 error1.name = 'error1';
      8 
      9 test(() => {
     10  assert_throws_js(TypeError, () => new ReadableStream().getReader({ mode: 'byob' }));
     11 }, 'getReader({mode: "byob"}) throws on non-bytes streams');
     12 
     13 
     14 test(() => {
     15  // Constructing ReadableStream with an empty underlying byte source object as parameter shouldn't throw.
     16  new ReadableStream({ type: 'bytes' }).getReader({ mode: 'byob' });
     17  // Constructor must perform ToString(type).
     18  new ReadableStream({ type: { toString() {return 'bytes';} } })
     19    .getReader({ mode: 'byob' });
     20  new ReadableStream({ type: { toString: null, valueOf() {return 'bytes';} } })
     21    .getReader({ mode: 'byob' });
     22 }, 'ReadableStream with byte source can be constructed with no errors');
     23 
     24 test(() => {
     25  const ReadableStreamBYOBReader = new ReadableStream({ type: 'bytes' }).getReader({ mode: 'byob' }).constructor;
     26  const rs = new ReadableStream({ type: 'bytes' });
     27 
     28  let reader = rs.getReader({ mode: { toString() { return 'byob'; } } });
     29  assert_true(reader instanceof ReadableStreamBYOBReader, 'must give a BYOB reader');
     30  reader.releaseLock();
     31 
     32  reader = rs.getReader({ mode: { toString: null, valueOf() {return 'byob';} } });
     33  assert_true(reader instanceof ReadableStreamBYOBReader, 'must give a BYOB reader');
     34  reader.releaseLock();
     35 
     36  reader = rs.getReader({ mode: 'byob', notmode: 'ignored' });
     37  assert_true(reader instanceof ReadableStreamBYOBReader, 'must give a BYOB reader');
     38 }, 'getReader({mode}) must perform ToString()');
     39 
     40 promise_test(() => {
     41  let startCalled = false;
     42  let startCalledBeforePull = false;
     43  let desiredSize;
     44  let controller;
     45 
     46  let resolveTestPromise;
     47  const testPromise = new Promise(resolve => {
     48    resolveTestPromise = resolve;
     49  });
     50 
     51  new ReadableStream({
     52    start(c) {
     53      controller = c;
     54      startCalled = true;
     55    },
     56    pull() {
     57      startCalledBeforePull = startCalled;
     58      desiredSize = controller.desiredSize;
     59      resolveTestPromise();
     60    },
     61    type: 'bytes'
     62  }, {
     63    highWaterMark: 256
     64  });
     65 
     66  return testPromise.then(() => {
     67    assert_true(startCalledBeforePull, 'start should be called before pull');
     68    assert_equals(desiredSize, 256, 'desiredSize should equal highWaterMark');
     69  });
     70 
     71 }, 'ReadableStream with byte source: Construct and expect start and pull being called');
     72 
     73 promise_test(() => {
     74  let pullCount = 0;
     75  let checkedNoPull = false;
     76 
     77  let resolveTestPromise;
     78  const testPromise = new Promise(resolve => {
     79    resolveTestPromise = resolve;
     80  });
     81  let resolveStartPromise;
     82 
     83  new ReadableStream({
     84    start() {
     85      return new Promise(resolve => {
     86        resolveStartPromise = resolve;
     87      });
     88    },
     89    pull() {
     90      if (checkedNoPull) {
     91        resolveTestPromise();
     92      }
     93 
     94      ++pullCount;
     95    },
     96    type: 'bytes'
     97  }, {
     98    highWaterMark: 256
     99  });
    100 
    101  Promise.resolve().then(() => {
    102    assert_equals(pullCount, 0);
    103    checkedNoPull = true;
    104    resolveStartPromise();
    105  });
    106 
    107  return testPromise;
    108 
    109 }, 'ReadableStream with byte source: No automatic pull call if start doesn\'t finish');
    110 
    111 test(() => {
    112  assert_throws_js(Error, () => new ReadableStream({ start() { throw new Error(); }, type:'bytes' }),
    113      'start() can throw an exception with type: bytes');
    114 }, 'ReadableStream with byte source: start() throws an exception');
    115 
    116 promise_test(t => {
    117  new ReadableStream({
    118    pull: t.unreached_func('pull() should not be called'),
    119    type: 'bytes'
    120  }, {
    121    highWaterMark: 0
    122  });
    123 
    124  return Promise.resolve();
    125 }, 'ReadableStream with byte source: Construct with highWaterMark of 0');
    126 
    127 test(() => {
    128  new ReadableStream({
    129    start(c) {
    130      assert_equals(c.desiredSize, 10, 'desiredSize must start at the highWaterMark');
    131      c.close();
    132      assert_equals(c.desiredSize, 0, 'after closing, desiredSize must be 0');
    133    },
    134    type: 'bytes'
    135  }, {
    136    highWaterMark: 10
    137  });
    138 }, 'ReadableStream with byte source: desiredSize when closed');
    139 
    140 test(() => {
    141  new ReadableStream({
    142    start(c) {
    143      assert_equals(c.desiredSize, 10, 'desiredSize must start at the highWaterMark');
    144      c.error();
    145      assert_equals(c.desiredSize, null, 'after erroring, desiredSize must be null');
    146    },
    147    type: 'bytes'
    148  }, {
    149    highWaterMark: 10
    150  });
    151 }, 'ReadableStream with byte source: desiredSize when errored');
    152 
    153 promise_test(t => {
    154  const stream = new ReadableStream({
    155    type: 'bytes'
    156  });
    157 
    158  const reader = stream.getReader();
    159  reader.releaseLock();
    160 
    161  return promise_rejects_js(t, TypeError, reader.closed, 'closed must reject');
    162 }, 'ReadableStream with byte source: getReader(), then releaseLock()');
    163 
    164 promise_test(t => {
    165  const stream = new ReadableStream({
    166    type: 'bytes'
    167  });
    168 
    169  const reader = stream.getReader({ mode: 'byob' });
    170  reader.releaseLock();
    171 
    172  return promise_rejects_js(t, TypeError, reader.closed, 'closed must reject');
    173 }, 'ReadableStream with byte source: getReader() with mode set to byob, then releaseLock()');
    174 
    175 promise_test(t => {
    176  const stream = new ReadableStream({
    177    start(c) {
    178      c.close();
    179    },
    180    pull: t.unreached_func('pull() should not be called'),
    181    type: 'bytes'
    182  });
    183 
    184  const reader = stream.getReader();
    185 
    186  return reader.closed.then(() => {
    187    assert_throws_js(TypeError, () => stream.getReader(), 'getReader() must throw');
    188  });
    189 }, 'ReadableStream with byte source: Test that closing a stream does not release a reader automatically');
    190 
    191 promise_test(t => {
    192  const stream = new ReadableStream({
    193    start(c) {
    194      c.close();
    195    },
    196    pull: t.unreached_func('pull() should not be called'),
    197    type: 'bytes'
    198  });
    199 
    200  const reader = stream.getReader({ mode: 'byob' });
    201 
    202  return reader.closed.then(() => {
    203    assert_throws_js(TypeError, () => stream.getReader({ mode: 'byob' }), 'getReader() must throw');
    204  });
    205 }, 'ReadableStream with byte source: Test that closing a stream does not release a BYOB reader automatically');
    206 
    207 promise_test(t => {
    208  const stream = new ReadableStream({
    209    start(c) {
    210      c.error(error1);
    211    },
    212    pull: t.unreached_func('pull() should not be called'),
    213    type: 'bytes'
    214  });
    215 
    216  const reader = stream.getReader();
    217 
    218  return promise_rejects_exactly(t, error1, reader.closed, 'closed must reject').then(() => {
    219    assert_throws_js(TypeError, () => stream.getReader(), 'getReader() must throw');
    220  });
    221 }, 'ReadableStream with byte source: Test that erroring a stream does not release a reader automatically');
    222 
    223 promise_test(t => {
    224  const stream = new ReadableStream({
    225    start(c) {
    226      c.error(error1);
    227    },
    228    pull: t.unreached_func('pull() should not be called'),
    229    type: 'bytes'
    230  });
    231 
    232  const reader = stream.getReader({ mode: 'byob' });
    233 
    234  return promise_rejects_exactly(t, error1, reader.closed, 'closed must reject').then(() => {
    235    assert_throws_js(TypeError, () => stream.getReader({ mode: 'byob' }), 'getReader() must throw');
    236  });
    237 }, 'ReadableStream with byte source: Test that erroring a stream does not release a BYOB reader automatically');
    238 
    239 promise_test(async t => {
    240  const rs = new ReadableStream({
    241    type: 'bytes',
    242    start(c) {
    243      c.enqueue(new Uint8Array([1, 2, 3]));
    244    }
    245  });
    246 
    247  const reader1 = rs.getReader({mode: 'byob'});
    248  reader1.releaseLock();
    249 
    250  const reader2 = rs.getReader({mode: 'byob'});
    251 
    252  // Should be a no-op
    253  reader1.releaseLock();
    254 
    255  const result = await reader2.read(new Uint8Array([0, 0, 0]));
    256  assert_typed_array_equals(result.value, new Uint8Array([1, 2, 3]),
    257    'read() should still work on reader2 even after reader1 is released');
    258  assert_false(result.done, 'done');
    259 
    260 }, 'ReadableStream with byte source: cannot use an already-released BYOB reader to unlock a stream again');
    261 
    262 promise_test(async t => {
    263  const stream = new ReadableStream({
    264    type: 'bytes'
    265  });
    266 
    267  const reader = stream.getReader();
    268  const read = reader.read();
    269  reader.releaseLock();
    270  await promise_rejects_js(t, TypeError, read, 'pending read must reject');
    271 }, 'ReadableStream with byte source: releaseLock() on ReadableStreamDefaultReader must reject pending read()');
    272 
    273 promise_test(async t => {
    274  const stream = new ReadableStream({
    275    type: 'bytes'
    276  });
    277 
    278  const reader = stream.getReader({ mode: 'byob' });
    279  const read = reader.read(new Uint8Array(1));
    280  reader.releaseLock();
    281  await promise_rejects_js(t, TypeError, read, 'pending read must reject');
    282 }, 'ReadableStream with byte source: releaseLock() on ReadableStreamBYOBReader must reject pending read()');
    283 
    284 promise_test(() => {
    285  let pullCount = 0;
    286 
    287  const stream = new ReadableStream({
    288    pull() {
    289      ++pullCount;
    290    },
    291    type: 'bytes'
    292  }, {
    293    highWaterMark: 8
    294  });
    295 
    296  stream.getReader();
    297 
    298  assert_equals(pullCount, 0, 'No pull as start() just finished and is not yet reflected to the state of the stream');
    299 
    300  return Promise.resolve().then(() => {
    301    assert_equals(pullCount, 1, 'pull must be invoked');
    302  });
    303 }, 'ReadableStream with byte source: Automatic pull() after start()');
    304 
    305 promise_test(() => {
    306  let pullCount = 0;
    307 
    308  const stream = new ReadableStream({
    309    pull() {
    310      ++pullCount;
    311    },
    312    type: 'bytes'
    313  }, {
    314    highWaterMark: 0
    315  });
    316 
    317  const reader = stream.getReader();
    318  reader.read();
    319 
    320  assert_equals(pullCount, 0, 'No pull as start() just finished and is not yet reflected to the state of the stream');
    321 
    322  return Promise.resolve().then(() => {
    323    assert_equals(pullCount, 1, 'pull must be invoked');
    324  });
    325 }, 'ReadableStream with byte source: Automatic pull() after start() and read()');
    326 
    327 // View buffers are detached after pull() returns, so record the information at the time that pull() was called.
    328 function extractViewInfo(view) {
    329  return {
    330    constructor: view.constructor,
    331    bufferByteLength: view.buffer.byteLength,
    332    byteOffset: view.byteOffset,
    333    byteLength: view.byteLength
    334  };
    335 }
    336 
    337 promise_test(() => {
    338  let pullCount = 0;
    339  let controller;
    340  const byobRequests = [];
    341 
    342  const stream = new ReadableStream({
    343    start(c) {
    344      controller = c;
    345    },
    346    pull() {
    347      const byobRequest = controller.byobRequest;
    348      const view = byobRequest.view;
    349      byobRequests[pullCount] = {
    350        nonNull: byobRequest !== null,
    351        viewNonNull: view !== null,
    352        viewInfo: extractViewInfo(view)
    353      };
    354      if (pullCount === 0) {
    355        view[0] = 0x01;
    356        byobRequest.respond(1);
    357      } else if (pullCount === 1) {
    358        view[0] = 0x02;
    359        view[1] = 0x03;
    360        byobRequest.respond(2);
    361      }
    362 
    363      ++pullCount;
    364    },
    365    type: 'bytes',
    366    autoAllocateChunkSize: 16
    367  }, {
    368    highWaterMark: 0
    369  });
    370 
    371  const reader = stream.getReader();
    372  const p0 = reader.read();
    373  const p1 = reader.read();
    374 
    375  assert_equals(pullCount, 0, 'No pull() as start() just finished and is not yet reflected to the state of the stream');
    376 
    377  return Promise.resolve().then(() => {
    378    assert_equals(pullCount, 1, 'pull() must have been invoked once');
    379    const byobRequest = byobRequests[0];
    380    assert_true(byobRequest.nonNull, 'first byobRequest must not be null');
    381    assert_true(byobRequest.viewNonNull, 'first byobRequest.view must not be null');
    382    const viewInfo = byobRequest.viewInfo;
    383    assert_equals(viewInfo.constructor, Uint8Array, 'first view.constructor should be Uint8Array');
    384    assert_equals(viewInfo.bufferByteLength, 16, 'first view.buffer.byteLength should be 16');
    385    assert_equals(viewInfo.byteOffset, 0, 'first view.byteOffset should be 0');
    386    assert_equals(viewInfo.byteLength, 16, 'first view.byteLength should be 16');
    387 
    388    return p0;
    389  }).then(result => {
    390    assert_equals(pullCount, 2, 'pull() must have been invoked twice');
    391    const value = result.value;
    392    assert_not_equals(value, undefined, 'first read should have a value');
    393    assert_equals(value.constructor, Uint8Array, 'first value should be a Uint8Array');
    394    assert_equals(value.buffer.byteLength, 16, 'first value.buffer.byteLength should be 16');
    395    assert_equals(value.byteOffset, 0, 'first value.byteOffset should be 0');
    396    assert_equals(value.byteLength, 1, 'first value.byteLength should be 1');
    397    assert_equals(value[0], 0x01, 'first value[0] should be 0x01');
    398    const byobRequest = byobRequests[1];
    399    assert_true(byobRequest.nonNull, 'second byobRequest must not be null');
    400    assert_true(byobRequest.viewNonNull, 'second byobRequest.view must not be null');
    401    const viewInfo = byobRequest.viewInfo;
    402    assert_equals(viewInfo.constructor, Uint8Array, 'second view.constructor should be Uint8Array');
    403    assert_equals(viewInfo.bufferByteLength, 16, 'second view.buffer.byteLength should be 16');
    404    assert_equals(viewInfo.byteOffset, 0, 'second view.byteOffset should be 0');
    405    assert_equals(viewInfo.byteLength, 16, 'second view.byteLength should be 16');
    406 
    407    return p1;
    408  }).then(result => {
    409    assert_equals(pullCount, 2, 'pull() should only be invoked twice');
    410    const value = result.value;
    411    assert_not_equals(value, undefined, 'second read should have a value');
    412    assert_equals(value.constructor, Uint8Array, 'second value should be a Uint8Array');
    413    assert_equals(value.buffer.byteLength, 16, 'second value.buffer.byteLength should be 16');
    414    assert_equals(value.byteOffset, 0, 'second value.byteOffset should be 0');
    415    assert_equals(value.byteLength, 2, 'second value.byteLength should be 2');
    416    assert_equals(value[0], 0x02, 'second value[0] should be 0x02');
    417    assert_equals(value[1], 0x03, 'second value[1] should be 0x03');
    418  });
    419 }, 'ReadableStream with byte source: autoAllocateChunkSize');
    420 
    421 promise_test(() => {
    422  let pullCount = 0;
    423  let controller;
    424  const byobRequests = [];
    425 
    426  const stream = new ReadableStream({
    427    start(c) {
    428      controller = c;
    429    },
    430    pull() {
    431      const byobRequest = controller.byobRequest;
    432      const view = byobRequest.view;
    433      byobRequests[pullCount] = {
    434        nonNull: byobRequest !== null,
    435        viewNonNull: view !== null,
    436        viewInfo: extractViewInfo(view)
    437      };
    438      if (pullCount === 0) {
    439        view[0] = 0x01;
    440        byobRequest.respond(1);
    441      } else if (pullCount === 1) {
    442        view[0] = 0x02;
    443        view[1] = 0x03;
    444        byobRequest.respond(2);
    445      }
    446 
    447      ++pullCount;
    448    },
    449    type: 'bytes',
    450    autoAllocateChunkSize: 16
    451  }, {
    452    highWaterMark: 0
    453  });
    454 
    455  const reader = stream.getReader();
    456  return reader.read().then(result => {
    457    const value = result.value;
    458    assert_not_equals(value, undefined, 'first read should have a value');
    459    assert_equals(value.constructor, Uint8Array, 'first value should be a Uint8Array');
    460    assert_equals(value.buffer.byteLength, 16, 'first value.buffer.byteLength should be 16');
    461    assert_equals(value.byteOffset, 0, 'first value.byteOffset should be 0');
    462    assert_equals(value.byteLength, 1, 'first value.byteLength should be 1');
    463    assert_equals(value[0], 0x01, 'first value[0] should be 0x01');
    464    const byobRequest = byobRequests[0];
    465    assert_true(byobRequest.nonNull, 'first byobRequest must not be null');
    466    assert_true(byobRequest.viewNonNull, 'first byobRequest.view must not be null');
    467    const viewInfo = byobRequest.viewInfo;
    468    assert_equals(viewInfo.constructor, Uint8Array, 'first view.constructor should be Uint8Array');
    469    assert_equals(viewInfo.bufferByteLength, 16, 'first view.buffer.byteLength should be 16');
    470    assert_equals(viewInfo.byteOffset, 0, 'first view.byteOffset should be 0');
    471    assert_equals(viewInfo.byteLength, 16, 'first view.byteLength should be 16');
    472 
    473    reader.releaseLock();
    474    const byobReader = stream.getReader({ mode: 'byob' });
    475    return byobReader.read(new Uint8Array(32));
    476  }).then(result => {
    477    const value = result.value;
    478    assert_not_equals(value, undefined, 'second read should have a value');
    479    assert_equals(value.constructor, Uint8Array, 'second value should be a Uint8Array');
    480    assert_equals(value.buffer.byteLength, 32, 'second value.buffer.byteLength should be 32');
    481    assert_equals(value.byteOffset, 0, 'second value.byteOffset should be 0');
    482    assert_equals(value.byteLength, 2, 'second value.byteLength should be 2');
    483    assert_equals(value[0], 0x02, 'second value[0] should be 0x02');
    484    assert_equals(value[1], 0x03, 'second value[1] should be 0x03');
    485    const byobRequest = byobRequests[1];
    486    assert_true(byobRequest.nonNull, 'second byobRequest must not be null');
    487    assert_true(byobRequest.viewNonNull, 'second byobRequest.view must not be null');
    488    const viewInfo = byobRequest.viewInfo;
    489    assert_equals(viewInfo.constructor, Uint8Array, 'second view.constructor should be Uint8Array');
    490    assert_equals(viewInfo.bufferByteLength, 32, 'second view.buffer.byteLength should be 32');
    491    assert_equals(viewInfo.byteOffset, 0, 'second view.byteOffset should be 0');
    492    assert_equals(viewInfo.byteLength, 32, 'second view.byteLength should be 32');
    493    assert_equals(pullCount, 2, 'pullCount should be 2');
    494  });
    495 }, 'ReadableStream with byte source: Mix of auto allocate and BYOB');
    496 
    497 promise_test(() => {
    498  let pullCount = 0;
    499 
    500  const stream = new ReadableStream({
    501    pull() {
    502      ++pullCount;
    503    },
    504    type: 'bytes'
    505  }, {
    506    highWaterMark: 0
    507  });
    508 
    509  const reader = stream.getReader();
    510  reader.read(new Uint8Array(8));
    511 
    512  assert_equals(pullCount, 0, 'No pull as start() just finished and is not yet reflected to the state of the stream');
    513 
    514  return Promise.resolve().then(() => {
    515    assert_equals(pullCount, 1, 'pull must be invoked');
    516  });
    517 }, 'ReadableStream with byte source: Automatic pull() after start() and read(view)');
    518 
    519 promise_test(() => {
    520  let pullCount = 0;
    521 
    522  let controller;
    523  let desiredSizeInStart;
    524  let desiredSizeInPull;
    525 
    526  const stream = new ReadableStream({
    527    start(c) {
    528      c.enqueue(new Uint8Array(16));
    529      desiredSizeInStart = c.desiredSize;
    530      controller = c;
    531    },
    532    pull() {
    533      ++pullCount;
    534 
    535      if (pullCount === 1) {
    536        desiredSizeInPull = controller.desiredSize;
    537      }
    538    },
    539    type: 'bytes'
    540  }, {
    541    highWaterMark: 8
    542  });
    543 
    544  return Promise.resolve().then(() => {
    545    assert_equals(pullCount, 0, 'No pull as the queue was filled by start()');
    546    assert_equals(desiredSizeInStart, -8, 'desiredSize after enqueue() in start()');
    547 
    548    const reader = stream.getReader();
    549 
    550    const promise = reader.read();
    551    assert_equals(pullCount, 1, 'The first pull() should be made on read()');
    552    assert_equals(desiredSizeInPull, 8, 'desiredSize in pull()');
    553 
    554    return promise.then(result => {
    555      assert_false(result.done, 'result.done');
    556 
    557      const view = result.value;
    558      assert_equals(view.constructor, Uint8Array, 'view.constructor');
    559      assert_equals(view.buffer.byteLength, 16, 'view.buffer');
    560      assert_equals(view.byteOffset, 0, 'view.byteOffset');
    561      assert_equals(view.byteLength, 16, 'view.byteLength');
    562    });
    563  });
    564 }, 'ReadableStream with byte source: enqueue(), getReader(), then read()');
    565 
    566 promise_test(() => {
    567  let controller;
    568 
    569  const stream = new ReadableStream({
    570    start(c) {
    571      controller = c;
    572    },
    573    type: 'bytes'
    574  });
    575 
    576  const reader = stream.getReader();
    577 
    578  const promise = reader.read().then(result => {
    579    assert_false(result.done);
    580 
    581    const view = result.value;
    582    assert_equals(view.constructor, Uint8Array);
    583    assert_equals(view.buffer.byteLength, 1);
    584    assert_equals(view.byteOffset, 0);
    585    assert_equals(view.byteLength, 1);
    586  });
    587 
    588  controller.enqueue(new Uint8Array(1));
    589 
    590  return promise;
    591 }, 'ReadableStream with byte source: Push source that doesn\'t understand pull signal');
    592 
    593 test(() => {
    594  assert_throws_js(TypeError, () => new ReadableStream({
    595    pull: 'foo',
    596    type: 'bytes'
    597  }), 'constructor should throw');
    598 }, 'ReadableStream with byte source: pull() function is not callable');
    599 
    600 promise_test(() => {
    601  const stream = new ReadableStream({
    602    start(c) {
    603      c.enqueue(new Uint16Array(16));
    604    },
    605    type: 'bytes'
    606  });
    607 
    608  const reader = stream.getReader();
    609 
    610  return reader.read().then(result => {
    611    assert_false(result.done);
    612 
    613    const view = result.value;
    614    assert_equals(view.constructor, Uint8Array);
    615    assert_equals(view.buffer.byteLength, 32);
    616    assert_equals(view.byteOffset, 0);
    617    assert_equals(view.byteLength, 32);
    618  });
    619 }, 'ReadableStream with byte source: enqueue() with Uint16Array, getReader(), then read()');
    620 
    621 promise_test(t => {
    622  const stream = new ReadableStream({
    623    start(c) {
    624      const view = new Uint8Array(16);
    625      view[0] = 0x01;
    626      view[8] = 0x02;
    627      c.enqueue(view);
    628    },
    629    pull: t.unreached_func('pull() should not be called'),
    630    type: 'bytes'
    631  });
    632 
    633  const byobReader = stream.getReader({ mode: 'byob' });
    634 
    635  return byobReader.read(new Uint8Array(8)).then(result => {
    636    assert_false(result.done, 'done');
    637 
    638    const view = result.value;
    639    assert_equals(view.constructor, Uint8Array, 'value.constructor');
    640    assert_equals(view.buffer.byteLength, 8, 'value.buffer.byteLength');
    641    assert_equals(view.byteOffset, 0, 'value.byteOffset');
    642    assert_equals(view.byteLength, 8, 'value.byteLength');
    643    assert_equals(view[0], 0x01);
    644 
    645    byobReader.releaseLock();
    646 
    647    const reader = stream.getReader();
    648 
    649    return reader.read();
    650  }).then(result => {
    651    assert_false(result.done, 'done');
    652 
    653    const view = result.value;
    654    assert_equals(view.constructor, Uint8Array, 'value.constructor');
    655    assert_equals(view.buffer.byteLength, 16, 'value.buffer.byteLength');
    656    assert_equals(view.byteOffset, 8, 'value.byteOffset');
    657    assert_equals(view.byteLength, 8, 'value.byteLength');
    658    assert_equals(view[0], 0x02);
    659  });
    660 }, 'ReadableStream with byte source: enqueue(), read(view) partially, then read()');
    661 
    662 promise_test(t => {
    663  let controller;
    664 
    665  const stream = new ReadableStream({
    666    start(c) {
    667      controller = c;
    668    },
    669    pull: t.unreached_func('pull() should not be called'),
    670    type: 'bytes'
    671  });
    672 
    673  const reader = stream.getReader();
    674 
    675  controller.enqueue(new Uint8Array(16));
    676  controller.close();
    677 
    678  return reader.read().then(result => {
    679    assert_false(result.done, 'done');
    680 
    681    const view = result.value;
    682    assert_equals(view.byteOffset, 0, 'byteOffset');
    683    assert_equals(view.byteLength, 16, 'byteLength');
    684 
    685    return reader.read();
    686  }).then(result => {
    687    assert_true(result.done, 'done');
    688    assert_equals(result.value, undefined, 'value');
    689  });
    690 }, 'ReadableStream with byte source: getReader(), enqueue(), close(), then read()');
    691 
    692 promise_test(t => {
    693  const stream = new ReadableStream({
    694    start(c) {
    695      c.enqueue(new Uint8Array(16));
    696      c.close();
    697    },
    698    pull: t.unreached_func('pull() should not be called'),
    699    type: 'bytes'
    700  });
    701 
    702  const reader = stream.getReader();
    703 
    704  return reader.read().then(result => {
    705    assert_false(result.done, 'done');
    706 
    707    const view = result.value;
    708    assert_equals(view.byteOffset, 0, 'byteOffset');
    709    assert_equals(view.byteLength, 16, 'byteLength');
    710 
    711    return reader.read();
    712  }).then(result => {
    713    assert_true(result.done, 'done');
    714    assert_equals(result.value, undefined, 'value');
    715  });
    716 }, 'ReadableStream with byte source: enqueue(), close(), getReader(), then read()');
    717 
    718 promise_test(() => {
    719  let controller;
    720  let byobRequest;
    721 
    722  const stream = new ReadableStream({
    723    start(c) {
    724      controller = c;
    725    },
    726    pull() {
    727      controller.enqueue(new Uint8Array(16));
    728      byobRequest = controller.byobRequest;
    729    },
    730    type: 'bytes'
    731  });
    732 
    733  const reader = stream.getReader();
    734 
    735  return reader.read().then(result => {
    736    assert_false(result.done, 'done');
    737    assert_equals(result.value.byteLength, 16, 'byteLength');
    738    assert_equals(byobRequest, null, 'byobRequest must be null');
    739  });
    740 }, 'ReadableStream with byte source: Respond to pull() by enqueue()');
    741 
    742 promise_test(() => {
    743  let pullCount = 0;
    744 
    745  let controller;
    746  let byobRequest;
    747  const desiredSizes = [];
    748 
    749  const stream = new ReadableStream({
    750    start(c) {
    751      controller = c;
    752    },
    753    pull() {
    754      byobRequest = controller.byobRequest;
    755      desiredSizes.push(controller.desiredSize);
    756      controller.enqueue(new Uint8Array(1));
    757      desiredSizes.push(controller.desiredSize);
    758      controller.enqueue(new Uint8Array(1));
    759      desiredSizes.push(controller.desiredSize);
    760 
    761      ++pullCount;
    762    },
    763    type: 'bytes'
    764  }, {
    765    highWaterMark: 0
    766  });
    767 
    768  const reader = stream.getReader();
    769 
    770  const p0 = reader.read();
    771  const p1 = reader.read();
    772  const p2 = reader.read();
    773 
    774  // Respond to the first pull call.
    775  controller.enqueue(new Uint8Array(1));
    776 
    777  assert_equals(pullCount, 0, 'pullCount after the enqueue() outside pull');
    778 
    779  return Promise.all([p0, p1, p2]).then(result => {
    780    assert_equals(pullCount, 1, 'pullCount after completion of all read()s');
    781 
    782    assert_equals(result[0].done, false, 'result[0].done');
    783    assert_equals(result[0].value.byteLength, 1, 'result[0].value.byteLength');
    784    assert_equals(result[1].done, false, 'result[1].done');
    785    assert_equals(result[1].value.byteLength, 1, 'result[1].value.byteLength');
    786    assert_equals(result[2].done, false, 'result[2].done');
    787    assert_equals(result[2].value.byteLength, 1, 'result[2].value.byteLength');
    788    assert_equals(byobRequest, null, 'byobRequest should be null');
    789    assert_equals(desiredSizes[0], 0, 'desiredSize on pull should be 0');
    790    assert_equals(desiredSizes[1], 0, 'desiredSize after 1st enqueue() should be 0');
    791    assert_equals(desiredSizes[2], 0, 'desiredSize after 2nd enqueue() should be 0');
    792    assert_equals(pullCount, 1, 'pull() should only be called once');
    793  });
    794 }, 'ReadableStream with byte source: Respond to pull() by enqueue() asynchronously');
    795 
    796 promise_test(() => {
    797  let pullCount = 0;
    798 
    799  let byobRequest;
    800  const desiredSizes = [];
    801 
    802  const stream = new ReadableStream({
    803    pull(c) {
    804      byobRequest = c.byobRequest;
    805      desiredSizes.push(c.desiredSize);
    806 
    807      if (pullCount < 3) {
    808        c.enqueue(new Uint8Array(1));
    809      } else {
    810        c.close();
    811      }
    812 
    813      ++pullCount;
    814    },
    815    type: 'bytes'
    816  }, {
    817    highWaterMark: 256
    818  });
    819 
    820  const reader = stream.getReader();
    821 
    822  const p0 = reader.read();
    823  const p1 = reader.read();
    824  const p2 = reader.read();
    825 
    826  assert_equals(pullCount, 0, 'No pull as start() just finished and is not yet reflected to the state of the stream');
    827 
    828  return Promise.all([p0, p1, p2]).then(result => {
    829    assert_equals(pullCount, 4, 'pullCount after completion of all read()s');
    830 
    831    assert_equals(result[0].done, false, 'result[0].done');
    832    assert_equals(result[0].value.byteLength, 1, 'result[0].value.byteLength');
    833    assert_equals(result[1].done, false, 'result[1].done');
    834    assert_equals(result[1].value.byteLength, 1, 'result[1].value.byteLength');
    835    assert_equals(result[2].done, false, 'result[2].done');
    836    assert_equals(result[2].value.byteLength, 1, 'result[2].value.byteLength');
    837    assert_equals(byobRequest, null, 'byobRequest should be null');
    838    assert_equals(desiredSizes[0], 256, 'desiredSize on pull should be 256');
    839    assert_equals(desiredSizes[1], 256, 'desiredSize after 1st enqueue() should be 256');
    840    assert_equals(desiredSizes[2], 256, 'desiredSize after 2nd enqueue() should be 256');
    841    assert_equals(desiredSizes[3], 256, 'desiredSize after 3rd enqueue() should be 256');
    842  });
    843 }, 'ReadableStream with byte source: Respond to multiple pull() by separate enqueue()');
    844 
    845 promise_test(() => {
    846  let controller;
    847 
    848  let pullCount = 0;
    849  const byobRequestDefined = [];
    850  let byobRequestViewDefined;
    851 
    852  const stream = new ReadableStream({
    853    start(c) {
    854      controller = c;
    855    },
    856    pull() {
    857      byobRequestDefined.push(controller.byobRequest !== null);
    858      const initialByobRequest = controller.byobRequest;
    859 
    860      const view = controller.byobRequest.view;
    861      view[0] = 0x01;
    862      controller.byobRequest.respond(1);
    863 
    864      byobRequestDefined.push(controller.byobRequest !== null);
    865      byobRequestViewDefined = initialByobRequest.view !== null;
    866 
    867      ++pullCount;
    868    },
    869    type: 'bytes'
    870  });
    871 
    872  const reader = stream.getReader({ mode: 'byob' });
    873 
    874  return reader.read(new Uint8Array(1)).then(result => {
    875    assert_false(result.done, 'result.done');
    876    assert_equals(result.value.byteLength, 1, 'result.value.byteLength');
    877    assert_equals(result.value[0], 0x01, 'result.value[0]');
    878    assert_equals(pullCount, 1, 'pull() should be called only once');
    879    assert_true(byobRequestDefined[0], 'byobRequest must not be null before respond()');
    880    assert_false(byobRequestDefined[1], 'byobRequest must be null after respond()');
    881    assert_false(byobRequestViewDefined, 'view of initial byobRequest must be null after respond()');
    882  });
    883 }, 'ReadableStream with byte source: read(view), then respond()');
    884 
    885 promise_test(() => {
    886  let controller;
    887 
    888  let pullCount = 0;
    889  const byobRequestDefined = [];
    890  let byobRequestViewDefined;
    891 
    892  const stream = new ReadableStream({
    893    start(c) {
    894      controller = c;
    895    },
    896    pull() {
    897      byobRequestDefined.push(controller.byobRequest !== null);
    898      const initialByobRequest = controller.byobRequest;
    899 
    900      const transferredView = transferArrayBufferView(controller.byobRequest.view);
    901      transferredView[0] = 0x01;
    902      controller.byobRequest.respondWithNewView(transferredView);
    903 
    904      byobRequestDefined.push(controller.byobRequest !== null);
    905      byobRequestViewDefined = initialByobRequest.view !== null;
    906 
    907      ++pullCount;
    908    },
    909    type: 'bytes'
    910  });
    911 
    912  const reader = stream.getReader({ mode: 'byob' });
    913 
    914  return reader.read(new Uint8Array(1)).then(result => {
    915    assert_false(result.done, 'result.done');
    916    assert_equals(result.value.byteLength, 1, 'result.value.byteLength');
    917    assert_equals(result.value[0], 0x01, 'result.value[0]');
    918    assert_equals(pullCount, 1, 'pull() should be called only once');
    919    assert_true(byobRequestDefined[0], 'byobRequest must not be null before respondWithNewView()');
    920    assert_false(byobRequestDefined[1], 'byobRequest must be null after respondWithNewView()');
    921    assert_false(byobRequestViewDefined, 'view of initial byobRequest must be null after respondWithNewView()');
    922  });
    923 }, 'ReadableStream with byte source: read(view), then respondWithNewView() with a transferred ArrayBuffer');
    924 
    925 promise_test(() => {
    926  let controller;
    927  let byobRequestWasDefined;
    928  let incorrectRespondException;
    929 
    930  const stream = new ReadableStream({
    931    start(c) {
    932      controller = c;
    933    },
    934    pull() {
    935      byobRequestWasDefined = controller.byobRequest !== null;
    936 
    937      try {
    938        controller.byobRequest.respond(2);
    939      } catch (e) {
    940        incorrectRespondException = e;
    941      }
    942 
    943      controller.byobRequest.respond(1);
    944    },
    945    type: 'bytes'
    946  });
    947 
    948  const reader = stream.getReader({ mode: 'byob' });
    949 
    950  return reader.read(new Uint8Array(1)).then(() => {
    951    assert_true(byobRequestWasDefined, 'byobRequest should be non-null');
    952    assert_not_equals(incorrectRespondException, undefined, 'respond() must throw');
    953    assert_equals(incorrectRespondException.name, 'RangeError', 'respond() must throw a RangeError');
    954  });
    955 }, 'ReadableStream with byte source: read(view), then respond() with too big value');
    956 
    957 promise_test(() => {
    958  let pullCount = 0;
    959 
    960  let controller;
    961  let byobRequest;
    962  let viewInfo;
    963 
    964  const stream = new ReadableStream({
    965    start(c) {
    966      controller = c;
    967    },
    968    pull() {
    969      ++pullCount;
    970 
    971      byobRequest = controller.byobRequest;
    972      const view = byobRequest.view;
    973      viewInfo = extractViewInfo(view);
    974 
    975      view[0] = 0x01;
    976      view[1] = 0x02;
    977      view[2] = 0x03;
    978 
    979      controller.byobRequest.respond(3);
    980    },
    981    type: 'bytes'
    982  });
    983 
    984  const reader = stream.getReader({ mode: 'byob' });
    985 
    986  return reader.read(new Uint16Array(2)).then(result => {
    987    assert_equals(pullCount, 1);
    988 
    989    assert_false(result.done, 'done');
    990 
    991    const view = result.value;
    992    assert_equals(view.byteOffset, 0, 'byteOffset');
    993    assert_equals(view.byteLength, 2, 'byteLength');
    994 
    995    const dataView = new DataView(view.buffer, view.byteOffset, view.byteLength);
    996    assert_equals(dataView.getUint16(0), 0x0102);
    997 
    998    return reader.read(new Uint8Array(1));
    999  }).then(result => {
   1000    assert_equals(pullCount, 1);
   1001    assert_not_equals(byobRequest, null, 'byobRequest must not be null');
   1002    assert_equals(viewInfo.constructor, Uint8Array, 'view.constructor should be Uint8Array');
   1003    assert_equals(viewInfo.bufferByteLength, 4, 'view.buffer.byteLength should be 4');
   1004    assert_equals(viewInfo.byteOffset, 0, 'view.byteOffset should be 0');
   1005    assert_equals(viewInfo.byteLength, 4, 'view.byteLength should be 4');
   1006 
   1007    assert_false(result.done, 'done');
   1008 
   1009    const view = result.value;
   1010    assert_equals(view.byteOffset, 0, 'byteOffset');
   1011    assert_equals(view.byteLength, 1, 'byteLength');
   1012 
   1013    assert_equals(view[0], 0x03);
   1014  });
   1015 }, 'ReadableStream with byte source: respond(3) to read(view) with 2 element Uint16Array enqueues the 1 byte ' +
   1016   'remainder');
   1017 
   1018 promise_test(() => {
   1019  let pullCount = 0;
   1020 
   1021  let controller;
   1022  let byobRequest;
   1023  let viewInfo;
   1024 
   1025  const stream = new ReadableStream({
   1026    start(c) {
   1027      controller = c;
   1028    },
   1029    pull() {
   1030      ++pullCount;
   1031 
   1032      byobRequest = controller.byobRequest;
   1033      const view = byobRequest.view;
   1034      viewInfo = extractViewInfo(view);
   1035 
   1036      view[0] = 0x01;
   1037      view[1] = 0x02;
   1038      view[2] = 0x03;
   1039 
   1040      controller.byobRequest.respond(3);
   1041    },
   1042    type: 'bytes'
   1043  });
   1044 
   1045  const reader = stream.getReader({ mode: 'byob' });
   1046  const read1 = reader.read(new Uint16Array(2));
   1047  const read2 = reader.read(new Uint8Array(1));
   1048 
   1049  return read1.then(result => {
   1050    assert_equals(pullCount, 1);
   1051 
   1052    assert_false(result.done, 'done');
   1053 
   1054    const view = result.value;
   1055    assert_equals(view.byteOffset, 0, 'byteOffset');
   1056    assert_equals(view.byteLength, 2, 'byteLength');
   1057 
   1058    const dataView = new DataView(view.buffer, view.byteOffset, view.byteLength);
   1059    assert_equals(dataView.getUint16(0), 0x0102);
   1060 
   1061    return read2;
   1062  }).then(result => {
   1063    assert_equals(pullCount, 1);
   1064    assert_not_equals(byobRequest, null, 'byobRequest must not be null');
   1065    assert_equals(viewInfo.constructor, Uint8Array, 'view.constructor should be Uint8Array');
   1066    assert_equals(viewInfo.bufferByteLength, 4, 'view.buffer.byteLength should be 4');
   1067    assert_equals(viewInfo.byteOffset, 0, 'view.byteOffset should be 0');
   1068    assert_equals(viewInfo.byteLength, 4, 'view.byteLength should be 4');
   1069 
   1070    assert_false(result.done, 'done');
   1071 
   1072    const view = result.value;
   1073    assert_equals(view.byteOffset, 0, 'byteOffset');
   1074    assert_equals(view.byteLength, 1, 'byteLength');
   1075 
   1076    assert_equals(view[0], 0x03);
   1077  });
   1078 }, 'ReadableStream with byte source: respond(3) to read(view) with 2 element Uint16Array fulfills second read(view) ' +
   1079   'with the 1 byte remainder');
   1080 
   1081 promise_test(t => {
   1082  const stream = new ReadableStream({
   1083    start(controller) {
   1084      const view = new Uint8Array(16);
   1085      view[15] = 0x01;
   1086      controller.enqueue(view);
   1087    },
   1088    pull: t.unreached_func('pull() should not be called'),
   1089    type: 'bytes'
   1090  });
   1091 
   1092  const reader = stream.getReader({ mode: 'byob' });
   1093 
   1094  return reader.read(new Uint8Array(16)).then(result => {
   1095    assert_false(result.done);
   1096 
   1097    const view = result.value;
   1098    assert_equals(view.byteOffset, 0);
   1099    assert_equals(view.byteLength, 16);
   1100    assert_equals(view[15], 0x01);
   1101  });
   1102 }, 'ReadableStream with byte source: enqueue(), getReader(), then read(view)');
   1103 
   1104 promise_test(t => {
   1105  let cancelCount = 0;
   1106  let reason;
   1107 
   1108  const passedReason = new TypeError('foo');
   1109 
   1110  const stream = new ReadableStream({
   1111    start(c) {
   1112      c.enqueue(new Uint8Array(16));
   1113    },
   1114    pull: t.unreached_func('pull() should not be called'),
   1115    cancel(r) {
   1116      if (cancelCount === 0) {
   1117        reason = r;
   1118      }
   1119 
   1120      ++cancelCount;
   1121    },
   1122    type: 'bytes'
   1123  });
   1124 
   1125  const reader = stream.getReader();
   1126 
   1127  return reader.cancel(passedReason).then(result => {
   1128    assert_equals(result, undefined);
   1129    assert_equals(cancelCount, 1);
   1130    assert_equals(reason, passedReason, 'reason should equal the passed reason');
   1131  });
   1132 }, 'ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = not BYOB)');
   1133 
   1134 promise_test(t => {
   1135  let cancelCount = 0;
   1136  let reason;
   1137 
   1138  const passedReason = new TypeError('foo');
   1139 
   1140  const stream = new ReadableStream({
   1141    start(c) {
   1142      c.enqueue(new Uint8Array(16));
   1143    },
   1144    pull: t.unreached_func('pull() should not be called'),
   1145    cancel(r) {
   1146      if (cancelCount === 0) {
   1147        reason = r;
   1148      }
   1149 
   1150      ++cancelCount;
   1151    },
   1152    type: 'bytes'
   1153  });
   1154 
   1155  const reader = stream.getReader({ mode: 'byob' });
   1156 
   1157  return reader.cancel(passedReason).then(result => {
   1158    assert_equals(result, undefined);
   1159    assert_equals(cancelCount, 1);
   1160    assert_equals(reason, passedReason, 'reason should equal the passed reason');
   1161  });
   1162 }, 'ReadableStream with byte source: enqueue(), getReader(), then cancel() (mode = BYOB)');
   1163 
   1164 promise_test(t => {
   1165  let cancelCount = 0;
   1166  let reason;
   1167 
   1168  const passedReason = new TypeError('foo');
   1169 
   1170  let controller;
   1171 
   1172  const stream = new ReadableStream({
   1173    start(c) {
   1174      controller = c;
   1175    },
   1176    pull: t.unreached_func('pull() should not be called'),
   1177    cancel(r) {
   1178      if (cancelCount === 0) {
   1179        reason = r;
   1180      }
   1181 
   1182      ++cancelCount;
   1183 
   1184      return 'bar';
   1185    },
   1186    type: 'bytes'
   1187  });
   1188 
   1189  const reader = stream.getReader({ mode: 'byob' });
   1190 
   1191  const readPromise = reader.read(new Uint8Array(1)).then(result => {
   1192    assert_true(result.done, 'result.done');
   1193    assert_equals(result.value, undefined, 'result.value');
   1194  });
   1195 
   1196  const cancelPromise = reader.cancel(passedReason).then(result => {
   1197    assert_equals(result, undefined, 'cancel() return value should be fulfilled with undefined');
   1198    assert_equals(cancelCount, 1, 'cancel() should be called only once');
   1199    assert_equals(reason, passedReason, 'reason should equal the passed reason');
   1200  });
   1201 
   1202  return Promise.all([readPromise, cancelPromise]);
   1203 }, 'ReadableStream with byte source: getReader(), read(view), then cancel()');
   1204 
   1205 promise_test(() => {
   1206  let pullCount = 0;
   1207 
   1208  let controller;
   1209  let byobRequest;
   1210  const viewInfos = [];
   1211 
   1212  const stream = new ReadableStream({
   1213    start(c) {
   1214      controller = c;
   1215    },
   1216    pull() {
   1217      byobRequest = controller.byobRequest;
   1218 
   1219      viewInfos.push(extractViewInfo(controller.byobRequest.view));
   1220      controller.enqueue(new Uint8Array(1));
   1221      viewInfos.push(extractViewInfo(controller.byobRequest.view));
   1222 
   1223      ++pullCount;
   1224    },
   1225    type: 'bytes'
   1226  });
   1227 
   1228  return Promise.resolve().then(() => {
   1229    assert_equals(pullCount, 0, 'No pull() as no read(view) yet');
   1230 
   1231    const reader = stream.getReader({ mode: 'byob' });
   1232 
   1233    const promise = reader.read(new Uint16Array(1)).then(result => {
   1234      assert_true(result.done, 'result.done');
   1235      assert_equals(result.value, undefined, 'result.value');
   1236    });
   1237 
   1238    assert_equals(pullCount, 1, '1 pull() should have been made in response to partial fill by enqueue()');
   1239    assert_not_equals(byobRequest, null, 'byobRequest should not be null');
   1240    assert_equals(viewInfos[0].byteLength, 2, 'byteLength before enqueue() should be 2');
   1241    assert_equals(viewInfos[1].byteLength, 1, 'byteLength after enqueue() should be 1');
   1242 
   1243    reader.cancel();
   1244 
   1245    assert_equals(pullCount, 1, 'pull() should only be called once');
   1246    return promise;
   1247  });
   1248 }, 'ReadableStream with byte source: cancel() with partially filled pending pull() request');
   1249 
   1250 promise_test(() => {
   1251  let controller;
   1252  let pullCalled = false;
   1253 
   1254  const stream = new ReadableStream({
   1255    start(c) {
   1256      const view = new Uint8Array(8);
   1257      view[7] = 0x01;
   1258      c.enqueue(view);
   1259 
   1260      controller = c;
   1261    },
   1262    pull() {
   1263      pullCalled = true;
   1264    },
   1265    type: 'bytes'
   1266  });
   1267 
   1268  const reader = stream.getReader({ mode: 'byob' });
   1269 
   1270  const buffer = new ArrayBuffer(16);
   1271 
   1272  return reader.read(new Uint8Array(buffer, 8, 8)).then(result => {
   1273    assert_false(result.done);
   1274 
   1275    assert_false(pullCalled, 'pull() must not have been called');
   1276 
   1277    const view = result.value;
   1278    assert_equals(view.constructor, Uint8Array);
   1279    assert_equals(view.buffer.byteLength, 16);
   1280    assert_equals(view.byteOffset, 8);
   1281    assert_equals(view.byteLength, 8);
   1282    assert_equals(view[7], 0x01);
   1283  });
   1284 }, 'ReadableStream with byte source: enqueue(), getReader(), then read(view) where view.buffer is not fully ' +
   1285   'covered by view');
   1286 
   1287 promise_test(() => {
   1288  let controller;
   1289  let pullCalled = false;
   1290 
   1291  const stream = new ReadableStream({
   1292    start(c) {
   1293      let view;
   1294 
   1295      view = new Uint8Array(16);
   1296      view[15] = 123;
   1297      c.enqueue(view);
   1298 
   1299      view = new Uint8Array(8);
   1300      view[7] = 111;
   1301      c.enqueue(view);
   1302 
   1303      controller = c;
   1304    },
   1305    pull() {
   1306      pullCalled = true;
   1307    },
   1308    type: 'bytes'
   1309  });
   1310 
   1311  const reader = stream.getReader({ mode: 'byob' });
   1312 
   1313  return reader.read(new Uint8Array(24)).then(result => {
   1314    assert_false(result.done, 'done');
   1315 
   1316    assert_false(pullCalled, 'pull() must not have been called');
   1317 
   1318    const view = result.value;
   1319    assert_equals(view.byteOffset, 0, 'byteOffset');
   1320    assert_equals(view.byteLength, 24, 'byteLength');
   1321    assert_equals(view[15], 123, 'Contents are set from the first chunk');
   1322    assert_equals(view[23], 111, 'Contents are set from the second chunk');
   1323  });
   1324 }, 'ReadableStream with byte source: Multiple enqueue(), getReader(), then read(view)');
   1325 
   1326 promise_test(() => {
   1327  let pullCalled = false;
   1328 
   1329  const stream = new ReadableStream({
   1330    start(c) {
   1331      const view = new Uint8Array(16);
   1332      view[15] = 0x01;
   1333      c.enqueue(view);
   1334    },
   1335    pull() {
   1336      pullCalled = true;
   1337    },
   1338    type: 'bytes'
   1339  });
   1340 
   1341  const reader = stream.getReader({ mode: 'byob' });
   1342 
   1343  return reader.read(new Uint8Array(24)).then(result => {
   1344    assert_false(result.done);
   1345 
   1346    assert_false(pullCalled, 'pull() must not have been called');
   1347 
   1348    const view = result.value;
   1349    assert_equals(view.byteOffset, 0);
   1350    assert_equals(view.byteLength, 16);
   1351    assert_equals(view[15], 0x01);
   1352  });
   1353 }, 'ReadableStream with byte source: enqueue(), getReader(), then read(view) with a bigger view');
   1354 
   1355 promise_test(() => {
   1356  let pullCalled = false;
   1357 
   1358  const stream = new ReadableStream({
   1359    start(c) {
   1360      const view = new Uint8Array(16);
   1361      view[7] = 0x01;
   1362      view[15] = 0x02;
   1363      c.enqueue(view);
   1364    },
   1365    pull() {
   1366      pullCalled = true;
   1367    },
   1368    type: 'bytes'
   1369  });
   1370 
   1371  const reader = stream.getReader({ mode: 'byob' });
   1372 
   1373  return reader.read(new Uint8Array(8)).then(result => {
   1374    assert_false(result.done, 'done');
   1375 
   1376    const view = result.value;
   1377    assert_equals(view.byteOffset, 0);
   1378    assert_equals(view.byteLength, 8);
   1379    assert_equals(view[7], 0x01);
   1380 
   1381    return reader.read(new Uint8Array(8));
   1382  }).then(result => {
   1383    assert_false(result.done, 'done');
   1384 
   1385    assert_false(pullCalled, 'pull() must not have been called');
   1386 
   1387    const view = result.value;
   1388    assert_equals(view.byteOffset, 0);
   1389    assert_equals(view.byteLength, 8);
   1390    assert_equals(view[7], 0x02);
   1391  });
   1392 }, 'ReadableStream with byte source: enqueue(), getReader(), then read(view) with smaller views');
   1393 
   1394 promise_test(() => {
   1395  let controller;
   1396  let viewInfo;
   1397 
   1398  const stream = new ReadableStream({
   1399    start(c) {
   1400      const view = new Uint8Array(1);
   1401      view[0] = 0xff;
   1402      c.enqueue(view);
   1403 
   1404      controller = c;
   1405    },
   1406    pull() {
   1407      if (controller.byobRequest === null) {
   1408        return;
   1409      }
   1410 
   1411      const view = controller.byobRequest.view;
   1412      viewInfo = extractViewInfo(view);
   1413 
   1414      view[0] = 0xaa;
   1415      controller.byobRequest.respond(1);
   1416    },
   1417    type: 'bytes'
   1418  });
   1419 
   1420  const reader = stream.getReader({ mode: 'byob' });
   1421 
   1422  return reader.read(new Uint16Array(1)).then(result => {
   1423    assert_false(result.done);
   1424 
   1425    const view = result.value;
   1426    assert_equals(view.byteOffset, 0);
   1427    assert_equals(view.byteLength, 2);
   1428 
   1429    const dataView = new DataView(view.buffer, view.byteOffset, view.byteLength);
   1430    assert_equals(dataView.getUint16(0), 0xffaa);
   1431 
   1432    assert_equals(viewInfo.constructor, Uint8Array, 'view.constructor should be Uint8Array');
   1433    assert_equals(viewInfo.bufferByteLength, 2, 'view.buffer.byteLength should be 2');
   1434    assert_equals(viewInfo.byteOffset, 1, 'view.byteOffset should be 1');
   1435    assert_equals(viewInfo.byteLength, 1, 'view.byteLength should be 1');
   1436  });
   1437 }, 'ReadableStream with byte source: enqueue() 1 byte, getReader(), then read(view) with Uint16Array');
   1438 
   1439 promise_test(() => {
   1440  let pullCount = 0;
   1441 
   1442  let controller;
   1443  let byobRequest;
   1444  let viewInfo;
   1445  let desiredSize;
   1446 
   1447  const stream = new ReadableStream({
   1448    start(c) {
   1449      const view = new Uint8Array(3);
   1450      view[0] = 0x01;
   1451      view[2] = 0x02;
   1452      c.enqueue(view);
   1453 
   1454      controller = c;
   1455    },
   1456    pull() {
   1457      byobRequest = controller.byobRequest;
   1458 
   1459      const view = controller.byobRequest.view;
   1460 
   1461      viewInfo = extractViewInfo(view);
   1462 
   1463      view[0] = 0x03;
   1464      controller.byobRequest.respond(1);
   1465 
   1466      desiredSize = controller.desiredSize;
   1467 
   1468      ++pullCount;
   1469    },
   1470    type: 'bytes'
   1471  });
   1472 
   1473  // Wait for completion of the start method to be reflected.
   1474  return Promise.resolve().then(() => {
   1475    const reader = stream.getReader({ mode: 'byob' });
   1476 
   1477    const promise = reader.read(new Uint16Array(2)).then(result => {
   1478      assert_false(result.done, 'done');
   1479 
   1480      const view = result.value;
   1481      assert_equals(view.constructor, Uint16Array, 'constructor');
   1482      assert_equals(view.buffer.byteLength, 4, 'buffer.byteLength');
   1483      assert_equals(view.byteOffset, 0, 'byteOffset');
   1484      assert_equals(view.byteLength, 2, 'byteLength');
   1485 
   1486      const dataView = new DataView(view.buffer, view.byteOffset, view.byteLength);
   1487      assert_equals(dataView.getUint16(0), 0x0100, 'contents are set');
   1488 
   1489      const p = reader.read(new Uint16Array(1));
   1490 
   1491      assert_equals(pullCount, 1);
   1492 
   1493      return p;
   1494    }).then(result => {
   1495      assert_false(result.done, 'done');
   1496 
   1497      const view = result.value;
   1498      assert_equals(view.buffer.byteLength, 2, 'buffer.byteLength');
   1499      assert_equals(view.byteOffset, 0, 'byteOffset');
   1500      assert_equals(view.byteLength, 2, 'byteLength');
   1501 
   1502      const dataView = new DataView(view.buffer, view.byteOffset, view.byteLength);
   1503      assert_equals(dataView.getUint16(0), 0x0203, 'contents are set');
   1504 
   1505      assert_not_equals(byobRequest, null, 'byobRequest must not be null');
   1506      assert_equals(viewInfo.constructor, Uint8Array, 'view.constructor should be Uint8Array');
   1507      assert_equals(viewInfo.bufferByteLength, 2, 'view.buffer.byteLength should be 2');
   1508      assert_equals(viewInfo.byteOffset, 1, 'view.byteOffset should be 1');
   1509      assert_equals(viewInfo.byteLength, 1, 'view.byteLength should be 1');
   1510      assert_equals(desiredSize, 0, 'desiredSize should be zero');
   1511    });
   1512 
   1513    assert_equals(pullCount, 0);
   1514 
   1515    return promise;
   1516  });
   1517 }, 'ReadableStream with byte source: enqueue() 3 byte, getReader(), then read(view) with 2-element Uint16Array');
   1518 
   1519 promise_test(t => {
   1520  const stream = new ReadableStream({
   1521    start(c) {
   1522      const view = new Uint8Array(1);
   1523      view[0] = 0xff;
   1524      c.enqueue(view);
   1525      c.close();
   1526    },
   1527    pull: t.unreached_func('pull() should not be called'),
   1528    type: 'bytes'
   1529  });
   1530 
   1531  const reader = stream.getReader({ mode: 'byob' });
   1532 
   1533 
   1534  return promise_rejects_js(t, TypeError, reader.read(new Uint16Array(1)), 'read(view) must fail')
   1535      .then(() => promise_rejects_js(t, TypeError, reader.closed, 'reader.closed should reject'));
   1536 }, 'ReadableStream with byte source: read(view) with Uint16Array on close()-d stream with 1 byte enqueue()-d must ' +
   1537   'fail');
   1538 
   1539 promise_test(t => {
   1540  let controller;
   1541 
   1542  const stream = new ReadableStream({
   1543    start(c) {
   1544      const view = new Uint8Array(1);
   1545      view[0] = 0xff;
   1546      c.enqueue(view);
   1547 
   1548      controller = c;
   1549    },
   1550    pull: t.unreached_func('pull() should not be called'),
   1551    type: 'bytes'
   1552  });
   1553 
   1554  const reader = stream.getReader({ mode: 'byob' });
   1555 
   1556  const readPromise = reader.read(new Uint16Array(1));
   1557 
   1558  assert_throws_js(TypeError, () => controller.close(), 'controller.close() must throw');
   1559 
   1560  return promise_rejects_js(t, TypeError, readPromise, 'read(view) must fail')
   1561      .then(() => promise_rejects_js(t, TypeError, reader.closed, 'reader.closed must reject'));
   1562 }, 'ReadableStream with byte source: A stream must be errored if close()-d before fulfilling read(view) with ' +
   1563   'Uint16Array');
   1564 
   1565 test(() => {
   1566  let controller;
   1567 
   1568  new ReadableStream({
   1569    start(c) {
   1570      controller = c;
   1571    },
   1572    type: 'bytes'
   1573  });
   1574 
   1575  // Enqueue a chunk so that the stream doesn't get closed. This is to check duplicate close() calls are rejected
   1576  // even if the stream has not yet entered the closed state.
   1577  const view = new Uint8Array(1);
   1578  controller.enqueue(view);
   1579  controller.close();
   1580 
   1581  assert_throws_js(TypeError, () => controller.close(), 'controller.close() must throw');
   1582 }, 'ReadableStream with byte source: Throw if close()-ed more than once');
   1583 
   1584 test(() => {
   1585  let controller;
   1586 
   1587  new ReadableStream({
   1588    start(c) {
   1589      controller = c;
   1590    },
   1591    type: 'bytes'
   1592  });
   1593 
   1594  // Enqueue a chunk so that the stream doesn't get closed. This is to check enqueue() after close() is  rejected
   1595  // even if the stream has not yet entered the closed state.
   1596  const view = new Uint8Array(1);
   1597  controller.enqueue(view);
   1598  controller.close();
   1599 
   1600  assert_throws_js(TypeError, () => controller.enqueue(view), 'controller.close() must throw');
   1601 }, 'ReadableStream with byte source: Throw on enqueue() after close()');
   1602 
   1603 promise_test(() => {
   1604  let controller;
   1605  let byobRequest;
   1606  let viewInfo;
   1607 
   1608  const stream = new ReadableStream({
   1609    start(c) {
   1610      controller = c;
   1611    },
   1612    pull() {
   1613      byobRequest = controller.byobRequest;
   1614      const view = controller.byobRequest.view;
   1615      viewInfo = extractViewInfo(view);
   1616 
   1617      view[15] = 0x01;
   1618      controller.byobRequest.respond(16);
   1619      controller.close();
   1620    },
   1621    type: 'bytes'
   1622  });
   1623 
   1624  const reader = stream.getReader({ mode: 'byob' });
   1625 
   1626  return reader.read(new Uint8Array(16)).then(result => {
   1627    assert_false(result.done);
   1628 
   1629    const view = result.value;
   1630    assert_equals(view.byteOffset, 0);
   1631    assert_equals(view.byteLength, 16);
   1632    assert_equals(view[15], 0x01);
   1633 
   1634    return reader.read(new Uint8Array(16));
   1635  }).then(result => {
   1636    assert_true(result.done);
   1637 
   1638    const view = result.value;
   1639    assert_equals(view.byteOffset, 0);
   1640    assert_equals(view.byteLength, 0);
   1641 
   1642    assert_not_equals(byobRequest, null, 'byobRequest must not be null');
   1643    assert_equals(viewInfo.constructor, Uint8Array, 'view.constructor should be Uint8Array');
   1644    assert_equals(viewInfo.bufferByteLength, 16, 'view.buffer.byteLength should be 16');
   1645    assert_equals(viewInfo.byteOffset, 0, 'view.byteOffset should be 0');
   1646    assert_equals(viewInfo.byteLength, 16, 'view.byteLength should be 16');
   1647  });
   1648 }, 'ReadableStream with byte source: read(view), then respond() and close() in pull()');
   1649 
   1650 promise_test(() => {
   1651  let pullCount = 0;
   1652 
   1653  let controller;
   1654  const viewInfos = [];
   1655  const viewInfosAfterRespond = [];
   1656 
   1657  const stream = new ReadableStream({
   1658    start(c) {
   1659      controller = c;
   1660    },
   1661    pull() {
   1662      if (controller.byobRequest === null) {
   1663        return;
   1664      }
   1665 
   1666      for (let i = 0; i < 4; ++i) {
   1667        const view = controller.byobRequest.view;
   1668        viewInfos.push(extractViewInfo(view));
   1669 
   1670        view[0] = 0x01;
   1671        controller.byobRequest.respond(1);
   1672        viewInfosAfterRespond.push(extractViewInfo(view));
   1673      }
   1674 
   1675      ++pullCount;
   1676    },
   1677    type: 'bytes'
   1678  });
   1679 
   1680  const reader = stream.getReader({ mode: 'byob' });
   1681 
   1682  return reader.read(new Uint32Array(1)).then(result => {
   1683    assert_false(result.done, 'result.done');
   1684 
   1685    const view = result.value;
   1686    assert_equals(view.byteOffset, 0, 'result.value.byteOffset');
   1687    assert_equals(view.byteLength, 4, 'result.value.byteLength');
   1688    assert_equals(view[0], 0x01010101, 'result.value[0]');
   1689 
   1690    assert_equals(pullCount, 1, 'pull() should only be called once');
   1691 
   1692    for (let i = 0; i < 4; ++i) {
   1693      assert_equals(viewInfos[i].constructor, Uint8Array, 'view.constructor should be Uint8Array');
   1694      assert_equals(viewInfos[i].bufferByteLength, 4, 'view.buffer.byteLength should be 4');
   1695 
   1696      assert_equals(viewInfos[i].byteOffset, i, 'view.byteOffset should be i');
   1697      assert_equals(viewInfos[i].byteLength, 4 - i, 'view.byteLength should be 4 - i');
   1698 
   1699      assert_equals(viewInfosAfterRespond[i].bufferByteLength, 0, 'view.buffer should be transferred after respond()');
   1700    }
   1701  });
   1702 }, 'ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple respond() calls');
   1703 
   1704 promise_test(() => {
   1705  let pullCount = 0;
   1706 
   1707  let controller;
   1708  const viewInfos = [];
   1709  const viewInfosAfterEnqueue = [];
   1710 
   1711  const stream = new ReadableStream({
   1712    start(c) {
   1713      controller = c;
   1714    },
   1715    pull() {
   1716      if (controller.byobRequest === null) {
   1717        return;
   1718      }
   1719 
   1720      for (let i = 0; i < 4; ++i) {
   1721        const view = controller.byobRequest.view;
   1722        viewInfos.push(extractViewInfo(view));
   1723 
   1724        controller.enqueue(new Uint8Array([0x01]));
   1725        viewInfosAfterEnqueue.push(extractViewInfo(view));
   1726      }
   1727 
   1728      ++pullCount;
   1729    },
   1730    type: 'bytes'
   1731  });
   1732 
   1733  const reader = stream.getReader({ mode: 'byob' });
   1734 
   1735  return reader.read(new Uint32Array(1)).then(result => {
   1736    assert_false(result.done, 'result.done');
   1737 
   1738    const view = result.value;
   1739    assert_equals(view.byteOffset, 0, 'result.value.byteOffset');
   1740    assert_equals(view.byteLength, 4, 'result.value.byteLength');
   1741    assert_equals(view[0], 0x01010101, 'result.value[0]');
   1742 
   1743    assert_equals(pullCount, 1, 'pull() should only be called once');
   1744 
   1745    for (let i = 0; i < 4; ++i) {
   1746      assert_equals(viewInfos[i].constructor, Uint8Array, 'view.constructor should be Uint8Array');
   1747      assert_equals(viewInfos[i].bufferByteLength, 4, 'view.buffer.byteLength should be 4');
   1748 
   1749      assert_equals(viewInfos[i].byteOffset, i, 'view.byteOffset should be i');
   1750      assert_equals(viewInfos[i].byteLength, 4 - i, 'view.byteLength should be 4 - i');
   1751 
   1752      assert_equals(viewInfosAfterEnqueue[i].bufferByteLength, 0, 'view.buffer should be transferred after enqueue()');
   1753    }
   1754  });
   1755 }, 'ReadableStream with byte source: read(view) with Uint32Array, then fill it by multiple enqueue() calls');
   1756 
   1757 promise_test(() => {
   1758  let pullCount = 0;
   1759 
   1760  let controller;
   1761  let byobRequest;
   1762 
   1763  const stream = new ReadableStream({
   1764    start(c) {
   1765      controller = c;
   1766    },
   1767    pull() {
   1768      byobRequest = controller.byobRequest;
   1769 
   1770      ++pullCount;
   1771    },
   1772    type: 'bytes'
   1773  });
   1774 
   1775  const reader = stream.getReader();
   1776 
   1777  const p0 = reader.read().then(result => {
   1778    assert_equals(pullCount, 1);
   1779 
   1780    controller.enqueue(new Uint8Array(2));
   1781 
   1782    // Since the queue has data no less than HWM, no more pull.
   1783    assert_equals(pullCount, 1);
   1784 
   1785    assert_false(result.done);
   1786 
   1787    const view = result.value;
   1788    assert_equals(view.constructor, Uint8Array);
   1789    assert_equals(view.buffer.byteLength, 1);
   1790    assert_equals(view.byteOffset, 0);
   1791    assert_equals(view.byteLength, 1);
   1792  });
   1793 
   1794  assert_equals(pullCount, 0, 'No pull should have been made since the startPromise has not yet been handled');
   1795 
   1796  const p1 = reader.read().then(result => {
   1797    assert_equals(pullCount, 1);
   1798 
   1799    assert_false(result.done);
   1800 
   1801    const view = result.value;
   1802    assert_equals(view.constructor, Uint8Array);
   1803    assert_equals(view.buffer.byteLength, 2);
   1804    assert_equals(view.byteOffset, 0);
   1805    assert_equals(view.byteLength, 2);
   1806 
   1807    assert_equals(byobRequest, null, 'byobRequest must be null');
   1808  });
   1809 
   1810  assert_equals(pullCount, 0, 'No pull should have been made since the startPromise has not yet been handled');
   1811 
   1812  controller.enqueue(new Uint8Array(1));
   1813 
   1814  assert_equals(pullCount, 0, 'No pull should have been made since the startPromise has not yet been handled');
   1815 
   1816  return Promise.all([p0, p1]);
   1817 }, 'ReadableStream with byte source: read() twice, then enqueue() twice');
   1818 
   1819 promise_test(t => {
   1820  let controller;
   1821 
   1822  const stream = new ReadableStream({
   1823    start(c) {
   1824      controller = c;
   1825    },
   1826    pull: t.unreached_func('pull() should not be called'),
   1827    type: 'bytes'
   1828  });
   1829 
   1830  const reader = stream.getReader({ mode: 'byob' });
   1831 
   1832  const p0 = reader.read(new Uint8Array(16)).then(result => {
   1833    assert_true(result.done, '1st read: done');
   1834 
   1835    const view = result.value;
   1836    assert_equals(view.buffer.byteLength, 16, '1st read: buffer.byteLength');
   1837    assert_equals(view.byteOffset, 0, '1st read: byteOffset');
   1838    assert_equals(view.byteLength, 0, '1st read: byteLength');
   1839  });
   1840 
   1841  const p1 = reader.read(new Uint8Array(32)).then(result => {
   1842    assert_true(result.done, '2nd read: done');
   1843 
   1844    const view = result.value;
   1845    assert_equals(view.buffer.byteLength, 32, '2nd read: buffer.byteLength');
   1846    assert_equals(view.byteOffset, 0, '2nd read: byteOffset');
   1847    assert_equals(view.byteLength, 0, '2nd read: byteLength');
   1848  });
   1849 
   1850  controller.close();
   1851  controller.byobRequest.respond(0);
   1852 
   1853  return Promise.all([p0, p1]);
   1854 }, 'ReadableStream with byte source: Multiple read(view), close() and respond()');
   1855 
   1856 promise_test(t => {
   1857  let controller;
   1858 
   1859  const stream = new ReadableStream({
   1860    start(c) {
   1861      controller = c;
   1862    },
   1863    pull: t.unreached_func('pull() should not be called'),
   1864    type: 'bytes'
   1865  });
   1866 
   1867  const reader = stream.getReader({ mode: 'byob' });
   1868 
   1869  const p0 = reader.read(new Uint8Array(16)).then(result => {
   1870    assert_false(result.done, '1st read: done');
   1871 
   1872    const view = result.value;
   1873    assert_equals(view.buffer.byteLength, 16, '1st read: buffer.byteLength');
   1874    assert_equals(view.byteOffset, 0, '1st read: byteOffset');
   1875    assert_equals(view.byteLength, 16, '1st read: byteLength');
   1876  });
   1877 
   1878  const p1 = reader.read(new Uint8Array(16)).then(result => {
   1879    assert_false(result.done, '2nd read: done');
   1880 
   1881    const view = result.value;
   1882    assert_equals(view.buffer.byteLength, 16, '2nd read: buffer.byteLength');
   1883    assert_equals(view.byteOffset, 0, '2nd read: byteOffset');
   1884    assert_equals(view.byteLength, 8, '2nd read: byteLength');
   1885  });
   1886 
   1887  controller.enqueue(new Uint8Array(24));
   1888 
   1889  return Promise.all([p0, p1]);
   1890 }, 'ReadableStream with byte source: Multiple read(view), big enqueue()');
   1891 
   1892 promise_test(t => {
   1893  let controller;
   1894 
   1895  const stream = new ReadableStream({
   1896    start(c) {
   1897      controller = c;
   1898    },
   1899    pull: t.unreached_func('pull() should not be called'),
   1900    type: 'bytes'
   1901  });
   1902 
   1903  const reader = stream.getReader({ mode: 'byob' });
   1904 
   1905  let bytesRead = 0;
   1906 
   1907  function pump() {
   1908    return reader.read(new Uint8Array(7)).then(result => {
   1909      if (result.done) {
   1910        assert_equals(bytesRead, 1024);
   1911        return undefined;
   1912      }
   1913 
   1914      bytesRead += result.value.byteLength;
   1915 
   1916      return pump();
   1917    });
   1918  }
   1919  const promise = pump();
   1920 
   1921  controller.enqueue(new Uint8Array(512));
   1922  controller.enqueue(new Uint8Array(512));
   1923  controller.close();
   1924 
   1925  return promise;
   1926 }, 'ReadableStream with byte source: Multiple read(view) and multiple enqueue()');
   1927 
   1928 promise_test(t => {
   1929  let pullCalled = false;
   1930  const stream = new ReadableStream({
   1931    pull(controller) {
   1932      pullCalled = true;
   1933    },
   1934    type: 'bytes'
   1935  });
   1936 
   1937  const reader = stream.getReader({ mode: 'byob' });
   1938 
   1939  return promise_rejects_js(t, TypeError, reader.read(), 'read() must fail')
   1940      .then(() => assert_false(pullCalled, 'pull() must not have been called'));
   1941 }, 'ReadableStream with byte source: read(view) with passing undefined as view must fail');
   1942 
   1943 promise_test(t => {
   1944  const stream = new ReadableStream({
   1945    type: 'bytes'
   1946  });
   1947 
   1948  const reader = stream.getReader({ mode: 'byob' });
   1949 
   1950  return promise_rejects_js(t, TypeError, reader.read({}), 'read(view) must fail');
   1951 }, 'ReadableStream with byte source: read(view) with passing an empty object as view must fail');
   1952 
   1953 promise_test(t => {
   1954  const stream = new ReadableStream({
   1955    type: 'bytes'
   1956  });
   1957 
   1958  const reader = stream.getReader({ mode: 'byob' });
   1959 
   1960  return promise_rejects_js(t, TypeError,
   1961                         reader.read({ buffer: new ArrayBuffer(10), byteOffset: 0, byteLength: 10 }),
   1962                         'read(view) must fail');
   1963 }, 'ReadableStream with byte source: Even read(view) with passing ArrayBufferView like object as view must fail');
   1964 
   1965 promise_test(t => {
   1966  const stream = new ReadableStream({
   1967    start(c) {
   1968      c.error(error1);
   1969    },
   1970    pull: t.unreached_func('pull() should not be called'),
   1971    type: 'bytes'
   1972  });
   1973 
   1974  const reader = stream.getReader();
   1975 
   1976  return promise_rejects_exactly(t, error1, reader.read(), 'read() must fail');
   1977 }, 'ReadableStream with byte source: read() on an errored stream');
   1978 
   1979 promise_test(t => {
   1980  let controller;
   1981 
   1982  const stream = new ReadableStream({
   1983    start(c) {
   1984      controller = c;
   1985    },
   1986    type: 'bytes'
   1987  });
   1988 
   1989  const reader = stream.getReader();
   1990 
   1991  const promise = promise_rejects_exactly(t, error1, reader.read(), 'read() must fail');
   1992 
   1993  controller.error(error1);
   1994 
   1995  return promise;
   1996 }, 'ReadableStream with byte source: read(), then error()');
   1997 
   1998 promise_test(t => {
   1999  const stream = new ReadableStream({
   2000    start(c) {
   2001      c.error(error1);
   2002    },
   2003    pull: t.unreached_func('pull() should not be called'),
   2004    type: 'bytes'
   2005  });
   2006 
   2007  const reader = stream.getReader({ mode: 'byob' });
   2008 
   2009  return promise_rejects_exactly(t, error1, reader.read(new Uint8Array(1)), 'read() must fail');
   2010 }, 'ReadableStream with byte source: read(view) on an errored stream');
   2011 
   2012 promise_test(t => {
   2013  let controller;
   2014 
   2015  const stream = new ReadableStream({
   2016    start(c) {
   2017      controller = c;
   2018    },
   2019    type: 'bytes'
   2020  });
   2021 
   2022  const reader = stream.getReader({ mode: 'byob' });
   2023 
   2024  const promise = promise_rejects_exactly(t, error1, reader.read(new Uint8Array(1)), 'read() must fail');
   2025 
   2026  controller.error(error1);
   2027 
   2028  return promise;
   2029 }, 'ReadableStream with byte source: read(view), then error()');
   2030 
   2031 promise_test(t => {
   2032  let controller;
   2033  let byobRequest;
   2034 
   2035  const testError = new TypeError('foo');
   2036 
   2037  const stream = new ReadableStream({
   2038    start(c) {
   2039      controller = c;
   2040    },
   2041    pull() {
   2042      byobRequest = controller.byobRequest;
   2043      throw testError;
   2044    },
   2045    type: 'bytes'
   2046  });
   2047 
   2048  const reader = stream.getReader();
   2049 
   2050  const promise = promise_rejects_exactly(t, testError, reader.read(), 'read() must fail');
   2051  return promise_rejects_exactly(t, testError, promise.then(() => reader.closed))
   2052      .then(() => assert_equals(byobRequest, null, 'byobRequest must be null'));
   2053 }, 'ReadableStream with byte source: Throwing in pull function must error the stream');
   2054 
   2055 promise_test(t => {
   2056  let byobRequest;
   2057 
   2058  const stream = new ReadableStream({
   2059    pull(controller) {
   2060      byobRequest = controller.byobRequest;
   2061      controller.error(error1);
   2062      throw new TypeError('foo');
   2063    },
   2064    type: 'bytes'
   2065  });
   2066 
   2067  const reader = stream.getReader();
   2068 
   2069  return promise_rejects_exactly(t, error1, reader.read(), 'read() must fail')
   2070      .then(() => promise_rejects_exactly(t, error1, reader.closed, 'closed must fail'))
   2071      .then(() => assert_equals(byobRequest, null, 'byobRequest must be null'));
   2072 }, 'ReadableStream with byte source: Throwing in pull in response to read() must be ignored if the stream is ' +
   2073   'errored in it');
   2074 
   2075 promise_test(t => {
   2076  let byobRequest;
   2077 
   2078  const testError = new TypeError('foo');
   2079 
   2080  const stream = new ReadableStream({
   2081    pull(controller) {
   2082      byobRequest = controller.byobRequest;
   2083      throw testError;
   2084    },
   2085    type: 'bytes'
   2086  });
   2087 
   2088  const reader = stream.getReader({ mode: 'byob' });
   2089 
   2090  return promise_rejects_exactly(t, testError, reader.read(new Uint8Array(1)), 'read(view) must fail')
   2091      .then(() => promise_rejects_exactly(t, testError, reader.closed, 'reader.closed must reject'))
   2092      .then(() => assert_not_equals(byobRequest, null, 'byobRequest must not be null'));
   2093 }, 'ReadableStream with byte source: Throwing in pull in response to read(view) function must error the stream');
   2094 
   2095 promise_test(t => {
   2096  let byobRequest;
   2097 
   2098  const stream = new ReadableStream({
   2099    pull(controller) {
   2100      byobRequest = controller.byobRequest;
   2101      controller.error(error1);
   2102      throw new TypeError('foo');
   2103    },
   2104    type: 'bytes'
   2105  });
   2106 
   2107  const reader = stream.getReader({ mode: 'byob' });
   2108 
   2109  return promise_rejects_exactly(t, error1, reader.read(new Uint8Array(1)), 'read(view) must fail')
   2110      .then(() => promise_rejects_exactly(t, error1, reader.closed, 'closed must fail'))
   2111      .then(() => assert_not_equals(byobRequest, null, 'byobRequest must not be null'));
   2112 }, 'ReadableStream with byte source: Throwing in pull in response to read(view) must be ignored if the stream is ' +
   2113   'errored in it');
   2114 
   2115 promise_test(() => {
   2116  let byobRequest;
   2117  const rs = new ReadableStream({
   2118    pull(controller) {
   2119      byobRequest = controller.byobRequest;
   2120      byobRequest.respond(4);
   2121    },
   2122    type: 'bytes'
   2123  });
   2124  const reader = rs.getReader({ mode: 'byob' });
   2125  const view = new Uint8Array(16);
   2126  return reader.read(view).then(() => {
   2127    assert_throws_js(TypeError, () => byobRequest.respond(4), 'respond() should throw a TypeError');
   2128  });
   2129 }, 'calling respond() twice on the same byobRequest should throw');
   2130 
   2131 promise_test(() => {
   2132  let byobRequest;
   2133  const newView = () => new Uint8Array(16);
   2134  const rs = new ReadableStream({
   2135    pull(controller) {
   2136      byobRequest = controller.byobRequest;
   2137      byobRequest.respondWithNewView(newView());
   2138    },
   2139    type: 'bytes'
   2140  });
   2141  const reader = rs.getReader({ mode: 'byob' });
   2142  return reader.read(newView()).then(() => {
   2143    assert_throws_js(TypeError, () => byobRequest.respondWithNewView(newView()),
   2144                     'respondWithNewView() should throw a TypeError');
   2145  });
   2146 }, 'calling respondWithNewView() twice on the same byobRequest should throw');
   2147 
   2148 promise_test(() => {
   2149  let controller;
   2150  let byobRequest;
   2151  let resolvePullCalledPromise;
   2152  const pullCalledPromise = new Promise(resolve => {
   2153    resolvePullCalledPromise = resolve;
   2154  });
   2155  let resolvePull;
   2156  const rs = new ReadableStream({
   2157    start(c) {
   2158      controller = c;
   2159    },
   2160    pull(c) {
   2161      byobRequest = c.byobRequest;
   2162      resolvePullCalledPromise();
   2163      return new Promise(resolve => {
   2164        resolvePull = resolve;
   2165      });
   2166    },
   2167    type: 'bytes'
   2168  });
   2169  const reader = rs.getReader({ mode: 'byob' });
   2170  const readPromise = reader.read(new Uint8Array(16));
   2171  return pullCalledPromise.then(() => {
   2172    controller.close();
   2173    byobRequest.respond(0);
   2174    resolvePull();
   2175    return readPromise.then(() => {
   2176      assert_throws_js(TypeError, () => byobRequest.respond(0), 'respond() should throw');
   2177    });
   2178  });
   2179 }, 'calling respond(0) twice on the same byobRequest should throw even when closed');
   2180 
   2181 promise_test(() => {
   2182  let controller;
   2183  let byobRequest;
   2184  let resolvePullCalledPromise;
   2185  const pullCalledPromise = new Promise(resolve => {
   2186    resolvePullCalledPromise = resolve;
   2187  });
   2188  let resolvePull;
   2189  const rs = new ReadableStream({
   2190    start(c) {
   2191      controller = c;
   2192    },
   2193    pull(c) {
   2194      byobRequest = c.byobRequest;
   2195      resolvePullCalledPromise();
   2196      return new Promise(resolve => {
   2197        resolvePull = resolve;
   2198      });
   2199    },
   2200    type: 'bytes'
   2201  });
   2202  const reader = rs.getReader({ mode: 'byob' });
   2203  const readPromise = reader.read(new Uint8Array(16));
   2204  return pullCalledPromise.then(() => {
   2205    const cancelPromise = reader.cancel('meh');
   2206    assert_throws_js(TypeError, () => byobRequest.respond(0), 'respond() should throw');
   2207    resolvePull();
   2208    return Promise.all([readPromise, cancelPromise]);
   2209  });
   2210 }, 'calling respond() should throw when canceled');
   2211 
   2212 promise_test(async t => {
   2213  let resolvePullCalledPromise;
   2214  const pullCalledPromise = new Promise(resolve => {
   2215    resolvePullCalledPromise = resolve;
   2216  });
   2217  let resolvePull;
   2218  const rs = new ReadableStream({
   2219    pull() {
   2220      resolvePullCalledPromise();
   2221      return new Promise(resolve => {
   2222        resolvePull = resolve;
   2223      });
   2224    },
   2225    type: 'bytes'
   2226  });
   2227  const reader = rs.getReader({ mode: 'byob' });
   2228  const read = reader.read(new Uint8Array(16));
   2229  await pullCalledPromise;
   2230  resolvePull();
   2231  await delay(0);
   2232  reader.releaseLock();
   2233  await promise_rejects_js(t, TypeError, read, 'pending read should reject');
   2234 }, 'pull() resolving should not resolve read()');
   2235 
   2236 promise_test(() => {
   2237  // Tests https://github.com/whatwg/streams/issues/686
   2238 
   2239  let controller;
   2240  const rs = new ReadableStream({
   2241    autoAllocateChunkSize: 128,
   2242    start(c) {
   2243      controller = c;
   2244    },
   2245    type: 'bytes'
   2246  });
   2247 
   2248  const readPromise = rs.getReader().read();
   2249 
   2250  const br = controller.byobRequest;
   2251  controller.close();
   2252 
   2253  br.respond(0);
   2254 
   2255  return readPromise;
   2256 }, 'ReadableStream with byte source: default reader + autoAllocateChunkSize + byobRequest interaction');
   2257 
   2258 test(() => {
   2259  assert_throws_js(TypeError, () => new ReadableStream({ autoAllocateChunkSize: 0, type: 'bytes' }),
   2260      'controller cannot be setup with autoAllocateChunkSize = 0');
   2261 }, 'ReadableStream with byte source: autoAllocateChunkSize cannot be 0');
   2262 
   2263 test(() => {
   2264  const ReadableStreamBYOBReader = new ReadableStream({ type: 'bytes' }).getReader({ mode: 'byob' }).constructor;
   2265  const stream = new ReadableStream({ type: 'bytes' });
   2266  new ReadableStreamBYOBReader(stream);
   2267 }, 'ReadableStreamBYOBReader can be constructed directly');
   2268 
   2269 test(() => {
   2270  const ReadableStreamBYOBReader = new ReadableStream({ type: 'bytes' }).getReader({ mode: 'byob' }).constructor;
   2271  assert_throws_js(TypeError, () => new ReadableStreamBYOBReader({}), 'constructor must throw');
   2272 }, 'ReadableStreamBYOBReader constructor requires a ReadableStream argument');
   2273 
   2274 test(() => {
   2275  const ReadableStreamBYOBReader = new ReadableStream({ type: 'bytes' }).getReader({ mode: 'byob' }).constructor;
   2276  const stream = new ReadableStream({ type: 'bytes' });
   2277  stream.getReader();
   2278  assert_throws_js(TypeError, () => new ReadableStreamBYOBReader(stream), 'constructor must throw');
   2279 }, 'ReadableStreamBYOBReader constructor requires an unlocked ReadableStream');
   2280 
   2281 test(() => {
   2282  const ReadableStreamBYOBReader = new ReadableStream({ type: 'bytes' }).getReader({ mode: 'byob' }).constructor;
   2283  const stream = new ReadableStream();
   2284  assert_throws_js(TypeError, () => new ReadableStreamBYOBReader(stream), 'constructor must throw');
   2285 }, 'ReadableStreamBYOBReader constructor requires a ReadableStream with type "bytes"');
   2286 
   2287 test(() => {
   2288  assert_throws_js(RangeError, () => new ReadableStream({ type: 'bytes' }, {
   2289    size() {
   2290      return 1;
   2291    }
   2292  }), 'constructor should throw for size function');
   2293 
   2294  assert_throws_js(RangeError,
   2295                   () => new ReadableStream({ type: 'bytes' }, new CountQueuingStrategy({ highWaterMark: 1 })),
   2296                   'constructor should throw when strategy is CountQueuingStrategy');
   2297 
   2298  assert_throws_js(RangeError,
   2299                   () => new ReadableStream({ type: 'bytes' }, new ByteLengthQueuingStrategy({ highWaterMark: 512 })),
   2300                   'constructor should throw when strategy is ByteLengthQueuingStrategy');
   2301 
   2302  class HasSizeMethod {
   2303    size() {}
   2304 }
   2305 
   2306  assert_throws_js(RangeError, () => new ReadableStream({ type: 'bytes' }, new HasSizeMethod()),
   2307                   'constructor should throw when size on the prototype chain');
   2308 }, 'ReadableStream constructor should not accept a strategy with a size defined if type is "bytes"');
   2309 
   2310 promise_test(async t => {
   2311  const stream = new ReadableStream({
   2312    pull: t.step_func(c => {
   2313      const view = new Uint8Array(c.byobRequest.view.buffer, 0, 1);
   2314      view[0] = 1;
   2315 
   2316      c.byobRequest.respondWithNewView(view);
   2317    }),
   2318    type: 'bytes'
   2319  });
   2320  const reader = stream.getReader({ mode: 'byob' });
   2321 
   2322  const result = await reader.read(new Uint8Array([4, 5, 6]));
   2323  assert_false(result.done, 'result.done');
   2324 
   2325  const view = result.value;
   2326  assert_equals(view.byteOffset, 0, 'result.value.byteOffset');
   2327  assert_equals(view.byteLength, 1, 'result.value.byteLength');
   2328  assert_equals(view[0], 1, 'result.value[0]');
   2329  assert_equals(view.buffer.byteLength, 3, 'result.value.buffer.byteLength');
   2330  assert_array_equals([...new Uint8Array(view.buffer)], [1, 5, 6], 'result.value.buffer');
   2331 }, 'ReadableStream with byte source: respondWithNewView() with a smaller view');
   2332 
   2333 promise_test(async t => {
   2334  const stream = new ReadableStream({
   2335    pull: t.step_func(c => {
   2336      const view = new Uint8Array(c.byobRequest.view.buffer, 0, 0);
   2337 
   2338      c.close();
   2339 
   2340      c.byobRequest.respondWithNewView(view);
   2341    }),
   2342    type: 'bytes'
   2343  });
   2344  const reader = stream.getReader({ mode: 'byob' });
   2345 
   2346  const result = await reader.read(new Uint8Array([4, 5, 6]));
   2347  assert_true(result.done, 'result.done');
   2348 
   2349  const view = result.value;
   2350  assert_equals(view.byteOffset, 0, 'result.value.byteOffset');
   2351  assert_equals(view.byteLength, 0, 'result.value.byteLength');
   2352  assert_equals(view.buffer.byteLength, 3, 'result.value.buffer.byteLength');
   2353  assert_array_equals([...new Uint8Array(view.buffer)], [4, 5, 6], 'result.value.buffer');
   2354 }, 'ReadableStream with byte source: respondWithNewView() with a zero-length view (in the closed state)');
   2355 
   2356 promise_test(async t => {
   2357  let controller;
   2358  let resolvePullCalledPromise;
   2359  const pullCalledPromise = new Promise(resolve => {
   2360    resolvePullCalledPromise = resolve;
   2361  });
   2362  const stream = new ReadableStream({
   2363    start: t.step_func((c) => {
   2364      controller = c;
   2365    }),
   2366    pull: t.step_func(() => {
   2367      resolvePullCalledPromise();
   2368    }),
   2369    type: 'bytes'
   2370  });
   2371 
   2372  const reader = stream.getReader({ mode: 'byob' });
   2373  const readPromise = reader.read(new Uint8Array([4, 5, 6]));
   2374  await pullCalledPromise;
   2375 
   2376  // Transfer the original BYOB request's buffer, and respond with a new view on that buffer
   2377  const transferredView = transferArrayBufferView(controller.byobRequest.view);
   2378  const newView = transferredView.subarray(0, 1);
   2379  newView[0] = 42;
   2380 
   2381  controller.byobRequest.respondWithNewView(newView);
   2382 
   2383  const result = await readPromise;
   2384  assert_false(result.done, 'result.done');
   2385 
   2386  const view = result.value;
   2387  assert_equals(view.byteOffset, 0, 'result.value.byteOffset');
   2388  assert_equals(view.byteLength, 1, 'result.value.byteLength');
   2389  assert_equals(view[0], 42, 'result.value[0]');
   2390  assert_equals(view.buffer.byteLength, 3, 'result.value.buffer.byteLength');
   2391  assert_array_equals([...new Uint8Array(view.buffer)], [42, 5, 6], 'result.value.buffer');
   2392 
   2393 }, 'ReadableStream with byte source: respondWithNewView() with a transferred non-zero-length view ' +
   2394   '(in the readable state)');
   2395 
   2396 promise_test(async t => {
   2397  let controller;
   2398  let resolvePullCalledPromise;
   2399  const pullCalledPromise = new Promise(resolve => {
   2400    resolvePullCalledPromise = resolve;
   2401  });
   2402  const stream = new ReadableStream({
   2403    start: t.step_func((c) => {
   2404      controller = c;
   2405    }),
   2406    pull: t.step_func(() => {
   2407      resolvePullCalledPromise();
   2408    }),
   2409    type: 'bytes'
   2410  });
   2411 
   2412  const reader = stream.getReader({ mode: 'byob' });
   2413  const readPromise = reader.read(new Uint8Array([4, 5, 6]));
   2414  await pullCalledPromise;
   2415 
   2416  // Transfer the original BYOB request's buffer, and respond with an empty view on that buffer
   2417  const transferredView = transferArrayBufferView(controller.byobRequest.view);
   2418  const newView = transferredView.subarray(0, 0);
   2419 
   2420  controller.close();
   2421  controller.byobRequest.respondWithNewView(newView);
   2422 
   2423  const result = await readPromise;
   2424  assert_true(result.done, 'result.done');
   2425 
   2426  const view = result.value;
   2427  assert_equals(view.byteOffset, 0, 'result.value.byteOffset');
   2428  assert_equals(view.byteLength, 0, 'result.value.byteLength');
   2429  assert_equals(view.buffer.byteLength, 3, 'result.value.buffer.byteLength');
   2430  assert_array_equals([...new Uint8Array(view.buffer)], [4, 5, 6], 'result.value.buffer');
   2431 
   2432 }, 'ReadableStream with byte source: respondWithNewView() with a transferred zero-length view ' +
   2433   '(in the closed state)');
   2434 
   2435 promise_test(async t => {
   2436  let controller;
   2437  let pullCount = 0;
   2438  const rs = new ReadableStream({
   2439    type: 'bytes',
   2440    autoAllocateChunkSize: 10,
   2441    start: t.step_func((c) => {
   2442      controller = c;
   2443    }),
   2444    pull: t.step_func(() => {
   2445      ++pullCount;
   2446    })
   2447  });
   2448 
   2449  await flushAsyncEvents();
   2450  assert_equals(pullCount, 0, 'pull() must not have been invoked yet');
   2451 
   2452  const reader1 = rs.getReader();
   2453  const read1 = reader1.read();
   2454  assert_equals(pullCount, 1, 'pull() must have been invoked once');
   2455  const byobRequest1 = controller.byobRequest;
   2456  assert_equals(byobRequest1.view.byteLength, 10, 'first byobRequest.view.byteLength');
   2457 
   2458  // enqueue() must discard the auto-allocated BYOB request
   2459  controller.enqueue(new Uint8Array([1, 2, 3]));
   2460  assert_equals(byobRequest1.view, null, 'first byobRequest must be invalidated after enqueue()');
   2461 
   2462  const result1 = await read1;
   2463  assert_false(result1.done, 'first result.done');
   2464  const view1 = result1.value;
   2465  assert_equals(view1.byteOffset, 0, 'first result.value.byteOffset');
   2466  assert_equals(view1.byteLength, 3, 'first result.value.byteLength');
   2467  assert_array_equals([...new Uint8Array(view1.buffer)], [1, 2, 3], 'first result.value.buffer');
   2468 
   2469  reader1.releaseLock();
   2470 
   2471  // read(view) should work after discarding the auto-allocated BYOB request
   2472  const reader2 = rs.getReader({ mode: 'byob' });
   2473  const read2 = reader2.read(new Uint8Array([4, 5, 6]));
   2474  assert_equals(pullCount, 2, 'pull() must have been invoked twice');
   2475  const byobRequest2 = controller.byobRequest;
   2476  assert_equals(byobRequest2.view.byteOffset, 0, 'second byobRequest.view.byteOffset');
   2477  assert_equals(byobRequest2.view.byteLength, 3, 'second byobRequest.view.byteLength');
   2478  assert_array_equals([...new Uint8Array(byobRequest2.view.buffer)], [4, 5, 6], 'second byobRequest.view.buffer');
   2479 
   2480  byobRequest2.respond(3);
   2481  assert_equals(byobRequest2.view, null, 'second byobRequest must be invalidated after respond()');
   2482 
   2483  const result2 = await read2;
   2484  assert_false(result2.done, 'second result.done');
   2485  const view2 = result2.value;
   2486  assert_equals(view2.byteOffset, 0, 'second result.value.byteOffset');
   2487  assert_equals(view2.byteLength, 3, 'second result.value.byteLength');
   2488  assert_array_equals([...new Uint8Array(view2.buffer)], [4, 5, 6], 'second result.value.buffer');
   2489 
   2490  reader2.releaseLock();
   2491  assert_equals(pullCount, 2, 'pull() must only have been invoked twice');
   2492 }, 'ReadableStream with byte source: enqueue() discards auto-allocated BYOB request');
   2493 
   2494 promise_test(async t => {
   2495  let controller;
   2496  const rs = new ReadableStream({
   2497    type: 'bytes',
   2498    start: t.step_func((c) => {
   2499      controller = c;
   2500    })
   2501  });
   2502  await flushAsyncEvents();
   2503 
   2504  const reader1 = rs.getReader({ mode: 'byob' });
   2505  const read1 = reader1.read(new Uint8Array([1, 2, 3]));
   2506  const byobRequest1 = controller.byobRequest;
   2507  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
   2508  assert_typed_array_equals(byobRequest1.view, new Uint8Array([1, 2, 3]), 'first byobRequest.view');
   2509 
   2510  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
   2511  reader1.releaseLock();
   2512  const reader2 = rs.getReader({ mode: 'byob' });
   2513  const read2 = reader2.read(new Uint8Array([4, 5, 6]));
   2514  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
   2515  assert_equals(controller.byobRequest, byobRequest1, 'byobRequest should be unchanged');
   2516  assert_array_equals([...new Uint8Array(byobRequest1.view.buffer)], [1, 2, 3], 'byobRequest.view.buffer should be unchanged');
   2517  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
   2518 
   2519  // respond() should fulfill the *second* read() request
   2520  byobRequest1.view[0] = 11;
   2521  byobRequest1.respond(1);
   2522  const byobRequest2 = controller.byobRequest;
   2523  assert_equals(byobRequest2, null, 'byobRequest should be null after respond()');
   2524 
   2525  const result2 = await read2;
   2526  assert_false(result2.done, 'second result.done');
   2527  assert_typed_array_equals(result2.value, new Uint8Array([11, 5, 6]).subarray(0, 1), 'second result.value');
   2528 
   2529 }, 'ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respond()');
   2530 
   2531 promise_test(async t => {
   2532  let controller;
   2533  const rs = new ReadableStream({
   2534    type: 'bytes',
   2535    start: t.step_func((c) => {
   2536      controller = c;
   2537    })
   2538  });
   2539  await flushAsyncEvents();
   2540 
   2541  const reader1 = rs.getReader({ mode: 'byob' });
   2542  const read1 = reader1.read(new Uint8Array([1, 2, 3]));
   2543  const byobRequest1 = controller.byobRequest;
   2544  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
   2545  assert_typed_array_equals(byobRequest1.view, new Uint8Array([1, 2, 3]), 'first byobRequest.view');
   2546 
   2547  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
   2548  reader1.releaseLock();
   2549  const reader2 = rs.getReader({ mode: 'byob' });
   2550  const read2 = reader2.read(new Uint16Array(1));
   2551  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
   2552  assert_equals(controller.byobRequest, byobRequest1, 'byobRequest should be unchanged');
   2553  assert_array_equals([...new Uint8Array(byobRequest1.view.buffer)], [1, 2, 3], 'byobRequest.view.buffer should be unchanged');
   2554  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
   2555 
   2556  // respond(1) should partially fill the second read(), but not yet fulfill it
   2557  byobRequest1.view[0] = 0x11;
   2558  byobRequest1.respond(1);
   2559 
   2560  // second BYOB request should use remaining buffer from the second read()
   2561  const byobRequest2 = controller.byobRequest;
   2562  assert_not_equals(byobRequest2, null, 'second byobRequest should exist');
   2563  assert_typed_array_equals(byobRequest2.view, new Uint8Array([0x11, 0]).subarray(1, 2), 'second byobRequest.view');
   2564 
   2565  // second respond(1) should fill the read request and fulfill it
   2566  byobRequest2.view[0] = 0x22;
   2567  byobRequest2.respond(1);
   2568  const result2 = await read2;
   2569  assert_false(result2.done, 'second result.done');
   2570  const view2 = result2.value;
   2571  assert_equals(view2.byteOffset, 0, 'second result.value.byteOffset');
   2572  assert_equals(view2.byteLength, 2, 'second result.value.byteLength');
   2573  const dataView2 = new DataView(view2.buffer, view2.byteOffset, view2.byteLength);
   2574  assert_equals(dataView2.getUint16(0), 0x1122, 'second result.value[0]');
   2575 
   2576 }, 'ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with ' +
   2577   '1 element Uint16Array, respond(1)');
   2578 
   2579 promise_test(async t => {
   2580  let controller;
   2581  const rs = new ReadableStream({
   2582    type: 'bytes',
   2583    start: t.step_func((c) => {
   2584      controller = c;
   2585    })
   2586  });
   2587  await flushAsyncEvents();
   2588 
   2589  const reader1 = rs.getReader({ mode: 'byob' });
   2590  const read1 = reader1.read(new Uint8Array([1, 2, 3]));
   2591  const byobRequest1 = controller.byobRequest;
   2592  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
   2593  assert_typed_array_equals(byobRequest1.view, new Uint8Array([1, 2, 3]), 'first byobRequest.view');
   2594 
   2595  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
   2596  reader1.releaseLock();
   2597  const reader2 = rs.getReader({ mode: 'byob' });
   2598  const read2 = reader2.read(new Uint8Array([4, 5]));
   2599  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
   2600  assert_equals(controller.byobRequest, byobRequest1, 'byobRequest should be unchanged');
   2601  assert_array_equals([...new Uint8Array(byobRequest1.view.buffer)], [1, 2, 3], 'byobRequest.view.buffer should be unchanged');
   2602  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
   2603 
   2604  // respond(3) should fulfill the second read(), and put 1 remaining byte in the queue
   2605  byobRequest1.view[0] = 6;
   2606  byobRequest1.view[1] = 7;
   2607  byobRequest1.view[2] = 8;
   2608  byobRequest1.respond(3);
   2609  const byobRequest2 = controller.byobRequest;
   2610  assert_equals(byobRequest2, null, 'byobRequest should be null after respond()');
   2611 
   2612  const result2 = await read2;
   2613  assert_false(result2.done, 'second result.done');
   2614  assert_typed_array_equals(result2.value, new Uint8Array([6, 7]), 'second result.value');
   2615 
   2616  // third read() should fulfill with the remaining byte
   2617  const result3 = await reader2.read(new Uint8Array([0, 0, 0]));
   2618  assert_false(result3.done, 'third result.done');
   2619  assert_typed_array_equals(result3.value, new Uint8Array([8, 0, 0]).subarray(0, 1), 'third result.value');
   2620 
   2621 }, 'ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader with ' +
   2622   '2 element Uint8Array, respond(3)');
   2623 
   2624 promise_test(async t => {
   2625  let controller;
   2626  const rs = new ReadableStream({
   2627    type: 'bytes',
   2628    start: t.step_func((c) => {
   2629      controller = c;
   2630    })
   2631  });
   2632  await flushAsyncEvents();
   2633 
   2634  const reader1 = rs.getReader({ mode: 'byob' });
   2635  const read1 = reader1.read(new Uint8Array([1, 2, 3]));
   2636  const byobRequest1 = controller.byobRequest;
   2637  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
   2638  assert_typed_array_equals(byobRequest1.view, new Uint8Array([1, 2, 3]), 'first byobRequest.view');
   2639 
   2640  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
   2641  reader1.releaseLock();
   2642  const reader2 = rs.getReader({ mode: 'byob' });
   2643  const read2 = reader2.read(new Uint8Array([4, 5, 6]));
   2644  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
   2645  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
   2646 
   2647  // respondWithNewView() should fulfill the *second* read() request
   2648  byobRequest1.view[0] = 11;
   2649  byobRequest1.view[1] = 12;
   2650  byobRequest1.respondWithNewView(byobRequest1.view.subarray(0, 2));
   2651  const byobRequest2 = controller.byobRequest;
   2652  assert_equals(byobRequest2, null, 'byobRequest should be null after respondWithNewView()');
   2653 
   2654  const result2 = await read2;
   2655  assert_false(result2.done, 'second result.done');
   2656  assert_typed_array_equals(result2.value, new Uint8Array([11, 12, 6]).subarray(0, 2), 'second result.value');
   2657 
   2658 }, 'ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, respondWithNewView()');
   2659 
   2660 promise_test(async t => {
   2661  let controller;
   2662  const rs = new ReadableStream({
   2663    type: 'bytes',
   2664    start: t.step_func((c) => {
   2665      controller = c;
   2666    })
   2667  });
   2668  await flushAsyncEvents();
   2669 
   2670  const reader1 = rs.getReader({ mode: 'byob' });
   2671  const read1 = reader1.read(new Uint8Array([1, 2, 3]));
   2672  const byobRequest1 = controller.byobRequest;
   2673  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
   2674  assert_typed_array_equals(byobRequest1.view, new Uint8Array([1, 2, 3]), 'first byobRequest.view');
   2675 
   2676  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
   2677  reader1.releaseLock();
   2678  const reader2 = rs.getReader({ mode: 'byob' });
   2679  const read2 = reader2.read(new Uint8Array([4, 5, 6]));
   2680  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
   2681  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
   2682 
   2683  // enqueue() should fulfill the *second* read() request
   2684  controller.enqueue(new Uint8Array([11, 12]));
   2685  const byobRequest2 = controller.byobRequest;
   2686  assert_equals(byobRequest2, null, 'byobRequest should be null after enqueue()');
   2687 
   2688  const result2 = await read2;
   2689  assert_false(result2.done, 'second result.done');
   2690  assert_typed_array_equals(result2.value, new Uint8Array([11, 12, 6]).subarray(0, 2), 'second result.value');
   2691 
   2692 }, 'ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, enqueue()');
   2693 
   2694 promise_test(async t => {
   2695  let controller;
   2696  const rs = new ReadableStream({
   2697    type: 'bytes',
   2698    start: t.step_func((c) => {
   2699      controller = c;
   2700    })
   2701  });
   2702  await flushAsyncEvents();
   2703 
   2704  const reader1 = rs.getReader({ mode: 'byob' });
   2705  const read1 = reader1.read(new Uint8Array([1, 2, 3]));
   2706  const byobRequest1 = controller.byobRequest;
   2707  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
   2708  assert_typed_array_equals(byobRequest1.view, new Uint8Array([1, 2, 3]), 'first byobRequest.view');
   2709 
   2710  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
   2711  reader1.releaseLock();
   2712  const reader2 = rs.getReader({ mode: 'byob' });
   2713  const read2 = reader2.read(new Uint8Array([4, 5, 6]));
   2714  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
   2715  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
   2716 
   2717  // close() followed by respond(0) should fulfill the second read()
   2718  controller.close();
   2719  byobRequest1.respond(0);
   2720  const byobRequest2 = controller.byobRequest;
   2721  assert_equals(byobRequest2, null, 'byobRequest should be null after respond()');
   2722 
   2723  const result2 = await read2;
   2724  assert_true(result2.done, 'second result.done');
   2725  assert_typed_array_equals(result2.value, new Uint8Array([4, 5, 6]).subarray(0, 0), 'second result.value');
   2726 }, 'ReadableStream with byte source: releaseLock() with pending read(view), read(view) on second reader, ' +
   2727   'close(), respond(0)');
   2728 
   2729 promise_test(async t => {
   2730  let controller;
   2731  const rs = new ReadableStream({
   2732    type: 'bytes',
   2733    autoAllocateChunkSize: 4,
   2734    start: t.step_func((c) => {
   2735      controller = c;
   2736    })
   2737  });
   2738  await flushAsyncEvents();
   2739 
   2740  const reader1 = rs.getReader();
   2741  const read1 = reader1.read();
   2742  const byobRequest1 = controller.byobRequest;
   2743  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
   2744  assert_typed_array_equals(byobRequest1.view, new Uint8Array(4), 'first byobRequest.view');
   2745 
   2746  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
   2747  reader1.releaseLock();
   2748  const reader2 = rs.getReader();
   2749  const read2 = reader2.read();
   2750  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
   2751  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
   2752 
   2753  // respond() should fulfill the *second* read() request
   2754  byobRequest1.view[0] = 11;
   2755  byobRequest1.respond(1);
   2756  const byobRequest2 = controller.byobRequest;
   2757  assert_equals(byobRequest2, null, 'byobRequest should be null after respond()');
   2758 
   2759  const result2 = await read2;
   2760  assert_false(result2.done, 'second result.done');
   2761  assert_typed_array_equals(result2.value, new Uint8Array([11, 0, 0, 0]).subarray(0, 1), 'second result.value');
   2762 
   2763 }, 'ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, respond()');
   2764 
   2765 promise_test(async t => {
   2766  let controller;
   2767  const rs = new ReadableStream({
   2768    type: 'bytes',
   2769    autoAllocateChunkSize: 4,
   2770    start: t.step_func((c) => {
   2771      controller = c;
   2772    })
   2773  });
   2774  await flushAsyncEvents();
   2775 
   2776  const reader1 = rs.getReader();
   2777  const read1 = reader1.read();
   2778  const byobRequest1 = controller.byobRequest;
   2779  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
   2780  assert_typed_array_equals(byobRequest1.view, new Uint8Array(4), 'first byobRequest.view');
   2781 
   2782  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
   2783  reader1.releaseLock();
   2784  const reader2 = rs.getReader();
   2785  const read2 = reader2.read();
   2786  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
   2787  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
   2788 
   2789  // enqueue() should fulfill the *second* read() request
   2790  controller.enqueue(new Uint8Array([11]));
   2791  const byobRequest2 = controller.byobRequest;
   2792  assert_equals(byobRequest2, null, 'byobRequest should be null after enqueue()');
   2793 
   2794  const result2 = await read2;
   2795  assert_false(result2.done, 'second result.done');
   2796  assert_typed_array_equals(result2.value, new Uint8Array([11]), 'second result.value');
   2797 
   2798 }, 'ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read() on second reader, enqueue()');
   2799 
   2800 promise_test(async t => {
   2801  let controller;
   2802  const rs = new ReadableStream({
   2803    type: 'bytes',
   2804    autoAllocateChunkSize: 4,
   2805    start: t.step_func((c) => {
   2806      controller = c;
   2807    })
   2808  });
   2809  await flushAsyncEvents();
   2810 
   2811  const reader1 = rs.getReader();
   2812  const read1 = reader1.read();
   2813  const byobRequest1 = controller.byobRequest;
   2814  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
   2815  assert_typed_array_equals(byobRequest1.view, new Uint8Array(4), 'first byobRequest.view');
   2816 
   2817  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
   2818  reader1.releaseLock();
   2819  const reader2 = rs.getReader({ mode: 'byob' });
   2820  const read2 = reader2.read(new Uint8Array([4, 5, 6]));
   2821  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
   2822  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
   2823 
   2824  // respond() should fulfill the *second* read() request
   2825  byobRequest1.view[0] = 11;
   2826  byobRequest1.respond(1);
   2827  const byobRequest2 = controller.byobRequest;
   2828  assert_equals(byobRequest2, null, 'byobRequest should be null after respond()');
   2829 
   2830  const result2 = await read2;
   2831  assert_false(result2.done, 'second result.done');
   2832  assert_typed_array_equals(result2.value, new Uint8Array([11, 5, 6]).subarray(0, 1), 'second result.value');
   2833 
   2834 }, 'ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, respond()');
   2835 
   2836 promise_test(async t => {
   2837  let controller;
   2838  const rs = new ReadableStream({
   2839    type: 'bytes',
   2840    autoAllocateChunkSize: 4,
   2841    start: t.step_func((c) => {
   2842      controller = c;
   2843    })
   2844  });
   2845  await flushAsyncEvents();
   2846 
   2847  const reader1 = rs.getReader();
   2848  const read1 = reader1.read();
   2849  const byobRequest1 = controller.byobRequest;
   2850  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
   2851  assert_typed_array_equals(byobRequest1.view, new Uint8Array(4), 'first byobRequest.view');
   2852 
   2853  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
   2854  reader1.releaseLock();
   2855  const reader2 = rs.getReader({ mode: 'byob' });
   2856  const read2 = reader2.read(new Uint8Array([4, 5, 6]));
   2857  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
   2858  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
   2859 
   2860  // enqueue() should fulfill the *second* read() request
   2861  controller.enqueue(new Uint8Array([11]));
   2862  const byobRequest2 = controller.byobRequest;
   2863  assert_equals(byobRequest2, null, 'byobRequest should be null after enqueue()');
   2864 
   2865  const result2 = await read2;
   2866  assert_false(result2.done, 'second result.done');
   2867  assert_typed_array_equals(result2.value, new Uint8Array([11, 5, 6]).subarray(0, 1), 'second result.value');
   2868 
   2869 }, 'ReadableStream with byte source: autoAllocateChunkSize, releaseLock() with pending read(), read(view) on second reader, enqueue()');
   2870 
   2871 promise_test(async t => {
   2872  let controller;
   2873  const rs = new ReadableStream({
   2874    type: 'bytes',
   2875    start: t.step_func((c) => {
   2876      controller = c;
   2877    })
   2878  });
   2879  await flushAsyncEvents();
   2880 
   2881  const reader1 = rs.getReader({ mode: 'byob' });
   2882  const read1 = reader1.read(new Uint16Array(1));
   2883  const byobRequest1 = controller.byobRequest;
   2884  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
   2885  assert_typed_array_equals(byobRequest1.view, new Uint8Array([0, 0]), 'first byobRequest.view');
   2886 
   2887  // respond(1) should partially fill the first read(), but not yet fulfill it
   2888  byobRequest1.view[0] = 0x11;
   2889  byobRequest1.respond(1);
   2890  const byobRequest2 = controller.byobRequest;
   2891  assert_not_equals(byobRequest2, null, 'second byobRequest should exist');
   2892  assert_typed_array_equals(byobRequest2.view, new Uint8Array([0x11, 0]).subarray(1, 2), 'second byobRequest.view');
   2893 
   2894  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
   2895  reader1.releaseLock();
   2896  const reader2 = rs.getReader({ mode: 'byob' });
   2897  const read2 = reader2.read(new Uint16Array(1));
   2898  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
   2899  assert_equals(controller.byobRequest, byobRequest2, 'byobRequest should be unchanged');
   2900  assert_typed_array_equals(byobRequest2.view, new Uint8Array([0x11, 0]).subarray(1, 2), 'byobRequest.view should be unchanged');
   2901  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
   2902 
   2903  // second respond(1) should fill the read request and fulfill it
   2904  byobRequest2.view[0] = 0x22;
   2905  byobRequest2.respond(1);
   2906  assert_equals(controller.byobRequest, null, 'byobRequest should be invalidated after second respond()');
   2907 
   2908  const result2 = await read2;
   2909  assert_false(result2.done, 'second result.done');
   2910  const view2 = result2.value;
   2911  assert_equals(view2.byteOffset, 0, 'second result.value.byteOffset');
   2912  assert_equals(view2.byteLength, 2, 'second result.value.byteLength');
   2913  const dataView2 = new DataView(view2.buffer, view2.byteOffset, view2.byteLength);
   2914  assert_equals(dataView2.getUint16(0), 0x1122, 'second result.value[0]');
   2915 
   2916 }, 'ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read(view) on ' +
   2917   'second reader with 1 element Uint16Array, respond(1)');
   2918 
   2919 promise_test(async t => {
   2920  let controller;
   2921  const rs = new ReadableStream({
   2922    type: 'bytes',
   2923    start: t.step_func((c) => {
   2924      controller = c;
   2925    })
   2926  });
   2927  await flushAsyncEvents();
   2928 
   2929  const reader1 = rs.getReader({ mode: 'byob' });
   2930  const read1 = reader1.read(new Uint16Array(1));
   2931  const byobRequest1 = controller.byobRequest;
   2932  assert_not_equals(byobRequest1, null, 'first byobRequest should exist');
   2933  assert_typed_array_equals(byobRequest1.view, new Uint8Array([0, 0]), 'first byobRequest.view');
   2934 
   2935  // respond(1) should partially fill the first read(), but not yet fulfill it
   2936  byobRequest1.view[0] = 0x11;
   2937  byobRequest1.respond(1);
   2938  const byobRequest2 = controller.byobRequest;
   2939  assert_not_equals(byobRequest2, null, 'second byobRequest should exist');
   2940  assert_typed_array_equals(byobRequest2.view, new Uint8Array([0x11, 0]).subarray(1, 2), 'second byobRequest.view');
   2941 
   2942  // releaseLock() should reject the pending read, but *not* invalidate the BYOB request
   2943  reader1.releaseLock();
   2944  const reader2 = rs.getReader();
   2945  const read2 = reader2.read();
   2946  assert_not_equals(controller.byobRequest, null, 'byobRequest should not be invalidated after releaseLock()');
   2947  assert_equals(controller.byobRequest, byobRequest2, 'byobRequest should be unchanged');
   2948  assert_typed_array_equals(byobRequest2.view, new Uint8Array([0x11, 0]).subarray(1, 2), 'byobRequest.view should be unchanged');
   2949  await promise_rejects_js(t, TypeError, read1, 'pending read must reject after releaseLock()');
   2950 
   2951  // enqueue() should fulfill the read request and put remaining byte in the queue
   2952  controller.enqueue(new Uint8Array([0x22]));
   2953  assert_equals(controller.byobRequest, null, 'byobRequest should be invalidated after second respond()');
   2954 
   2955  const result2 = await read2;
   2956  assert_false(result2.done, 'second result.done');
   2957  assert_typed_array_equals(result2.value, new Uint8Array([0x11]), 'second result.value');
   2958 
   2959  const result3 = await reader2.read();
   2960  assert_false(result3.done, 'third result.done');
   2961  assert_typed_array_equals(result3.value, new Uint8Array([0x22]), 'third result.value');
   2962 
   2963 }, 'ReadableStream with byte source: read(view) with 1 element Uint16Array, respond(1), releaseLock(), read() on ' +
   2964   'second reader, enqueue()');
   2965 
   2966 promise_test(async t => {
   2967  // Tests https://github.com/nodejs/node/issues/41886
   2968  const stream = new ReadableStream({
   2969    type: 'bytes',
   2970    autoAllocateChunkSize: 10,
   2971    pull: t.step_func((c) => {
   2972      const newView = new Uint8Array(c.byobRequest.view.buffer, 0, 3);
   2973      newView.set([20, 21, 22]);
   2974      c.byobRequest.respondWithNewView(newView);
   2975    })
   2976  });
   2977 
   2978  const reader = stream.getReader();
   2979  const result = await reader.read();
   2980  assert_false(result.done, 'result.done');
   2981 
   2982  const view = result.value;
   2983  assert_equals(view.byteOffset, 0, 'result.value.byteOffset');
   2984  assert_equals(view.byteLength, 3, 'result.value.byteLength');
   2985  assert_equals(view.buffer.byteLength, 10, 'result.value.buffer.byteLength');
   2986  assert_array_equals([...new Uint8Array(view)], [20, 21, 22], 'result.value');
   2987 }, 'ReadableStream with byte source: autoAllocateChunkSize, read(), respondWithNewView()');