11cb0ef41Sopenharmony_ci// Flags: --expose-internals --no-warnings
21cb0ef41Sopenharmony_ci'use strict';
31cb0ef41Sopenharmony_ci
41cb0ef41Sopenharmony_ciconst common = require('../common');
51cb0ef41Sopenharmony_ciconst assert = require('assert');
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciconst {
81cb0ef41Sopenharmony_ci  ReadableStream,
91cb0ef41Sopenharmony_ci  ReadableByteStreamController,
101cb0ef41Sopenharmony_ci  ReadableStreamDefaultReader,
111cb0ef41Sopenharmony_ci  ReadableStreamBYOBReader,
121cb0ef41Sopenharmony_ci  ReadableStreamBYOBRequest,
131cb0ef41Sopenharmony_ci} = require('stream/web');
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ciconst {
161cb0ef41Sopenharmony_ci  kState,
171cb0ef41Sopenharmony_ci} = require('internal/webstreams/util');
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ciconst {
201cb0ef41Sopenharmony_ci  open,
211cb0ef41Sopenharmony_ci} = require('fs/promises');
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ciconst {
241cb0ef41Sopenharmony_ci  readFileSync,
251cb0ef41Sopenharmony_ci} = require('fs');
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ciconst {
281cb0ef41Sopenharmony_ci  Buffer,
291cb0ef41Sopenharmony_ci} = require('buffer');
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ciconst {
321cb0ef41Sopenharmony_ci  inspect,
331cb0ef41Sopenharmony_ci} = require('util');
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci{
361cb0ef41Sopenharmony_ci  const r = new ReadableStream({
371cb0ef41Sopenharmony_ci    type: 'bytes',
381cb0ef41Sopenharmony_ci  });
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  assert(r[kState].controller instanceof ReadableByteStreamController);
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  assert.strictEqual(typeof r.locked, 'boolean');
431cb0ef41Sopenharmony_ci  assert.strictEqual(typeof r.cancel, 'function');
441cb0ef41Sopenharmony_ci  assert.strictEqual(typeof r.getReader, 'function');
451cb0ef41Sopenharmony_ci  assert.strictEqual(typeof r.pipeThrough, 'function');
461cb0ef41Sopenharmony_ci  assert.strictEqual(typeof r.pipeTo, 'function');
471cb0ef41Sopenharmony_ci  assert.strictEqual(typeof r.tee, 'function');
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  ['', null, 'asdf'].forEach((mode) => {
501cb0ef41Sopenharmony_ci    assert.throws(() => r.getReader({ mode }), {
511cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_VALUE',
521cb0ef41Sopenharmony_ci    });
531cb0ef41Sopenharmony_ci  });
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  [1, 'asdf'].forEach((options) => {
561cb0ef41Sopenharmony_ci    assert.throws(() => r.getReader(options), {
571cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
581cb0ef41Sopenharmony_ci    });
591cb0ef41Sopenharmony_ci  });
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci  assert(!r.locked);
621cb0ef41Sopenharmony_ci  const defaultReader = r.getReader();
631cb0ef41Sopenharmony_ci  assert(r.locked);
641cb0ef41Sopenharmony_ci  assert(defaultReader instanceof ReadableStreamDefaultReader);
651cb0ef41Sopenharmony_ci  defaultReader.releaseLock();
661cb0ef41Sopenharmony_ci  const byobReader = r.getReader({ mode: 'byob' });
671cb0ef41Sopenharmony_ci  assert(byobReader instanceof ReadableStreamBYOBReader);
681cb0ef41Sopenharmony_ci  assert.match(
691cb0ef41Sopenharmony_ci    inspect(byobReader, { depth: 0 }),
701cb0ef41Sopenharmony_ci    /ReadableStreamBYOBReader/);
711cb0ef41Sopenharmony_ci}
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ciclass Source {
741cb0ef41Sopenharmony_ci  constructor() {
751cb0ef41Sopenharmony_ci    this.controllerClosed = false;
761cb0ef41Sopenharmony_ci  }
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci  async start(controller) {
791cb0ef41Sopenharmony_ci    this.file = await open(__filename);
801cb0ef41Sopenharmony_ci    this.controller = controller;
811cb0ef41Sopenharmony_ci  }
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci  async pull(controller) {
841cb0ef41Sopenharmony_ci    const byobRequest = controller.byobRequest;
851cb0ef41Sopenharmony_ci    assert.match(inspect(byobRequest), /ReadableStreamBYOBRequest/);
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci    const view = byobRequest.view;
881cb0ef41Sopenharmony_ci    const {
891cb0ef41Sopenharmony_ci      bytesRead,
901cb0ef41Sopenharmony_ci    } = await this.file.read({
911cb0ef41Sopenharmony_ci      buffer: view,
921cb0ef41Sopenharmony_ci      offset: view.byteOffset,
931cb0ef41Sopenharmony_ci      length: view.byteLength
941cb0ef41Sopenharmony_ci    });
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci    if (bytesRead === 0) {
971cb0ef41Sopenharmony_ci      await this.file.close();
981cb0ef41Sopenharmony_ci      this.controller.close();
991cb0ef41Sopenharmony_ci    }
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ci    assert.throws(() => byobRequest.respondWithNewView({}), {
1021cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
1031cb0ef41Sopenharmony_ci    });
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci    byobRequest.respond(bytesRead);
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci    assert.throws(() => byobRequest.respond(bytesRead), {
1081cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_STATE',
1091cb0ef41Sopenharmony_ci    });
1101cb0ef41Sopenharmony_ci    assert.throws(() => byobRequest.respondWithNewView(view), {
1111cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_STATE',
1121cb0ef41Sopenharmony_ci    });
1131cb0ef41Sopenharmony_ci  }
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci  get type() { return 'bytes'; }
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci  get autoAllocateChunkSize() { return 1024; }
1181cb0ef41Sopenharmony_ci}
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci{
1211cb0ef41Sopenharmony_ci  const stream = new ReadableStream(new Source());
1221cb0ef41Sopenharmony_ci  assert(stream[kState].controller instanceof ReadableByteStreamController);
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci  async function read(stream) {
1251cb0ef41Sopenharmony_ci    const reader = stream.getReader({ mode: 'byob' });
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci    const chunks = [];
1281cb0ef41Sopenharmony_ci    let result;
1291cb0ef41Sopenharmony_ci    do {
1301cb0ef41Sopenharmony_ci      result = await reader.read(Buffer.alloc(100));
1311cb0ef41Sopenharmony_ci      if (result.value !== undefined)
1321cb0ef41Sopenharmony_ci        chunks.push(Buffer.from(result.value));
1331cb0ef41Sopenharmony_ci    } while (!result.done);
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci    return Buffer.concat(chunks);
1361cb0ef41Sopenharmony_ci  }
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ci  read(stream).then(common.mustCall((data) => {
1391cb0ef41Sopenharmony_ci    const check = readFileSync(__filename);
1401cb0ef41Sopenharmony_ci    assert.deepStrictEqual(check, data);
1411cb0ef41Sopenharmony_ci  }));
1421cb0ef41Sopenharmony_ci}
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ci{
1451cb0ef41Sopenharmony_ci  const stream = new ReadableStream(new Source());
1461cb0ef41Sopenharmony_ci  assert(stream[kState].controller instanceof ReadableByteStreamController);
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ci  async function read(stream) {
1491cb0ef41Sopenharmony_ci    const chunks = [];
1501cb0ef41Sopenharmony_ci    for await (const chunk of stream)
1511cb0ef41Sopenharmony_ci      chunks.push(chunk);
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci    return Buffer.concat(chunks);
1541cb0ef41Sopenharmony_ci  }
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ci  read(stream).then(common.mustCall((data) => {
1571cb0ef41Sopenharmony_ci    const check = readFileSync(__filename);
1581cb0ef41Sopenharmony_ci    assert.deepStrictEqual(check, data);
1591cb0ef41Sopenharmony_ci  }));
1601cb0ef41Sopenharmony_ci}
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci{
1631cb0ef41Sopenharmony_ci  const stream = new ReadableStream(new Source());
1641cb0ef41Sopenharmony_ci  assert(stream[kState].controller instanceof ReadableByteStreamController);
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci  async function read(stream) {
1671cb0ef41Sopenharmony_ci    // eslint-disable-next-line no-unused-vars
1681cb0ef41Sopenharmony_ci    for await (const _ of stream)
1691cb0ef41Sopenharmony_ci      break;
1701cb0ef41Sopenharmony_ci  }
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ci  read(stream).then(common.mustCall());
1731cb0ef41Sopenharmony_ci}
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci{
1761cb0ef41Sopenharmony_ci  const stream = new ReadableStream(new Source());
1771cb0ef41Sopenharmony_ci  assert(stream[kState].controller instanceof ReadableByteStreamController);
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_ci  const error = new Error('boom');
1801cb0ef41Sopenharmony_ci
1811cb0ef41Sopenharmony_ci  async function read(stream) {
1821cb0ef41Sopenharmony_ci    // eslint-disable-next-line no-unused-vars
1831cb0ef41Sopenharmony_ci    for await (const _ of stream)
1841cb0ef41Sopenharmony_ci      throw error;
1851cb0ef41Sopenharmony_ci  }
1861cb0ef41Sopenharmony_ci
1871cb0ef41Sopenharmony_ci  assert.rejects(read(stream), error);
1881cb0ef41Sopenharmony_ci}
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_ci{
1911cb0ef41Sopenharmony_ci  assert.throws(() => {
1921cb0ef41Sopenharmony_ci    Reflect.get(ReadableStreamBYOBRequest.prototype, 'view', {});
1931cb0ef41Sopenharmony_ci  }, {
1941cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_THIS',
1951cb0ef41Sopenharmony_ci  });
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_ci  assert.throws(() => ReadableStreamBYOBRequest.prototype.respond.call({}), {
1981cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_THIS',
1991cb0ef41Sopenharmony_ci  });
2001cb0ef41Sopenharmony_ci
2011cb0ef41Sopenharmony_ci  assert.throws(() => {
2021cb0ef41Sopenharmony_ci    ReadableStreamBYOBRequest.prototype.respondWithNewView.call({});
2031cb0ef41Sopenharmony_ci  }, {
2041cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_THIS',
2051cb0ef41Sopenharmony_ci  });
2061cb0ef41Sopenharmony_ci}
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_ci{
2091cb0ef41Sopenharmony_ci  const readable = new ReadableStream({ type: 'bytes' });
2101cb0ef41Sopenharmony_ci  const reader = readable.getReader({ mode: 'byob' });
2111cb0ef41Sopenharmony_ci  reader.releaseLock();
2121cb0ef41Sopenharmony_ci  reader.releaseLock();
2131cb0ef41Sopenharmony_ci  assert.rejects(reader.read(new Uint8Array(10)), {
2141cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_STATE',
2151cb0ef41Sopenharmony_ci  });
2161cb0ef41Sopenharmony_ci  assert.rejects(reader.cancel(), {
2171cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_STATE',
2181cb0ef41Sopenharmony_ci  });
2191cb0ef41Sopenharmony_ci}
2201cb0ef41Sopenharmony_ci
2211cb0ef41Sopenharmony_ci{
2221cb0ef41Sopenharmony_ci  let controller;
2231cb0ef41Sopenharmony_ci  new ReadableStream({
2241cb0ef41Sopenharmony_ci    type: 'bytes',
2251cb0ef41Sopenharmony_ci    start(c) { controller = c; }
2261cb0ef41Sopenharmony_ci  });
2271cb0ef41Sopenharmony_ci  assert.throws(() => controller.enqueue(1), {
2281cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_TYPE',
2291cb0ef41Sopenharmony_ci  });
2301cb0ef41Sopenharmony_ci  controller.close();
2311cb0ef41Sopenharmony_ci  assert.throws(() => controller.enqueue(new Uint8Array(10)), {
2321cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_STATE',
2331cb0ef41Sopenharmony_ci  });
2341cb0ef41Sopenharmony_ci  assert.throws(() => controller.close(), {
2351cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_STATE',
2361cb0ef41Sopenharmony_ci  });
2371cb0ef41Sopenharmony_ci}
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_ci{
2401cb0ef41Sopenharmony_ci  let controller;
2411cb0ef41Sopenharmony_ci  new ReadableStream({
2421cb0ef41Sopenharmony_ci    type: 'bytes',
2431cb0ef41Sopenharmony_ci    start(c) { controller = c; }
2441cb0ef41Sopenharmony_ci  });
2451cb0ef41Sopenharmony_ci  controller.enqueue(new Uint8Array(10));
2461cb0ef41Sopenharmony_ci  controller.close();
2471cb0ef41Sopenharmony_ci  assert.throws(() => controller.enqueue(new Uint8Array(10)), {
2481cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_STATE',
2491cb0ef41Sopenharmony_ci  });
2501cb0ef41Sopenharmony_ci}
2511cb0ef41Sopenharmony_ci
2521cb0ef41Sopenharmony_ci{
2531cb0ef41Sopenharmony_ci  const stream = new ReadableStream({
2541cb0ef41Sopenharmony_ci    type: 'bytes',
2551cb0ef41Sopenharmony_ci    pull(c) {
2561cb0ef41Sopenharmony_ci      const v = new Uint8Array(c.byobRequest.view.buffer, 0, 3);
2571cb0ef41Sopenharmony_ci      v.set([20, 21, 22]);
2581cb0ef41Sopenharmony_ci      c.byobRequest.respondWithNewView(v);
2591cb0ef41Sopenharmony_ci    },
2601cb0ef41Sopenharmony_ci  });
2611cb0ef41Sopenharmony_ci  const buffer = new ArrayBuffer(10);
2621cb0ef41Sopenharmony_ci  const view = new Uint8Array(buffer, 0, 3);
2631cb0ef41Sopenharmony_ci  view.set([10, 11, 12]);
2641cb0ef41Sopenharmony_ci  const reader = stream.getReader({ mode: 'byob' });
2651cb0ef41Sopenharmony_ci  reader.read(view);
2661cb0ef41Sopenharmony_ci}
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ci{
2691cb0ef41Sopenharmony_ci  const stream = new ReadableStream({
2701cb0ef41Sopenharmony_ci    type: 'bytes',
2711cb0ef41Sopenharmony_ci    autoAllocateChunkSize: 10,
2721cb0ef41Sopenharmony_ci    pull(c) {
2731cb0ef41Sopenharmony_ci      const v = new Uint8Array(c.byobRequest.view.buffer, 0, 3);
2741cb0ef41Sopenharmony_ci      v.set([20, 21, 22]);
2751cb0ef41Sopenharmony_ci      c.byobRequest.respondWithNewView(v);
2761cb0ef41Sopenharmony_ci    },
2771cb0ef41Sopenharmony_ci  });
2781cb0ef41Sopenharmony_ci  const reader = stream.getReader();
2791cb0ef41Sopenharmony_ci  reader.read();
2801cb0ef41Sopenharmony_ci}
281