11cb0ef41Sopenharmony_ci// Copyright Joyent, Inc. and other Node contributors.
21cb0ef41Sopenharmony_ci//
31cb0ef41Sopenharmony_ci// Permission is hereby granted, free of charge, to any person obtaining a
41cb0ef41Sopenharmony_ci// copy of this software and associated documentation files (the
51cb0ef41Sopenharmony_ci// "Software"), to deal in the Software without restriction, including
61cb0ef41Sopenharmony_ci// without limitation the rights to use, copy, modify, merge, publish,
71cb0ef41Sopenharmony_ci// distribute, sublicense, and/or sell copies of the Software, and to permit
81cb0ef41Sopenharmony_ci// persons to whom the Software is furnished to do so, subject to the
91cb0ef41Sopenharmony_ci// following conditions:
101cb0ef41Sopenharmony_ci//
111cb0ef41Sopenharmony_ci// The above copyright notice and this permission notice shall be included
121cb0ef41Sopenharmony_ci// in all copies or substantial portions of the Software.
131cb0ef41Sopenharmony_ci//
141cb0ef41Sopenharmony_ci// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
151cb0ef41Sopenharmony_ci// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
161cb0ef41Sopenharmony_ci// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
171cb0ef41Sopenharmony_ci// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
181cb0ef41Sopenharmony_ci// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
191cb0ef41Sopenharmony_ci// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
201cb0ef41Sopenharmony_ci// USE OR OTHER DEALINGS IN THE SOFTWARE.
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci'use strict';
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ciconst common = require('../common');
251cb0ef41Sopenharmony_ciconst { Readable, Writable } = require('stream');
261cb0ef41Sopenharmony_ciconst assert = require('assert');
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_cifunction toArray(callback) {
291cb0ef41Sopenharmony_ci  const stream = new Writable({ objectMode: true });
301cb0ef41Sopenharmony_ci  const list = [];
311cb0ef41Sopenharmony_ci  stream.write = function(chunk) {
321cb0ef41Sopenharmony_ci    list.push(chunk);
331cb0ef41Sopenharmony_ci  };
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci  stream.end = common.mustCall(function() {
361cb0ef41Sopenharmony_ci    callback(list);
371cb0ef41Sopenharmony_ci  });
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  return stream;
401cb0ef41Sopenharmony_ci}
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_cifunction fromArray(list) {
431cb0ef41Sopenharmony_ci  const r = new Readable({ objectMode: true });
441cb0ef41Sopenharmony_ci  r._read = common.mustNotCall();
451cb0ef41Sopenharmony_ci  list.forEach(function(chunk) {
461cb0ef41Sopenharmony_ci    r.push(chunk);
471cb0ef41Sopenharmony_ci  });
481cb0ef41Sopenharmony_ci  r.push(null);
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci  return r;
511cb0ef41Sopenharmony_ci}
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci{
541cb0ef41Sopenharmony_ci  // Verify that objects can be read from the stream
551cb0ef41Sopenharmony_ci  const r = fromArray([{ one: '1' }, { two: '2' }]);
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  const v1 = r.read();
581cb0ef41Sopenharmony_ci  const v2 = r.read();
591cb0ef41Sopenharmony_ci  const v3 = r.read();
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci  assert.deepStrictEqual(v1, { one: '1' });
621cb0ef41Sopenharmony_ci  assert.deepStrictEqual(v2, { two: '2' });
631cb0ef41Sopenharmony_ci  assert.strictEqual(v3, null);
641cb0ef41Sopenharmony_ci}
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci{
671cb0ef41Sopenharmony_ci  // Verify that objects can be piped into the stream
681cb0ef41Sopenharmony_ci  const r = fromArray([{ one: '1' }, { two: '2' }]);
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci  r.pipe(toArray(common.mustCall(function(list) {
711cb0ef41Sopenharmony_ci    assert.deepStrictEqual(list, [
721cb0ef41Sopenharmony_ci      { one: '1' },
731cb0ef41Sopenharmony_ci      { two: '2' },
741cb0ef41Sopenharmony_ci    ]);
751cb0ef41Sopenharmony_ci  })));
761cb0ef41Sopenharmony_ci}
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci{
791cb0ef41Sopenharmony_ci  // Verify that read(n) is ignored
801cb0ef41Sopenharmony_ci  const r = fromArray([{ one: '1' }, { two: '2' }]);
811cb0ef41Sopenharmony_ci  const value = r.read(2);
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci  assert.deepStrictEqual(value, { one: '1' });
841cb0ef41Sopenharmony_ci}
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci{
871cb0ef41Sopenharmony_ci  // Verify that objects can be synchronously read
881cb0ef41Sopenharmony_ci  const r = new Readable({ objectMode: true });
891cb0ef41Sopenharmony_ci  const list = [{ one: '1' }, { two: '2' }];
901cb0ef41Sopenharmony_ci  r._read = function(n) {
911cb0ef41Sopenharmony_ci    const item = list.shift();
921cb0ef41Sopenharmony_ci    r.push(item || null);
931cb0ef41Sopenharmony_ci  };
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci  r.pipe(toArray(common.mustCall(function(list) {
961cb0ef41Sopenharmony_ci    assert.deepStrictEqual(list, [
971cb0ef41Sopenharmony_ci      { one: '1' },
981cb0ef41Sopenharmony_ci      { two: '2' },
991cb0ef41Sopenharmony_ci    ]);
1001cb0ef41Sopenharmony_ci  })));
1011cb0ef41Sopenharmony_ci}
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci{
1041cb0ef41Sopenharmony_ci  // Verify that objects can be asynchronously read
1051cb0ef41Sopenharmony_ci  const r = new Readable({ objectMode: true });
1061cb0ef41Sopenharmony_ci  const list = [{ one: '1' }, { two: '2' }];
1071cb0ef41Sopenharmony_ci  r._read = function(n) {
1081cb0ef41Sopenharmony_ci    const item = list.shift();
1091cb0ef41Sopenharmony_ci    process.nextTick(function() {
1101cb0ef41Sopenharmony_ci      r.push(item || null);
1111cb0ef41Sopenharmony_ci    });
1121cb0ef41Sopenharmony_ci  };
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci  r.pipe(toArray(common.mustCall(function(list) {
1151cb0ef41Sopenharmony_ci    assert.deepStrictEqual(list, [
1161cb0ef41Sopenharmony_ci      { one: '1' },
1171cb0ef41Sopenharmony_ci      { two: '2' },
1181cb0ef41Sopenharmony_ci    ]);
1191cb0ef41Sopenharmony_ci  })));
1201cb0ef41Sopenharmony_ci}
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci{
1231cb0ef41Sopenharmony_ci  // Verify that strings can be read as objects
1241cb0ef41Sopenharmony_ci  const r = new Readable({
1251cb0ef41Sopenharmony_ci    objectMode: true
1261cb0ef41Sopenharmony_ci  });
1271cb0ef41Sopenharmony_ci  r._read = common.mustNotCall();
1281cb0ef41Sopenharmony_ci  const list = ['one', 'two', 'three'];
1291cb0ef41Sopenharmony_ci  list.forEach(function(str) {
1301cb0ef41Sopenharmony_ci    r.push(str);
1311cb0ef41Sopenharmony_ci  });
1321cb0ef41Sopenharmony_ci  r.push(null);
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci  r.pipe(toArray(common.mustCall(function(array) {
1351cb0ef41Sopenharmony_ci    assert.deepStrictEqual(array, list);
1361cb0ef41Sopenharmony_ci  })));
1371cb0ef41Sopenharmony_ci}
1381cb0ef41Sopenharmony_ci
1391cb0ef41Sopenharmony_ci{
1401cb0ef41Sopenharmony_ci  // Verify read(0) behavior for object streams
1411cb0ef41Sopenharmony_ci  const r = new Readable({
1421cb0ef41Sopenharmony_ci    objectMode: true
1431cb0ef41Sopenharmony_ci  });
1441cb0ef41Sopenharmony_ci  r._read = common.mustNotCall();
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ci  r.push('foobar');
1471cb0ef41Sopenharmony_ci  r.push(null);
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci  r.pipe(toArray(common.mustCall(function(array) {
1501cb0ef41Sopenharmony_ci    assert.deepStrictEqual(array, ['foobar']);
1511cb0ef41Sopenharmony_ci  })));
1521cb0ef41Sopenharmony_ci}
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci{
1551cb0ef41Sopenharmony_ci  // Verify the behavior of pushing falsey values
1561cb0ef41Sopenharmony_ci  const r = new Readable({
1571cb0ef41Sopenharmony_ci    objectMode: true
1581cb0ef41Sopenharmony_ci  });
1591cb0ef41Sopenharmony_ci  r._read = common.mustNotCall();
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ci  r.push(false);
1621cb0ef41Sopenharmony_ci  r.push(0);
1631cb0ef41Sopenharmony_ci  r.push('');
1641cb0ef41Sopenharmony_ci  r.push(null);
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci  r.pipe(toArray(common.mustCall(function(array) {
1671cb0ef41Sopenharmony_ci    assert.deepStrictEqual(array, [false, 0, '']);
1681cb0ef41Sopenharmony_ci  })));
1691cb0ef41Sopenharmony_ci}
1701cb0ef41Sopenharmony_ci
1711cb0ef41Sopenharmony_ci{
1721cb0ef41Sopenharmony_ci  // Verify high watermark _read() behavior
1731cb0ef41Sopenharmony_ci  const r = new Readable({
1741cb0ef41Sopenharmony_ci    highWaterMark: 6,
1751cb0ef41Sopenharmony_ci    objectMode: true
1761cb0ef41Sopenharmony_ci  });
1771cb0ef41Sopenharmony_ci  let calls = 0;
1781cb0ef41Sopenharmony_ci  const list = ['1', '2', '3', '4', '5', '6', '7', '8'];
1791cb0ef41Sopenharmony_ci
1801cb0ef41Sopenharmony_ci  r._read = function(n) {
1811cb0ef41Sopenharmony_ci    calls++;
1821cb0ef41Sopenharmony_ci  };
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_ci  list.forEach(function(c) {
1851cb0ef41Sopenharmony_ci    r.push(c);
1861cb0ef41Sopenharmony_ci  });
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_ci  const v = r.read();
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_ci  assert.strictEqual(calls, 0);
1911cb0ef41Sopenharmony_ci  assert.strictEqual(v, '1');
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_ci  const v2 = r.read();
1941cb0ef41Sopenharmony_ci  assert.strictEqual(v2, '2');
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ci  const v3 = r.read();
1971cb0ef41Sopenharmony_ci  assert.strictEqual(v3, '3');
1981cb0ef41Sopenharmony_ci
1991cb0ef41Sopenharmony_ci  assert.strictEqual(calls, 1);
2001cb0ef41Sopenharmony_ci}
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_ci{
2031cb0ef41Sopenharmony_ci  // Verify high watermark push behavior
2041cb0ef41Sopenharmony_ci  const r = new Readable({
2051cb0ef41Sopenharmony_ci    highWaterMark: 6,
2061cb0ef41Sopenharmony_ci    objectMode: true
2071cb0ef41Sopenharmony_ci  });
2081cb0ef41Sopenharmony_ci  r._read = common.mustNotCall();
2091cb0ef41Sopenharmony_ci  for (let i = 0; i < 6; i++) {
2101cb0ef41Sopenharmony_ci    const bool = r.push(i);
2111cb0ef41Sopenharmony_ci    assert.strictEqual(bool, i !== 5);
2121cb0ef41Sopenharmony_ci  }
2131cb0ef41Sopenharmony_ci}
2141cb0ef41Sopenharmony_ci
2151cb0ef41Sopenharmony_ci{
2161cb0ef41Sopenharmony_ci  // Verify that objects can be written to stream
2171cb0ef41Sopenharmony_ci  const w = new Writable({ objectMode: true });
2181cb0ef41Sopenharmony_ci
2191cb0ef41Sopenharmony_ci  w._write = function(chunk, encoding, cb) {
2201cb0ef41Sopenharmony_ci    assert.deepStrictEqual(chunk, { foo: 'bar' });
2211cb0ef41Sopenharmony_ci    cb();
2221cb0ef41Sopenharmony_ci  };
2231cb0ef41Sopenharmony_ci
2241cb0ef41Sopenharmony_ci  w.on('finish', common.mustCall());
2251cb0ef41Sopenharmony_ci  w.write({ foo: 'bar' });
2261cb0ef41Sopenharmony_ci  w.end();
2271cb0ef41Sopenharmony_ci}
2281cb0ef41Sopenharmony_ci
2291cb0ef41Sopenharmony_ci{
2301cb0ef41Sopenharmony_ci  // Verify that multiple objects can be written to stream
2311cb0ef41Sopenharmony_ci  const w = new Writable({ objectMode: true });
2321cb0ef41Sopenharmony_ci  const list = [];
2331cb0ef41Sopenharmony_ci
2341cb0ef41Sopenharmony_ci  w._write = function(chunk, encoding, cb) {
2351cb0ef41Sopenharmony_ci    list.push(chunk);
2361cb0ef41Sopenharmony_ci    cb();
2371cb0ef41Sopenharmony_ci  };
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_ci  w.on('finish', common.mustCall(function() {
2401cb0ef41Sopenharmony_ci    assert.deepStrictEqual(list, [0, 1, 2, 3, 4]);
2411cb0ef41Sopenharmony_ci  }));
2421cb0ef41Sopenharmony_ci
2431cb0ef41Sopenharmony_ci  w.write(0);
2441cb0ef41Sopenharmony_ci  w.write(1);
2451cb0ef41Sopenharmony_ci  w.write(2);
2461cb0ef41Sopenharmony_ci  w.write(3);
2471cb0ef41Sopenharmony_ci  w.write(4);
2481cb0ef41Sopenharmony_ci  w.end();
2491cb0ef41Sopenharmony_ci}
2501cb0ef41Sopenharmony_ci
2511cb0ef41Sopenharmony_ci{
2521cb0ef41Sopenharmony_ci  // Verify that strings can be written as objects
2531cb0ef41Sopenharmony_ci  const w = new Writable({
2541cb0ef41Sopenharmony_ci    objectMode: true
2551cb0ef41Sopenharmony_ci  });
2561cb0ef41Sopenharmony_ci  const list = [];
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_ci  w._write = function(chunk, encoding, cb) {
2591cb0ef41Sopenharmony_ci    list.push(chunk);
2601cb0ef41Sopenharmony_ci    process.nextTick(cb);
2611cb0ef41Sopenharmony_ci  };
2621cb0ef41Sopenharmony_ci
2631cb0ef41Sopenharmony_ci  w.on('finish', common.mustCall(function() {
2641cb0ef41Sopenharmony_ci    assert.deepStrictEqual(list, ['0', '1', '2', '3', '4']);
2651cb0ef41Sopenharmony_ci  }));
2661cb0ef41Sopenharmony_ci
2671cb0ef41Sopenharmony_ci  w.write('0');
2681cb0ef41Sopenharmony_ci  w.write('1');
2691cb0ef41Sopenharmony_ci  w.write('2');
2701cb0ef41Sopenharmony_ci  w.write('3');
2711cb0ef41Sopenharmony_ci  w.write('4');
2721cb0ef41Sopenharmony_ci  w.end();
2731cb0ef41Sopenharmony_ci}
2741cb0ef41Sopenharmony_ci
2751cb0ef41Sopenharmony_ci{
2761cb0ef41Sopenharmony_ci  // Verify that stream buffers finish until callback is called
2771cb0ef41Sopenharmony_ci  const w = new Writable({
2781cb0ef41Sopenharmony_ci    objectMode: true
2791cb0ef41Sopenharmony_ci  });
2801cb0ef41Sopenharmony_ci  let called = false;
2811cb0ef41Sopenharmony_ci
2821cb0ef41Sopenharmony_ci  w._write = function(chunk, encoding, cb) {
2831cb0ef41Sopenharmony_ci    assert.strictEqual(chunk, 'foo');
2841cb0ef41Sopenharmony_ci
2851cb0ef41Sopenharmony_ci    process.nextTick(function() {
2861cb0ef41Sopenharmony_ci      called = true;
2871cb0ef41Sopenharmony_ci      cb();
2881cb0ef41Sopenharmony_ci    });
2891cb0ef41Sopenharmony_ci  };
2901cb0ef41Sopenharmony_ci
2911cb0ef41Sopenharmony_ci  w.on('finish', common.mustCall(function() {
2921cb0ef41Sopenharmony_ci    assert.strictEqual(called, true);
2931cb0ef41Sopenharmony_ci  }));
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ci  w.write('foo');
2961cb0ef41Sopenharmony_ci  w.end();
2971cb0ef41Sopenharmony_ci}
298