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: R, Writable: W } = require('stream'); 261cb0ef41Sopenharmony_ciconst assert = require('assert'); 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciconst EE = require('events').EventEmitter; 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ciclass TestReader extends R { 311cb0ef41Sopenharmony_ci constructor(n) { 321cb0ef41Sopenharmony_ci super(); 331cb0ef41Sopenharmony_ci this._buffer = Buffer.alloc(n || 100, 'x'); 341cb0ef41Sopenharmony_ci this._pos = 0; 351cb0ef41Sopenharmony_ci this._bufs = 10; 361cb0ef41Sopenharmony_ci } 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci _read(n) { 391cb0ef41Sopenharmony_ci const max = this._buffer.length - this._pos; 401cb0ef41Sopenharmony_ci n = Math.max(n, 0); 411cb0ef41Sopenharmony_ci const toRead = Math.min(n, max); 421cb0ef41Sopenharmony_ci if (toRead === 0) { 431cb0ef41Sopenharmony_ci // Simulate the read buffer filling up with some more bytes some time 441cb0ef41Sopenharmony_ci // in the future. 451cb0ef41Sopenharmony_ci setTimeout(() => { 461cb0ef41Sopenharmony_ci this._pos = 0; 471cb0ef41Sopenharmony_ci this._bufs -= 1; 481cb0ef41Sopenharmony_ci if (this._bufs <= 0) { 491cb0ef41Sopenharmony_ci // read them all! 501cb0ef41Sopenharmony_ci if (!this.ended) 511cb0ef41Sopenharmony_ci this.push(null); 521cb0ef41Sopenharmony_ci } else { 531cb0ef41Sopenharmony_ci // now we have more. 541cb0ef41Sopenharmony_ci // kinda cheating by calling _read, but whatever, 551cb0ef41Sopenharmony_ci // it's just fake anyway. 561cb0ef41Sopenharmony_ci this._read(n); 571cb0ef41Sopenharmony_ci } 581cb0ef41Sopenharmony_ci }, 10); 591cb0ef41Sopenharmony_ci return; 601cb0ef41Sopenharmony_ci } 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_ci const ret = this._buffer.slice(this._pos, this._pos + toRead); 631cb0ef41Sopenharmony_ci this._pos += toRead; 641cb0ef41Sopenharmony_ci this.push(ret); 651cb0ef41Sopenharmony_ci } 661cb0ef41Sopenharmony_ci} 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ciclass TestWriter extends EE { 691cb0ef41Sopenharmony_ci constructor() { 701cb0ef41Sopenharmony_ci super(); 711cb0ef41Sopenharmony_ci this.received = []; 721cb0ef41Sopenharmony_ci this.flush = false; 731cb0ef41Sopenharmony_ci } 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci write(c) { 761cb0ef41Sopenharmony_ci this.received.push(c.toString()); 771cb0ef41Sopenharmony_ci this.emit('write', c); 781cb0ef41Sopenharmony_ci return true; 791cb0ef41Sopenharmony_ci } 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci end(c) { 821cb0ef41Sopenharmony_ci if (c) this.write(c); 831cb0ef41Sopenharmony_ci this.emit('end', this.received); 841cb0ef41Sopenharmony_ci } 851cb0ef41Sopenharmony_ci} 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci{ 881cb0ef41Sopenharmony_ci // Test basic functionality 891cb0ef41Sopenharmony_ci const r = new TestReader(20); 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci const reads = []; 921cb0ef41Sopenharmony_ci const expect = [ 'x', 931cb0ef41Sopenharmony_ci 'xx', 941cb0ef41Sopenharmony_ci 'xxx', 951cb0ef41Sopenharmony_ci 'xxxx', 961cb0ef41Sopenharmony_ci 'xxxxx', 971cb0ef41Sopenharmony_ci 'xxxxxxxxx', 981cb0ef41Sopenharmony_ci 'xxxxxxxxxx', 991cb0ef41Sopenharmony_ci 'xxxxxxxxxxxx', 1001cb0ef41Sopenharmony_ci 'xxxxxxxxxxxxx', 1011cb0ef41Sopenharmony_ci 'xxxxxxxxxxxxxxx', 1021cb0ef41Sopenharmony_ci 'xxxxxxxxxxxxxxxxx', 1031cb0ef41Sopenharmony_ci 'xxxxxxxxxxxxxxxxxxx', 1041cb0ef41Sopenharmony_ci 'xxxxxxxxxxxxxxxxxxxxx', 1051cb0ef41Sopenharmony_ci 'xxxxxxxxxxxxxxxxxxxxxxx', 1061cb0ef41Sopenharmony_ci 'xxxxxxxxxxxxxxxxxxxxxxxxx', 1071cb0ef41Sopenharmony_ci 'xxxxxxxxxxxxxxxxxxxxx' ]; 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci r.on('end', common.mustCall(function() { 1101cb0ef41Sopenharmony_ci assert.deepStrictEqual(reads, expect); 1111cb0ef41Sopenharmony_ci })); 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci let readSize = 1; 1141cb0ef41Sopenharmony_ci function flow() { 1151cb0ef41Sopenharmony_ci let res; 1161cb0ef41Sopenharmony_ci while (null !== (res = r.read(readSize++))) { 1171cb0ef41Sopenharmony_ci reads.push(res.toString()); 1181cb0ef41Sopenharmony_ci } 1191cb0ef41Sopenharmony_ci r.once('readable', flow); 1201cb0ef41Sopenharmony_ci } 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci flow(); 1231cb0ef41Sopenharmony_ci} 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci{ 1261cb0ef41Sopenharmony_ci // Verify pipe 1271cb0ef41Sopenharmony_ci const r = new TestReader(5); 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci const expect = [ 'xxxxx', 1301cb0ef41Sopenharmony_ci 'xxxxx', 1311cb0ef41Sopenharmony_ci 'xxxxx', 1321cb0ef41Sopenharmony_ci 'xxxxx', 1331cb0ef41Sopenharmony_ci 'xxxxx', 1341cb0ef41Sopenharmony_ci 'xxxxx', 1351cb0ef41Sopenharmony_ci 'xxxxx', 1361cb0ef41Sopenharmony_ci 'xxxxx', 1371cb0ef41Sopenharmony_ci 'xxxxx', 1381cb0ef41Sopenharmony_ci 'xxxxx' ]; 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci const w = new TestWriter(); 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_ci w.on('end', common.mustCall(function(received) { 1431cb0ef41Sopenharmony_ci assert.deepStrictEqual(received, expect); 1441cb0ef41Sopenharmony_ci })); 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ci r.pipe(w); 1471cb0ef41Sopenharmony_ci} 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci[1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(function(SPLIT) { 1511cb0ef41Sopenharmony_ci // Verify unpipe 1521cb0ef41Sopenharmony_ci const r = new TestReader(5); 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ci // Unpipe after 3 writes, then write to another stream instead. 1551cb0ef41Sopenharmony_ci let expect = [ 'xxxxx', 1561cb0ef41Sopenharmony_ci 'xxxxx', 1571cb0ef41Sopenharmony_ci 'xxxxx', 1581cb0ef41Sopenharmony_ci 'xxxxx', 1591cb0ef41Sopenharmony_ci 'xxxxx', 1601cb0ef41Sopenharmony_ci 'xxxxx', 1611cb0ef41Sopenharmony_ci 'xxxxx', 1621cb0ef41Sopenharmony_ci 'xxxxx', 1631cb0ef41Sopenharmony_ci 'xxxxx', 1641cb0ef41Sopenharmony_ci 'xxxxx' ]; 1651cb0ef41Sopenharmony_ci expect = [ expect.slice(0, SPLIT), expect.slice(SPLIT) ]; 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci const w = [ new TestWriter(), new TestWriter() ]; 1681cb0ef41Sopenharmony_ci 1691cb0ef41Sopenharmony_ci let writes = SPLIT; 1701cb0ef41Sopenharmony_ci w[0].on('write', function() { 1711cb0ef41Sopenharmony_ci if (--writes === 0) { 1721cb0ef41Sopenharmony_ci r.unpipe(); 1731cb0ef41Sopenharmony_ci assert.deepStrictEqual(r._readableState.pipes, []); 1741cb0ef41Sopenharmony_ci w[0].end(); 1751cb0ef41Sopenharmony_ci r.pipe(w[1]); 1761cb0ef41Sopenharmony_ci assert.deepStrictEqual(r._readableState.pipes, [w[1]]); 1771cb0ef41Sopenharmony_ci } 1781cb0ef41Sopenharmony_ci }); 1791cb0ef41Sopenharmony_ci 1801cb0ef41Sopenharmony_ci let ended = 0; 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci w[0].on('end', common.mustCall(function(results) { 1831cb0ef41Sopenharmony_ci ended++; 1841cb0ef41Sopenharmony_ci assert.strictEqual(ended, 1); 1851cb0ef41Sopenharmony_ci assert.deepStrictEqual(results, expect[0]); 1861cb0ef41Sopenharmony_ci })); 1871cb0ef41Sopenharmony_ci 1881cb0ef41Sopenharmony_ci w[1].on('end', common.mustCall(function(results) { 1891cb0ef41Sopenharmony_ci ended++; 1901cb0ef41Sopenharmony_ci assert.strictEqual(ended, 2); 1911cb0ef41Sopenharmony_ci assert.deepStrictEqual(results, expect[1]); 1921cb0ef41Sopenharmony_ci })); 1931cb0ef41Sopenharmony_ci 1941cb0ef41Sopenharmony_ci r.pipe(w[0]); 1951cb0ef41Sopenharmony_ci}); 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_ci{ 1991cb0ef41Sopenharmony_ci // Verify both writers get the same data when piping to destinations 2001cb0ef41Sopenharmony_ci const r = new TestReader(5); 2011cb0ef41Sopenharmony_ci const w = [ new TestWriter(), new TestWriter() ]; 2021cb0ef41Sopenharmony_ci 2031cb0ef41Sopenharmony_ci const expect = [ 'xxxxx', 2041cb0ef41Sopenharmony_ci 'xxxxx', 2051cb0ef41Sopenharmony_ci 'xxxxx', 2061cb0ef41Sopenharmony_ci 'xxxxx', 2071cb0ef41Sopenharmony_ci 'xxxxx', 2081cb0ef41Sopenharmony_ci 'xxxxx', 2091cb0ef41Sopenharmony_ci 'xxxxx', 2101cb0ef41Sopenharmony_ci 'xxxxx', 2111cb0ef41Sopenharmony_ci 'xxxxx', 2121cb0ef41Sopenharmony_ci 'xxxxx' ]; 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ci w[0].on('end', common.mustCall(function(received) { 2151cb0ef41Sopenharmony_ci assert.deepStrictEqual(received, expect); 2161cb0ef41Sopenharmony_ci })); 2171cb0ef41Sopenharmony_ci w[1].on('end', common.mustCall(function(received) { 2181cb0ef41Sopenharmony_ci assert.deepStrictEqual(received, expect); 2191cb0ef41Sopenharmony_ci })); 2201cb0ef41Sopenharmony_ci 2211cb0ef41Sopenharmony_ci r.pipe(w[0]); 2221cb0ef41Sopenharmony_ci r.pipe(w[1]); 2231cb0ef41Sopenharmony_ci} 2241cb0ef41Sopenharmony_ci 2251cb0ef41Sopenharmony_ci 2261cb0ef41Sopenharmony_ci[1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(function(SPLIT) { 2271cb0ef41Sopenharmony_ci // Verify multi-unpipe 2281cb0ef41Sopenharmony_ci const r = new TestReader(5); 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_ci // Unpipe after 3 writes, then write to another stream instead. 2311cb0ef41Sopenharmony_ci let expect = [ 'xxxxx', 2321cb0ef41Sopenharmony_ci 'xxxxx', 2331cb0ef41Sopenharmony_ci 'xxxxx', 2341cb0ef41Sopenharmony_ci 'xxxxx', 2351cb0ef41Sopenharmony_ci 'xxxxx', 2361cb0ef41Sopenharmony_ci 'xxxxx', 2371cb0ef41Sopenharmony_ci 'xxxxx', 2381cb0ef41Sopenharmony_ci 'xxxxx', 2391cb0ef41Sopenharmony_ci 'xxxxx', 2401cb0ef41Sopenharmony_ci 'xxxxx' ]; 2411cb0ef41Sopenharmony_ci expect = [ expect.slice(0, SPLIT), expect.slice(SPLIT) ]; 2421cb0ef41Sopenharmony_ci 2431cb0ef41Sopenharmony_ci const w = [ new TestWriter(), new TestWriter(), new TestWriter() ]; 2441cb0ef41Sopenharmony_ci 2451cb0ef41Sopenharmony_ci let writes = SPLIT; 2461cb0ef41Sopenharmony_ci w[0].on('write', function() { 2471cb0ef41Sopenharmony_ci if (--writes === 0) { 2481cb0ef41Sopenharmony_ci r.unpipe(); 2491cb0ef41Sopenharmony_ci w[0].end(); 2501cb0ef41Sopenharmony_ci r.pipe(w[1]); 2511cb0ef41Sopenharmony_ci } 2521cb0ef41Sopenharmony_ci }); 2531cb0ef41Sopenharmony_ci 2541cb0ef41Sopenharmony_ci let ended = 0; 2551cb0ef41Sopenharmony_ci 2561cb0ef41Sopenharmony_ci w[0].on('end', common.mustCall(function(results) { 2571cb0ef41Sopenharmony_ci ended++; 2581cb0ef41Sopenharmony_ci assert.strictEqual(ended, 1); 2591cb0ef41Sopenharmony_ci assert.deepStrictEqual(results, expect[0]); 2601cb0ef41Sopenharmony_ci })); 2611cb0ef41Sopenharmony_ci 2621cb0ef41Sopenharmony_ci w[1].on('end', common.mustCall(function(results) { 2631cb0ef41Sopenharmony_ci ended++; 2641cb0ef41Sopenharmony_ci assert.strictEqual(ended, 2); 2651cb0ef41Sopenharmony_ci assert.deepStrictEqual(results, expect[1]); 2661cb0ef41Sopenharmony_ci })); 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ci r.pipe(w[0]); 2691cb0ef41Sopenharmony_ci r.pipe(w[2]); 2701cb0ef41Sopenharmony_ci}); 2711cb0ef41Sopenharmony_ci 2721cb0ef41Sopenharmony_ci{ 2731cb0ef41Sopenharmony_ci // Verify that back pressure is respected 2741cb0ef41Sopenharmony_ci const r = new R({ objectMode: true }); 2751cb0ef41Sopenharmony_ci r._read = common.mustNotCall(); 2761cb0ef41Sopenharmony_ci let counter = 0; 2771cb0ef41Sopenharmony_ci r.push(['one']); 2781cb0ef41Sopenharmony_ci r.push(['two']); 2791cb0ef41Sopenharmony_ci r.push(['three']); 2801cb0ef41Sopenharmony_ci r.push(['four']); 2811cb0ef41Sopenharmony_ci r.push(null); 2821cb0ef41Sopenharmony_ci 2831cb0ef41Sopenharmony_ci const w1 = new R(); 2841cb0ef41Sopenharmony_ci w1.write = function(chunk) { 2851cb0ef41Sopenharmony_ci assert.strictEqual(chunk[0], 'one'); 2861cb0ef41Sopenharmony_ci w1.emit('close'); 2871cb0ef41Sopenharmony_ci process.nextTick(function() { 2881cb0ef41Sopenharmony_ci r.pipe(w2); 2891cb0ef41Sopenharmony_ci r.pipe(w3); 2901cb0ef41Sopenharmony_ci }); 2911cb0ef41Sopenharmony_ci }; 2921cb0ef41Sopenharmony_ci w1.end = common.mustNotCall(); 2931cb0ef41Sopenharmony_ci 2941cb0ef41Sopenharmony_ci r.pipe(w1); 2951cb0ef41Sopenharmony_ci 2961cb0ef41Sopenharmony_ci const expected = ['two', 'two', 'three', 'three', 'four', 'four']; 2971cb0ef41Sopenharmony_ci 2981cb0ef41Sopenharmony_ci const w2 = new R(); 2991cb0ef41Sopenharmony_ci w2.write = function(chunk) { 3001cb0ef41Sopenharmony_ci assert.strictEqual(chunk[0], expected.shift()); 3011cb0ef41Sopenharmony_ci assert.strictEqual(counter, 0); 3021cb0ef41Sopenharmony_ci 3031cb0ef41Sopenharmony_ci counter++; 3041cb0ef41Sopenharmony_ci 3051cb0ef41Sopenharmony_ci if (chunk[0] === 'four') { 3061cb0ef41Sopenharmony_ci return true; 3071cb0ef41Sopenharmony_ci } 3081cb0ef41Sopenharmony_ci 3091cb0ef41Sopenharmony_ci setTimeout(function() { 3101cb0ef41Sopenharmony_ci counter--; 3111cb0ef41Sopenharmony_ci w2.emit('drain'); 3121cb0ef41Sopenharmony_ci }, 10); 3131cb0ef41Sopenharmony_ci 3141cb0ef41Sopenharmony_ci return false; 3151cb0ef41Sopenharmony_ci }; 3161cb0ef41Sopenharmony_ci w2.end = common.mustCall(); 3171cb0ef41Sopenharmony_ci 3181cb0ef41Sopenharmony_ci const w3 = new R(); 3191cb0ef41Sopenharmony_ci w3.write = function(chunk) { 3201cb0ef41Sopenharmony_ci assert.strictEqual(chunk[0], expected.shift()); 3211cb0ef41Sopenharmony_ci assert.strictEqual(counter, 1); 3221cb0ef41Sopenharmony_ci 3231cb0ef41Sopenharmony_ci counter++; 3241cb0ef41Sopenharmony_ci 3251cb0ef41Sopenharmony_ci if (chunk[0] === 'four') { 3261cb0ef41Sopenharmony_ci return true; 3271cb0ef41Sopenharmony_ci } 3281cb0ef41Sopenharmony_ci 3291cb0ef41Sopenharmony_ci setTimeout(function() { 3301cb0ef41Sopenharmony_ci counter--; 3311cb0ef41Sopenharmony_ci w3.emit('drain'); 3321cb0ef41Sopenharmony_ci }, 50); 3331cb0ef41Sopenharmony_ci 3341cb0ef41Sopenharmony_ci return false; 3351cb0ef41Sopenharmony_ci }; 3361cb0ef41Sopenharmony_ci w3.end = common.mustCall(function() { 3371cb0ef41Sopenharmony_ci assert.strictEqual(counter, 2); 3381cb0ef41Sopenharmony_ci assert.strictEqual(expected.length, 0); 3391cb0ef41Sopenharmony_ci }); 3401cb0ef41Sopenharmony_ci} 3411cb0ef41Sopenharmony_ci 3421cb0ef41Sopenharmony_ci{ 3431cb0ef41Sopenharmony_ci // Verify read(0) behavior for ended streams 3441cb0ef41Sopenharmony_ci const r = new R(); 3451cb0ef41Sopenharmony_ci let written = false; 3461cb0ef41Sopenharmony_ci let ended = false; 3471cb0ef41Sopenharmony_ci r._read = common.mustNotCall(); 3481cb0ef41Sopenharmony_ci 3491cb0ef41Sopenharmony_ci r.push(Buffer.from('foo')); 3501cb0ef41Sopenharmony_ci r.push(null); 3511cb0ef41Sopenharmony_ci 3521cb0ef41Sopenharmony_ci const v = r.read(0); 3531cb0ef41Sopenharmony_ci 3541cb0ef41Sopenharmony_ci assert.strictEqual(v, null); 3551cb0ef41Sopenharmony_ci 3561cb0ef41Sopenharmony_ci const w = new R(); 3571cb0ef41Sopenharmony_ci w.write = function(buffer) { 3581cb0ef41Sopenharmony_ci written = true; 3591cb0ef41Sopenharmony_ci assert.strictEqual(ended, false); 3601cb0ef41Sopenharmony_ci assert.strictEqual(buffer.toString(), 'foo'); 3611cb0ef41Sopenharmony_ci }; 3621cb0ef41Sopenharmony_ci 3631cb0ef41Sopenharmony_ci w.end = common.mustCall(function() { 3641cb0ef41Sopenharmony_ci ended = true; 3651cb0ef41Sopenharmony_ci assert.strictEqual(written, true); 3661cb0ef41Sopenharmony_ci }); 3671cb0ef41Sopenharmony_ci 3681cb0ef41Sopenharmony_ci r.pipe(w); 3691cb0ef41Sopenharmony_ci} 3701cb0ef41Sopenharmony_ci 3711cb0ef41Sopenharmony_ci{ 3721cb0ef41Sopenharmony_ci // Verify synchronous _read ending 3731cb0ef41Sopenharmony_ci const r = new R(); 3741cb0ef41Sopenharmony_ci let called = false; 3751cb0ef41Sopenharmony_ci r._read = function(n) { 3761cb0ef41Sopenharmony_ci r.push(null); 3771cb0ef41Sopenharmony_ci }; 3781cb0ef41Sopenharmony_ci 3791cb0ef41Sopenharmony_ci r.once('end', function() { 3801cb0ef41Sopenharmony_ci // Verify that this is called before the next tick 3811cb0ef41Sopenharmony_ci called = true; 3821cb0ef41Sopenharmony_ci }); 3831cb0ef41Sopenharmony_ci 3841cb0ef41Sopenharmony_ci r.read(); 3851cb0ef41Sopenharmony_ci 3861cb0ef41Sopenharmony_ci process.nextTick(function() { 3871cb0ef41Sopenharmony_ci assert.strictEqual(called, true); 3881cb0ef41Sopenharmony_ci }); 3891cb0ef41Sopenharmony_ci} 3901cb0ef41Sopenharmony_ci 3911cb0ef41Sopenharmony_ci{ 3921cb0ef41Sopenharmony_ci // Verify that adding readable listeners trigger data flow 3931cb0ef41Sopenharmony_ci const r = new R({ highWaterMark: 5 }); 3941cb0ef41Sopenharmony_ci let onReadable = false; 3951cb0ef41Sopenharmony_ci let readCalled = 0; 3961cb0ef41Sopenharmony_ci 3971cb0ef41Sopenharmony_ci r._read = function(n) { 3981cb0ef41Sopenharmony_ci if (readCalled++ === 2) 3991cb0ef41Sopenharmony_ci r.push(null); 4001cb0ef41Sopenharmony_ci else 4011cb0ef41Sopenharmony_ci r.push(Buffer.from('asdf')); 4021cb0ef41Sopenharmony_ci }; 4031cb0ef41Sopenharmony_ci 4041cb0ef41Sopenharmony_ci r.on('readable', function() { 4051cb0ef41Sopenharmony_ci onReadable = true; 4061cb0ef41Sopenharmony_ci r.read(); 4071cb0ef41Sopenharmony_ci }); 4081cb0ef41Sopenharmony_ci 4091cb0ef41Sopenharmony_ci r.on('end', common.mustCall(function() { 4101cb0ef41Sopenharmony_ci assert.strictEqual(readCalled, 3); 4111cb0ef41Sopenharmony_ci assert.ok(onReadable); 4121cb0ef41Sopenharmony_ci })); 4131cb0ef41Sopenharmony_ci} 4141cb0ef41Sopenharmony_ci 4151cb0ef41Sopenharmony_ci{ 4161cb0ef41Sopenharmony_ci // Verify that streams are chainable 4171cb0ef41Sopenharmony_ci const r = new R(); 4181cb0ef41Sopenharmony_ci r._read = common.mustCall(); 4191cb0ef41Sopenharmony_ci const r2 = r.setEncoding('utf8').pause().resume().pause(); 4201cb0ef41Sopenharmony_ci assert.strictEqual(r, r2); 4211cb0ef41Sopenharmony_ci} 4221cb0ef41Sopenharmony_ci 4231cb0ef41Sopenharmony_ci{ 4241cb0ef41Sopenharmony_ci // Verify readableEncoding property 4251cb0ef41Sopenharmony_ci assert(Object.hasOwn(R.prototype, 'readableEncoding')); 4261cb0ef41Sopenharmony_ci 4271cb0ef41Sopenharmony_ci const r = new R({ encoding: 'utf8' }); 4281cb0ef41Sopenharmony_ci assert.strictEqual(r.readableEncoding, 'utf8'); 4291cb0ef41Sopenharmony_ci} 4301cb0ef41Sopenharmony_ci 4311cb0ef41Sopenharmony_ci{ 4321cb0ef41Sopenharmony_ci // Verify readableObjectMode property 4331cb0ef41Sopenharmony_ci assert(Object.hasOwn(R.prototype, 'readableObjectMode')); 4341cb0ef41Sopenharmony_ci 4351cb0ef41Sopenharmony_ci const r = new R({ objectMode: true }); 4361cb0ef41Sopenharmony_ci assert.strictEqual(r.readableObjectMode, true); 4371cb0ef41Sopenharmony_ci} 4381cb0ef41Sopenharmony_ci 4391cb0ef41Sopenharmony_ci{ 4401cb0ef41Sopenharmony_ci // Verify writableObjectMode property 4411cb0ef41Sopenharmony_ci assert(Object.hasOwn(W.prototype, 'writableObjectMode')); 4421cb0ef41Sopenharmony_ci 4431cb0ef41Sopenharmony_ci const w = new W({ objectMode: true }); 4441cb0ef41Sopenharmony_ci assert.strictEqual(w.writableObjectMode, true); 4451cb0ef41Sopenharmony_ci} 446