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  WritableStream,
91cb0ef41Sopenharmony_ci  WritableStreamDefaultController,
101cb0ef41Sopenharmony_ci  WritableStreamDefaultWriter,
111cb0ef41Sopenharmony_ci  CountQueuingStrategy,
121cb0ef41Sopenharmony_ci} = require('stream/web');
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ciconst {
151cb0ef41Sopenharmony_ci  kState,
161cb0ef41Sopenharmony_ci} = require('internal/webstreams/util');
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ciconst {
191cb0ef41Sopenharmony_ci  isPromise,
201cb0ef41Sopenharmony_ci} = require('util/types');
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ciconst {
231cb0ef41Sopenharmony_ci  kTransfer,
241cb0ef41Sopenharmony_ci} = require('internal/worker/js_transferable');
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ciconst {
271cb0ef41Sopenharmony_ci  inspect,
281cb0ef41Sopenharmony_ci} = require('util');
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ciclass Sink {
311cb0ef41Sopenharmony_ci  constructor() {
321cb0ef41Sopenharmony_ci    this.chunks = [];
331cb0ef41Sopenharmony_ci  }
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci  start() {
361cb0ef41Sopenharmony_ci    this.started = true;
371cb0ef41Sopenharmony_ci  }
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  write(chunk) {
401cb0ef41Sopenharmony_ci    this.chunks.push(chunk);
411cb0ef41Sopenharmony_ci  }
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci  close() {
441cb0ef41Sopenharmony_ci    this.closed = true;
451cb0ef41Sopenharmony_ci  }
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  abort() {
481cb0ef41Sopenharmony_ci    this.aborted = true;
491cb0ef41Sopenharmony_ci  }
501cb0ef41Sopenharmony_ci}
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci{
531cb0ef41Sopenharmony_ci  const stream = new WritableStream();
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  assert(stream[kState].controller instanceof WritableStreamDefaultController);
561cb0ef41Sopenharmony_ci  assert(!stream.locked);
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci  assert.strictEqual(typeof stream.abort, 'function');
591cb0ef41Sopenharmony_ci  assert.strictEqual(typeof stream.close, 'function');
601cb0ef41Sopenharmony_ci  assert.strictEqual(typeof stream.getWriter, 'function');
611cb0ef41Sopenharmony_ci}
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci[1, false, ''].forEach((type) => {
641cb0ef41Sopenharmony_ci  assert.throws(() => new WritableStream({ type }), {
651cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_VALUE',
661cb0ef41Sopenharmony_ci  });
671cb0ef41Sopenharmony_ci});
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci['a', {}].forEach((highWaterMark) => {
701cb0ef41Sopenharmony_ci  assert.throws(() => new WritableStream({}, { highWaterMark }), {
711cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_VALUE',
721cb0ef41Sopenharmony_ci  });
731cb0ef41Sopenharmony_ci});
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci['a', false, {}].forEach((size) => {
761cb0ef41Sopenharmony_ci  assert.throws(() => new WritableStream({}, { size }), {
771cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_TYPE',
781cb0ef41Sopenharmony_ci  });
791cb0ef41Sopenharmony_ci});
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci{
821cb0ef41Sopenharmony_ci  new WritableStream({}, 1);
831cb0ef41Sopenharmony_ci  new WritableStream({}, 'a');
841cb0ef41Sopenharmony_ci  new WritableStream({}, null);
851cb0ef41Sopenharmony_ci}
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci{
881cb0ef41Sopenharmony_ci  const sink = new Sink();
891cb0ef41Sopenharmony_ci  const stream = new WritableStream(
901cb0ef41Sopenharmony_ci    sink,
911cb0ef41Sopenharmony_ci    new CountQueuingStrategy({ highWaterMark: 1 }));
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci  assert(!stream.locked);
941cb0ef41Sopenharmony_ci  const writer = stream.getWriter();
951cb0ef41Sopenharmony_ci  assert(stream.locked);
961cb0ef41Sopenharmony_ci  assert(writer instanceof WritableStreamDefaultWriter);
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ci  assert(isPromise(writer.closed));
991cb0ef41Sopenharmony_ci  assert(isPromise(writer.ready));
1001cb0ef41Sopenharmony_ci  assert(typeof writer.desiredSize, 'number');
1011cb0ef41Sopenharmony_ci  assert(typeof writer.abort, 'function');
1021cb0ef41Sopenharmony_ci  assert(typeof writer.close, 'function');
1031cb0ef41Sopenharmony_ci  assert(typeof writer.releaseLock, 'function');
1041cb0ef41Sopenharmony_ci  assert(typeof writer.write, 'function');
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci  writer.releaseLock();
1071cb0ef41Sopenharmony_ci  assert(!stream.locked);
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ci  const writer2 = stream.getWriter();
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ci  assert(sink.started);
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci  writer2.closed.then(common.mustCall());
1141cb0ef41Sopenharmony_ci  writer2.ready.then(common.mustCall());
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ci  writer2.close().then(common.mustCall(() => {
1171cb0ef41Sopenharmony_ci    assert.strict(sink.closed);
1181cb0ef41Sopenharmony_ci  }));
1191cb0ef41Sopenharmony_ci}
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ci{
1221cb0ef41Sopenharmony_ci  const sink = new Sink();
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci  const stream = new WritableStream(
1251cb0ef41Sopenharmony_ci    sink,
1261cb0ef41Sopenharmony_ci    new CountQueuingStrategy({ highWaterMark: 1 }));
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci  const error = new Error('boom');
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci  const writer = stream.getWriter();
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci  assert.rejects(writer.closed, error);
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci  writer.abort(error).then(common.mustCall(() => {
1351cb0ef41Sopenharmony_ci    assert.strictEqual(stream[kState].state, 'errored');
1361cb0ef41Sopenharmony_ci    assert(sink.aborted);
1371cb0ef41Sopenharmony_ci  }));
1381cb0ef41Sopenharmony_ci}
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci{
1411cb0ef41Sopenharmony_ci  const sink = new Sink();
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci  const stream = new WritableStream(
1441cb0ef41Sopenharmony_ci    sink, { highWaterMark: 1 }
1451cb0ef41Sopenharmony_ci  );
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ci  async function write(stream) {
1481cb0ef41Sopenharmony_ci    const writer = stream.getWriter();
1491cb0ef41Sopenharmony_ci    const p = writer.write('hello');
1501cb0ef41Sopenharmony_ci    assert.strictEqual(writer.desiredSize, 0);
1511cb0ef41Sopenharmony_ci    await p;
1521cb0ef41Sopenharmony_ci    assert.strictEqual(writer.desiredSize, 1);
1531cb0ef41Sopenharmony_ci  }
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_ci  write(stream).then(common.mustCall(() => {
1561cb0ef41Sopenharmony_ci    assert.deepStrictEqual(['hello'], sink.chunks);
1571cb0ef41Sopenharmony_ci  }));
1581cb0ef41Sopenharmony_ci}
1591cb0ef41Sopenharmony_ci
1601cb0ef41Sopenharmony_ci{
1611cb0ef41Sopenharmony_ci  assert.throws(() => Reflect.get(WritableStream.prototype, 'locked', {}), {
1621cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_THIS',
1631cb0ef41Sopenharmony_ci  });
1641cb0ef41Sopenharmony_ci  assert.rejects(() => WritableStream.prototype.abort({}), {
1651cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_THIS',
1661cb0ef41Sopenharmony_ci  });
1671cb0ef41Sopenharmony_ci  assert.rejects(() => WritableStream.prototype.close({}), {
1681cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_THIS',
1691cb0ef41Sopenharmony_ci  });
1701cb0ef41Sopenharmony_ci  assert.throws(() => WritableStream.prototype.getWriter.call(), {
1711cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_THIS',
1721cb0ef41Sopenharmony_ci  });
1731cb0ef41Sopenharmony_ci  assert.throws(() => WritableStream.prototype[kTransfer].call(), {
1741cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_THIS',
1751cb0ef41Sopenharmony_ci  });
1761cb0ef41Sopenharmony_ci  assert.rejects(
1771cb0ef41Sopenharmony_ci    Reflect.get(WritableStreamDefaultWriter.prototype, 'closed'), {
1781cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_THIS',
1791cb0ef41Sopenharmony_ci    });
1801cb0ef41Sopenharmony_ci  assert.rejects(
1811cb0ef41Sopenharmony_ci    Reflect.get(WritableStreamDefaultWriter.prototype, 'ready'), {
1821cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_THIS',
1831cb0ef41Sopenharmony_ci    });
1841cb0ef41Sopenharmony_ci  assert.throws(
1851cb0ef41Sopenharmony_ci    () => Reflect.get(WritableStreamDefaultWriter.prototype, 'desiredSize'), {
1861cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_THIS',
1871cb0ef41Sopenharmony_ci    });
1881cb0ef41Sopenharmony_ci  assert.rejects(WritableStreamDefaultWriter.prototype.abort({}), {
1891cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_THIS',
1901cb0ef41Sopenharmony_ci  });
1911cb0ef41Sopenharmony_ci  assert.rejects(WritableStreamDefaultWriter.prototype.close({}), {
1921cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_THIS',
1931cb0ef41Sopenharmony_ci  });
1941cb0ef41Sopenharmony_ci  assert.rejects(WritableStreamDefaultWriter.prototype.write({}), {
1951cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_THIS',
1961cb0ef41Sopenharmony_ci  });
1971cb0ef41Sopenharmony_ci  assert.throws(() => WritableStreamDefaultWriter.prototype.releaseLock({}), {
1981cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_THIS',
1991cb0ef41Sopenharmony_ci  });
2001cb0ef41Sopenharmony_ci
2011cb0ef41Sopenharmony_ci  assert.throws(() => {
2021cb0ef41Sopenharmony_ci    Reflect.get(WritableStreamDefaultController.prototype, 'signal', {});
2031cb0ef41Sopenharmony_ci  }, {
2041cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_THIS',
2051cb0ef41Sopenharmony_ci  });
2061cb0ef41Sopenharmony_ci
2071cb0ef41Sopenharmony_ci  assert.throws(() => {
2081cb0ef41Sopenharmony_ci    WritableStreamDefaultController.prototype.error({});
2091cb0ef41Sopenharmony_ci  }, {
2101cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_THIS',
2111cb0ef41Sopenharmony_ci  });
2121cb0ef41Sopenharmony_ci}
2131cb0ef41Sopenharmony_ci
2141cb0ef41Sopenharmony_ci{
2151cb0ef41Sopenharmony_ci  let controller;
2161cb0ef41Sopenharmony_ci  const writable = new WritableStream({
2171cb0ef41Sopenharmony_ci    start(c) { controller = c; }
2181cb0ef41Sopenharmony_ci  });
2191cb0ef41Sopenharmony_ci  assert.strictEqual(
2201cb0ef41Sopenharmony_ci    inspect(writable),
2211cb0ef41Sopenharmony_ci    'WritableStream { locked: false, state: \'writable\' }');
2221cb0ef41Sopenharmony_ci  assert.strictEqual(
2231cb0ef41Sopenharmony_ci    inspect(writable, { depth: null }),
2241cb0ef41Sopenharmony_ci    'WritableStream { locked: false, state: \'writable\' }');
2251cb0ef41Sopenharmony_ci  assert.strictEqual(
2261cb0ef41Sopenharmony_ci    inspect(writable, { depth: 0 }),
2271cb0ef41Sopenharmony_ci    'WritableStream [Object]');
2281cb0ef41Sopenharmony_ci
2291cb0ef41Sopenharmony_ci  const writer = writable.getWriter();
2301cb0ef41Sopenharmony_ci  assert.match(
2311cb0ef41Sopenharmony_ci    inspect(writer),
2321cb0ef41Sopenharmony_ci    /WritableStreamDefaultWriter/);
2331cb0ef41Sopenharmony_ci  assert.match(
2341cb0ef41Sopenharmony_ci    inspect(writer, { depth: null }),
2351cb0ef41Sopenharmony_ci    /WritableStreamDefaultWriter/);
2361cb0ef41Sopenharmony_ci  assert.match(
2371cb0ef41Sopenharmony_ci    inspect(writer, { depth: 0 }),
2381cb0ef41Sopenharmony_ci    /WritableStreamDefaultWriter \[/);
2391cb0ef41Sopenharmony_ci
2401cb0ef41Sopenharmony_ci  assert.match(
2411cb0ef41Sopenharmony_ci    inspect(controller),
2421cb0ef41Sopenharmony_ci    /WritableStreamDefaultController/);
2431cb0ef41Sopenharmony_ci  assert.match(
2441cb0ef41Sopenharmony_ci    inspect(controller, { depth: null }),
2451cb0ef41Sopenharmony_ci    /WritableStreamDefaultController/);
2461cb0ef41Sopenharmony_ci  assert.match(
2471cb0ef41Sopenharmony_ci    inspect(controller, { depth: 0 }),
2481cb0ef41Sopenharmony_ci    /WritableStreamDefaultController \[/);
2491cb0ef41Sopenharmony_ci
2501cb0ef41Sopenharmony_ci  writer.abort(new Error('boom'));
2511cb0ef41Sopenharmony_ci
2521cb0ef41Sopenharmony_ci  assert.strictEqual(writer.desiredSize, null);
2531cb0ef41Sopenharmony_ci  setImmediate(() => assert.strictEqual(writer.desiredSize, null));
2541cb0ef41Sopenharmony_ci}
255