11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ciconst assert = require('assert');
51cb0ef41Sopenharmony_ciconst { Duplex, Readable, Writable, pipeline, PassThrough } = require('stream');
61cb0ef41Sopenharmony_ciconst { ReadableStream, WritableStream } = require('stream/web');
71cb0ef41Sopenharmony_ciconst { Blob } = require('buffer');
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci{
101cb0ef41Sopenharmony_ci  const d = Duplex.from({
111cb0ef41Sopenharmony_ci    readable: new Readable({
121cb0ef41Sopenharmony_ci      read() {
131cb0ef41Sopenharmony_ci        this.push('asd');
141cb0ef41Sopenharmony_ci        this.push(null);
151cb0ef41Sopenharmony_ci      }
161cb0ef41Sopenharmony_ci    })
171cb0ef41Sopenharmony_ci  });
181cb0ef41Sopenharmony_ci  assert.strictEqual(d.readable, true);
191cb0ef41Sopenharmony_ci  assert.strictEqual(d.writable, false);
201cb0ef41Sopenharmony_ci  d.once('readable', common.mustCall(function() {
211cb0ef41Sopenharmony_ci    assert.strictEqual(d.read().toString(), 'asd');
221cb0ef41Sopenharmony_ci  }));
231cb0ef41Sopenharmony_ci  d.once('end', common.mustCall(function() {
241cb0ef41Sopenharmony_ci    assert.strictEqual(d.readable, false);
251cb0ef41Sopenharmony_ci  }));
261cb0ef41Sopenharmony_ci}
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci{
291cb0ef41Sopenharmony_ci  const d = Duplex.from(new Readable({
301cb0ef41Sopenharmony_ci    read() {
311cb0ef41Sopenharmony_ci      this.push('asd');
321cb0ef41Sopenharmony_ci      this.push(null);
331cb0ef41Sopenharmony_ci    }
341cb0ef41Sopenharmony_ci  }));
351cb0ef41Sopenharmony_ci  assert.strictEqual(d.readable, true);
361cb0ef41Sopenharmony_ci  assert.strictEqual(d.writable, false);
371cb0ef41Sopenharmony_ci  d.once('readable', common.mustCall(function() {
381cb0ef41Sopenharmony_ci    assert.strictEqual(d.read().toString(), 'asd');
391cb0ef41Sopenharmony_ci  }));
401cb0ef41Sopenharmony_ci  d.once('end', common.mustCall(function() {
411cb0ef41Sopenharmony_ci    assert.strictEqual(d.readable, false);
421cb0ef41Sopenharmony_ci  }));
431cb0ef41Sopenharmony_ci}
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci{
461cb0ef41Sopenharmony_ci  let ret = '';
471cb0ef41Sopenharmony_ci  const d = Duplex.from(new Writable({
481cb0ef41Sopenharmony_ci    write(chunk, encoding, callback) {
491cb0ef41Sopenharmony_ci      ret += chunk;
501cb0ef41Sopenharmony_ci      callback();
511cb0ef41Sopenharmony_ci    }
521cb0ef41Sopenharmony_ci  }));
531cb0ef41Sopenharmony_ci  assert.strictEqual(d.readable, false);
541cb0ef41Sopenharmony_ci  assert.strictEqual(d.writable, true);
551cb0ef41Sopenharmony_ci  d.end('asd');
561cb0ef41Sopenharmony_ci  d.on('finish', common.mustCall(function() {
571cb0ef41Sopenharmony_ci    assert.strictEqual(d.writable, false);
581cb0ef41Sopenharmony_ci    assert.strictEqual(ret, 'asd');
591cb0ef41Sopenharmony_ci  }));
601cb0ef41Sopenharmony_ci}
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci{
631cb0ef41Sopenharmony_ci  let ret = '';
641cb0ef41Sopenharmony_ci  const d = Duplex.from({
651cb0ef41Sopenharmony_ci    writable: new Writable({
661cb0ef41Sopenharmony_ci      write(chunk, encoding, callback) {
671cb0ef41Sopenharmony_ci        ret += chunk;
681cb0ef41Sopenharmony_ci        callback();
691cb0ef41Sopenharmony_ci      }
701cb0ef41Sopenharmony_ci    })
711cb0ef41Sopenharmony_ci  });
721cb0ef41Sopenharmony_ci  assert.strictEqual(d.readable, false);
731cb0ef41Sopenharmony_ci  assert.strictEqual(d.writable, true);
741cb0ef41Sopenharmony_ci  d.end('asd');
751cb0ef41Sopenharmony_ci  d.on('finish', common.mustCall(function() {
761cb0ef41Sopenharmony_ci    assert.strictEqual(d.writable, false);
771cb0ef41Sopenharmony_ci    assert.strictEqual(ret, 'asd');
781cb0ef41Sopenharmony_ci  }));
791cb0ef41Sopenharmony_ci}
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci{
821cb0ef41Sopenharmony_ci  let ret = '';
831cb0ef41Sopenharmony_ci  const d = Duplex.from({
841cb0ef41Sopenharmony_ci    readable: new Readable({
851cb0ef41Sopenharmony_ci      read() {
861cb0ef41Sopenharmony_ci        this.push('asd');
871cb0ef41Sopenharmony_ci        this.push(null);
881cb0ef41Sopenharmony_ci      }
891cb0ef41Sopenharmony_ci    }),
901cb0ef41Sopenharmony_ci    writable: new Writable({
911cb0ef41Sopenharmony_ci      write(chunk, encoding, callback) {
921cb0ef41Sopenharmony_ci        ret += chunk;
931cb0ef41Sopenharmony_ci        callback();
941cb0ef41Sopenharmony_ci      }
951cb0ef41Sopenharmony_ci    })
961cb0ef41Sopenharmony_ci  });
971cb0ef41Sopenharmony_ci  assert.strictEqual(d.readable, true);
981cb0ef41Sopenharmony_ci  assert.strictEqual(d.writable, true);
991cb0ef41Sopenharmony_ci  d.once('readable', common.mustCall(function() {
1001cb0ef41Sopenharmony_ci    assert.strictEqual(d.read().toString(), 'asd');
1011cb0ef41Sopenharmony_ci  }));
1021cb0ef41Sopenharmony_ci  d.once('end', common.mustCall(function() {
1031cb0ef41Sopenharmony_ci    assert.strictEqual(d.readable, false);
1041cb0ef41Sopenharmony_ci  }));
1051cb0ef41Sopenharmony_ci  d.end('asd');
1061cb0ef41Sopenharmony_ci  d.once('finish', common.mustCall(function() {
1071cb0ef41Sopenharmony_ci    assert.strictEqual(d.writable, false);
1081cb0ef41Sopenharmony_ci    assert.strictEqual(ret, 'asd');
1091cb0ef41Sopenharmony_ci  }));
1101cb0ef41Sopenharmony_ci}
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci{
1131cb0ef41Sopenharmony_ci  const d = Duplex.from(Promise.resolve('asd'));
1141cb0ef41Sopenharmony_ci  assert.strictEqual(d.readable, true);
1151cb0ef41Sopenharmony_ci  assert.strictEqual(d.writable, false);
1161cb0ef41Sopenharmony_ci  d.once('readable', common.mustCall(function() {
1171cb0ef41Sopenharmony_ci    assert.strictEqual(d.read().toString(), 'asd');
1181cb0ef41Sopenharmony_ci  }));
1191cb0ef41Sopenharmony_ci  d.once('end', common.mustCall(function() {
1201cb0ef41Sopenharmony_ci    assert.strictEqual(d.readable, false);
1211cb0ef41Sopenharmony_ci  }));
1221cb0ef41Sopenharmony_ci}
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci{
1251cb0ef41Sopenharmony_ci  // https://github.com/nodejs/node/issues/40497
1261cb0ef41Sopenharmony_ci  pipeline(
1271cb0ef41Sopenharmony_ci    ['abc\ndef\nghi'],
1281cb0ef41Sopenharmony_ci    Duplex.from(async function * (source) {
1291cb0ef41Sopenharmony_ci      let rest = '';
1301cb0ef41Sopenharmony_ci      for await (const chunk of source) {
1311cb0ef41Sopenharmony_ci        const lines = (rest + chunk.toString()).split('\n');
1321cb0ef41Sopenharmony_ci        rest = lines.pop();
1331cb0ef41Sopenharmony_ci        for (const line of lines) {
1341cb0ef41Sopenharmony_ci          yield line;
1351cb0ef41Sopenharmony_ci        }
1361cb0ef41Sopenharmony_ci      }
1371cb0ef41Sopenharmony_ci      yield rest;
1381cb0ef41Sopenharmony_ci    }),
1391cb0ef41Sopenharmony_ci    async function * (source) { // eslint-disable-line require-yield
1401cb0ef41Sopenharmony_ci      let ret = '';
1411cb0ef41Sopenharmony_ci      for await (const x of source) {
1421cb0ef41Sopenharmony_ci        ret += x;
1431cb0ef41Sopenharmony_ci      }
1441cb0ef41Sopenharmony_ci      assert.strictEqual(ret, 'abcdefghi');
1451cb0ef41Sopenharmony_ci    },
1461cb0ef41Sopenharmony_ci    common.mustSucceed(),
1471cb0ef41Sopenharmony_ci  );
1481cb0ef41Sopenharmony_ci}
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_ci// Ensure that isDuplexNodeStream was called
1511cb0ef41Sopenharmony_ci{
1521cb0ef41Sopenharmony_ci  const duplex = new Duplex();
1531cb0ef41Sopenharmony_ci  assert.strictEqual(Duplex.from(duplex), duplex);
1541cb0ef41Sopenharmony_ci}
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ci// Ensure that Duplex.from works for blobs
1571cb0ef41Sopenharmony_ci{
1581cb0ef41Sopenharmony_ci  const blob = new Blob(['blob']);
1591cb0ef41Sopenharmony_ci  const expectedByteLength = blob.size;
1601cb0ef41Sopenharmony_ci  const duplex = Duplex.from(blob);
1611cb0ef41Sopenharmony_ci  duplex.on('data', common.mustCall((arrayBuffer) => {
1621cb0ef41Sopenharmony_ci    assert.strictEqual(arrayBuffer.byteLength, expectedByteLength);
1631cb0ef41Sopenharmony_ci  }));
1641cb0ef41Sopenharmony_ci}
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci// Ensure that given a promise rejection it emits an error
1671cb0ef41Sopenharmony_ci{
1681cb0ef41Sopenharmony_ci  const myErrorMessage = 'myCustomError';
1691cb0ef41Sopenharmony_ci  Duplex.from(Promise.reject(myErrorMessage))
1701cb0ef41Sopenharmony_ci    .on('error', common.mustCall((error) => {
1711cb0ef41Sopenharmony_ci      assert.strictEqual(error, myErrorMessage);
1721cb0ef41Sopenharmony_ci    }));
1731cb0ef41Sopenharmony_ci}
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci// Ensure that given a promise rejection on an async function it emits an error
1761cb0ef41Sopenharmony_ci{
1771cb0ef41Sopenharmony_ci  const myErrorMessage = 'myCustomError';
1781cb0ef41Sopenharmony_ci  async function asyncFn() {
1791cb0ef41Sopenharmony_ci    return Promise.reject(myErrorMessage);
1801cb0ef41Sopenharmony_ci  }
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_ci  Duplex.from(asyncFn)
1831cb0ef41Sopenharmony_ci    .on('error', common.mustCall((error) => {
1841cb0ef41Sopenharmony_ci      assert.strictEqual(error, myErrorMessage);
1851cb0ef41Sopenharmony_ci    }));
1861cb0ef41Sopenharmony_ci}
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_ci// Ensure that Duplex.from throws an Invalid return value when function is void
1891cb0ef41Sopenharmony_ci{
1901cb0ef41Sopenharmony_ci  assert.throws(() => Duplex.from(() => {}), {
1911cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_RETURN_VALUE',
1921cb0ef41Sopenharmony_ci  });
1931cb0ef41Sopenharmony_ci}
1941cb0ef41Sopenharmony_ci
1951cb0ef41Sopenharmony_ci// Ensure data if a sub object has a readable stream it's duplexified
1961cb0ef41Sopenharmony_ci{
1971cb0ef41Sopenharmony_ci  const msg = Buffer.from('hello');
1981cb0ef41Sopenharmony_ci  const duplex = Duplex.from({
1991cb0ef41Sopenharmony_ci    readable: Readable({
2001cb0ef41Sopenharmony_ci      read() {
2011cb0ef41Sopenharmony_ci        this.push(msg);
2021cb0ef41Sopenharmony_ci        this.push(null);
2031cb0ef41Sopenharmony_ci      }
2041cb0ef41Sopenharmony_ci    })
2051cb0ef41Sopenharmony_ci  }).on('data', common.mustCall((data) => {
2061cb0ef41Sopenharmony_ci    assert.strictEqual(data, msg);
2071cb0ef41Sopenharmony_ci  }));
2081cb0ef41Sopenharmony_ci
2091cb0ef41Sopenharmony_ci  assert.strictEqual(duplex.writable, false);
2101cb0ef41Sopenharmony_ci}
2111cb0ef41Sopenharmony_ci
2121cb0ef41Sopenharmony_ci// Ensure data if a sub object has a writable stream it's duplexified
2131cb0ef41Sopenharmony_ci{
2141cb0ef41Sopenharmony_ci  const msg = Buffer.from('hello');
2151cb0ef41Sopenharmony_ci  const duplex = Duplex.from({
2161cb0ef41Sopenharmony_ci    writable: Writable({
2171cb0ef41Sopenharmony_ci      write: common.mustCall((data) => {
2181cb0ef41Sopenharmony_ci        assert.strictEqual(data, msg);
2191cb0ef41Sopenharmony_ci      })
2201cb0ef41Sopenharmony_ci    })
2211cb0ef41Sopenharmony_ci  });
2221cb0ef41Sopenharmony_ci
2231cb0ef41Sopenharmony_ci  duplex.write(msg);
2241cb0ef41Sopenharmony_ci  assert.strictEqual(duplex.readable, false);
2251cb0ef41Sopenharmony_ci}
2261cb0ef41Sopenharmony_ci
2271cb0ef41Sopenharmony_ci// Ensure data if a sub object has a writable and readable stream it's duplexified
2281cb0ef41Sopenharmony_ci{
2291cb0ef41Sopenharmony_ci  const msg = Buffer.from('hello');
2301cb0ef41Sopenharmony_ci
2311cb0ef41Sopenharmony_ci  const duplex = Duplex.from({
2321cb0ef41Sopenharmony_ci    readable: Readable({
2331cb0ef41Sopenharmony_ci      read() {
2341cb0ef41Sopenharmony_ci        this.push(msg);
2351cb0ef41Sopenharmony_ci        this.push(null);
2361cb0ef41Sopenharmony_ci      }
2371cb0ef41Sopenharmony_ci    }),
2381cb0ef41Sopenharmony_ci    writable: Writable({
2391cb0ef41Sopenharmony_ci      write: common.mustCall((data) => {
2401cb0ef41Sopenharmony_ci        assert.strictEqual(data, msg);
2411cb0ef41Sopenharmony_ci      })
2421cb0ef41Sopenharmony_ci    })
2431cb0ef41Sopenharmony_ci  });
2441cb0ef41Sopenharmony_ci
2451cb0ef41Sopenharmony_ci  duplex.pipe(duplex)
2461cb0ef41Sopenharmony_ci    .on('data', common.mustCall((data) => {
2471cb0ef41Sopenharmony_ci      assert.strictEqual(data, msg);
2481cb0ef41Sopenharmony_ci      assert.strictEqual(duplex.readable, true);
2491cb0ef41Sopenharmony_ci      assert.strictEqual(duplex.writable, true);
2501cb0ef41Sopenharmony_ci    }))
2511cb0ef41Sopenharmony_ci    .on('end', common.mustCall());
2521cb0ef41Sopenharmony_ci}
2531cb0ef41Sopenharmony_ci
2541cb0ef41Sopenharmony_ci// Ensure that given readable stream that throws an error it calls destroy
2551cb0ef41Sopenharmony_ci{
2561cb0ef41Sopenharmony_ci  const myErrorMessage = 'error!';
2571cb0ef41Sopenharmony_ci  const duplex = Duplex.from(Readable({
2581cb0ef41Sopenharmony_ci    read() {
2591cb0ef41Sopenharmony_ci      throw new Error(myErrorMessage);
2601cb0ef41Sopenharmony_ci    }
2611cb0ef41Sopenharmony_ci  }));
2621cb0ef41Sopenharmony_ci  duplex.on('error', common.mustCall((msg) => {
2631cb0ef41Sopenharmony_ci    assert.strictEqual(msg.message, myErrorMessage);
2641cb0ef41Sopenharmony_ci  }));
2651cb0ef41Sopenharmony_ci}
2661cb0ef41Sopenharmony_ci
2671cb0ef41Sopenharmony_ci// Ensure that given writable stream that throws an error it calls destroy
2681cb0ef41Sopenharmony_ci{
2691cb0ef41Sopenharmony_ci  const myErrorMessage = 'error!';
2701cb0ef41Sopenharmony_ci  const duplex = Duplex.from(Writable({
2711cb0ef41Sopenharmony_ci    write(chunk, enc, cb) {
2721cb0ef41Sopenharmony_ci      cb(myErrorMessage);
2731cb0ef41Sopenharmony_ci    }
2741cb0ef41Sopenharmony_ci  }));
2751cb0ef41Sopenharmony_ci
2761cb0ef41Sopenharmony_ci  duplex.on('error', common.mustCall((msg) => {
2771cb0ef41Sopenharmony_ci    assert.strictEqual(msg, myErrorMessage);
2781cb0ef41Sopenharmony_ci  }));
2791cb0ef41Sopenharmony_ci
2801cb0ef41Sopenharmony_ci  duplex.write('test');
2811cb0ef41Sopenharmony_ci}
2821cb0ef41Sopenharmony_ci
2831cb0ef41Sopenharmony_ci{
2841cb0ef41Sopenharmony_ci  const through = new PassThrough({ objectMode: true });
2851cb0ef41Sopenharmony_ci
2861cb0ef41Sopenharmony_ci  let res = '';
2871cb0ef41Sopenharmony_ci  const d = Readable.from(['foo', 'bar'], { objectMode: true })
2881cb0ef41Sopenharmony_ci    .pipe(Duplex.from({
2891cb0ef41Sopenharmony_ci      writable: through,
2901cb0ef41Sopenharmony_ci      readable: through
2911cb0ef41Sopenharmony_ci    }));
2921cb0ef41Sopenharmony_ci
2931cb0ef41Sopenharmony_ci  d.on('data', (data) => {
2941cb0ef41Sopenharmony_ci    d.pause();
2951cb0ef41Sopenharmony_ci    setImmediate(() => {
2961cb0ef41Sopenharmony_ci      d.resume();
2971cb0ef41Sopenharmony_ci    });
2981cb0ef41Sopenharmony_ci    res += data;
2991cb0ef41Sopenharmony_ci  }).on('end', common.mustCall(() => {
3001cb0ef41Sopenharmony_ci    assert.strictEqual(res, 'foobar');
3011cb0ef41Sopenharmony_ci  })).on('close', common.mustCall());
3021cb0ef41Sopenharmony_ci}
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_cifunction makeATestReadableStream(value) {
3051cb0ef41Sopenharmony_ci  return new ReadableStream({
3061cb0ef41Sopenharmony_ci    start(controller) {
3071cb0ef41Sopenharmony_ci      controller.enqueue(value);
3081cb0ef41Sopenharmony_ci      controller.close();
3091cb0ef41Sopenharmony_ci    }
3101cb0ef41Sopenharmony_ci  });
3111cb0ef41Sopenharmony_ci}
3121cb0ef41Sopenharmony_ci
3131cb0ef41Sopenharmony_cifunction makeATestWritableStream(writeFunc) {
3141cb0ef41Sopenharmony_ci  return new WritableStream({
3151cb0ef41Sopenharmony_ci    write(chunk) {
3161cb0ef41Sopenharmony_ci      writeFunc(chunk);
3171cb0ef41Sopenharmony_ci    }
3181cb0ef41Sopenharmony_ci  });
3191cb0ef41Sopenharmony_ci}
3201cb0ef41Sopenharmony_ci
3211cb0ef41Sopenharmony_ci{
3221cb0ef41Sopenharmony_ci  const d = Duplex.from({
3231cb0ef41Sopenharmony_ci    readable: makeATestReadableStream('foo'),
3241cb0ef41Sopenharmony_ci  });
3251cb0ef41Sopenharmony_ci  assert.strictEqual(d.readable, true);
3261cb0ef41Sopenharmony_ci  assert.strictEqual(d.writable, false);
3271cb0ef41Sopenharmony_ci
3281cb0ef41Sopenharmony_ci  d.on('data', common.mustCall((data) => {
3291cb0ef41Sopenharmony_ci    assert.strictEqual(data.toString(), 'foo');
3301cb0ef41Sopenharmony_ci  }));
3311cb0ef41Sopenharmony_ci
3321cb0ef41Sopenharmony_ci  d.on('end', common.mustCall(() => {
3331cb0ef41Sopenharmony_ci    assert.strictEqual(d.readable, false);
3341cb0ef41Sopenharmony_ci  }));
3351cb0ef41Sopenharmony_ci}
3361cb0ef41Sopenharmony_ci
3371cb0ef41Sopenharmony_ci{
3381cb0ef41Sopenharmony_ci  const d = Duplex.from(makeATestReadableStream('foo'));
3391cb0ef41Sopenharmony_ci
3401cb0ef41Sopenharmony_ci  assert.strictEqual(d.readable, true);
3411cb0ef41Sopenharmony_ci  assert.strictEqual(d.writable, false);
3421cb0ef41Sopenharmony_ci
3431cb0ef41Sopenharmony_ci  d.on('data', common.mustCall((data) => {
3441cb0ef41Sopenharmony_ci    assert.strictEqual(data.toString(), 'foo');
3451cb0ef41Sopenharmony_ci  }));
3461cb0ef41Sopenharmony_ci
3471cb0ef41Sopenharmony_ci  d.on('end', common.mustCall(() => {
3481cb0ef41Sopenharmony_ci    assert.strictEqual(d.readable, false);
3491cb0ef41Sopenharmony_ci  }));
3501cb0ef41Sopenharmony_ci}
3511cb0ef41Sopenharmony_ci
3521cb0ef41Sopenharmony_ci{
3531cb0ef41Sopenharmony_ci  let ret = '';
3541cb0ef41Sopenharmony_ci  const d = Duplex.from({
3551cb0ef41Sopenharmony_ci    writable: makeATestWritableStream((chunk) => ret += chunk),
3561cb0ef41Sopenharmony_ci  });
3571cb0ef41Sopenharmony_ci
3581cb0ef41Sopenharmony_ci  assert.strictEqual(d.readable, false);
3591cb0ef41Sopenharmony_ci  assert.strictEqual(d.writable, true);
3601cb0ef41Sopenharmony_ci
3611cb0ef41Sopenharmony_ci  d.end('foo');
3621cb0ef41Sopenharmony_ci  d.on('finish', common.mustCall(() => {
3631cb0ef41Sopenharmony_ci    assert.strictEqual(ret, 'foo');
3641cb0ef41Sopenharmony_ci    assert.strictEqual(d.writable, false);
3651cb0ef41Sopenharmony_ci  }));
3661cb0ef41Sopenharmony_ci}
3671cb0ef41Sopenharmony_ci
3681cb0ef41Sopenharmony_ci{
3691cb0ef41Sopenharmony_ci  let ret = '';
3701cb0ef41Sopenharmony_ci  const d = Duplex.from(makeATestWritableStream((chunk) => ret += chunk));
3711cb0ef41Sopenharmony_ci
3721cb0ef41Sopenharmony_ci  assert.strictEqual(d.readable, false);
3731cb0ef41Sopenharmony_ci  assert.strictEqual(d.writable, true);
3741cb0ef41Sopenharmony_ci
3751cb0ef41Sopenharmony_ci  d.end('foo');
3761cb0ef41Sopenharmony_ci  d.on('finish', common.mustCall(() => {
3771cb0ef41Sopenharmony_ci    assert.strictEqual(ret, 'foo');
3781cb0ef41Sopenharmony_ci    assert.strictEqual(d.writable, false);
3791cb0ef41Sopenharmony_ci  }));
3801cb0ef41Sopenharmony_ci}
3811cb0ef41Sopenharmony_ci
3821cb0ef41Sopenharmony_ci{
3831cb0ef41Sopenharmony_ci  let ret = '';
3841cb0ef41Sopenharmony_ci  const d = Duplex.from({
3851cb0ef41Sopenharmony_ci    readable: makeATestReadableStream('foo'),
3861cb0ef41Sopenharmony_ci    writable: makeATestWritableStream((chunk) => ret += chunk),
3871cb0ef41Sopenharmony_ci  });
3881cb0ef41Sopenharmony_ci
3891cb0ef41Sopenharmony_ci  d.end('bar');
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ci  d.on('data', common.mustCall((data) => {
3921cb0ef41Sopenharmony_ci    assert.strictEqual(data.toString(), 'foo');
3931cb0ef41Sopenharmony_ci  }));
3941cb0ef41Sopenharmony_ci
3951cb0ef41Sopenharmony_ci  d.on('end', common.mustCall(() => {
3961cb0ef41Sopenharmony_ci    assert.strictEqual(d.readable, false);
3971cb0ef41Sopenharmony_ci  }));
3981cb0ef41Sopenharmony_ci
3991cb0ef41Sopenharmony_ci  d.on('finish', common.mustCall(() => {
4001cb0ef41Sopenharmony_ci    assert.strictEqual(ret, 'bar');
4011cb0ef41Sopenharmony_ci    assert.strictEqual(d.writable, false);
4021cb0ef41Sopenharmony_ci  }));
4031cb0ef41Sopenharmony_ci}
404