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