11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ciconst assert = require('assert');
51cb0ef41Sopenharmony_ciconst { Readable } = require('stream');
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci{
81cb0ef41Sopenharmony_ci  // Check that strings are saved as Buffer
91cb0ef41Sopenharmony_ci  const readable = new Readable({ read() {} });
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci  const string = 'abc';
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ci  readable.on('data', common.mustCall((chunk) => {
141cb0ef41Sopenharmony_ci    assert(Buffer.isBuffer(chunk));
151cb0ef41Sopenharmony_ci    assert.strictEqual(chunk.toString('utf8'), string);
161cb0ef41Sopenharmony_ci  }, 1));
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ci  readable.unshift(string);
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci}
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci{
231cb0ef41Sopenharmony_ci  // Check that data goes at the beginning
241cb0ef41Sopenharmony_ci  const readable = new Readable({ read() {} });
251cb0ef41Sopenharmony_ci  const unshift = 'front';
261cb0ef41Sopenharmony_ci  const push = 'back';
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci  const expected = [unshift, push];
291cb0ef41Sopenharmony_ci  readable.on('data', common.mustCall((chunk) => {
301cb0ef41Sopenharmony_ci    assert.strictEqual(chunk.toString('utf8'), expected.shift());
311cb0ef41Sopenharmony_ci  }, 2));
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci  readable.push(push);
351cb0ef41Sopenharmony_ci  readable.unshift(unshift);
361cb0ef41Sopenharmony_ci}
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci{
391cb0ef41Sopenharmony_ci  // Check that buffer is saved with correct encoding
401cb0ef41Sopenharmony_ci  const readable = new Readable({ read() {} });
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  const encoding = 'base64';
431cb0ef41Sopenharmony_ci  const string = Buffer.from('abc').toString(encoding);
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci  readable.on('data', common.mustCall((chunk) => {
461cb0ef41Sopenharmony_ci    assert.strictEqual(chunk.toString(encoding), string);
471cb0ef41Sopenharmony_ci  }, 1));
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  readable.unshift(string, encoding);
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci}
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci{
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  const streamEncoding = 'base64';
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  function checkEncoding(readable) {
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci    // chunk encodings
601cb0ef41Sopenharmony_ci    const encodings = ['utf8', 'binary', 'hex', 'base64'];
611cb0ef41Sopenharmony_ci    const expected = [];
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci    readable.on('data', common.mustCall((chunk) => {
641cb0ef41Sopenharmony_ci      const { encoding, string } = expected.pop();
651cb0ef41Sopenharmony_ci      assert.strictEqual(chunk.toString(encoding), string);
661cb0ef41Sopenharmony_ci    }, encodings.length));
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci    for (const encoding of encodings) {
691cb0ef41Sopenharmony_ci      const string = 'abc';
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci      // If encoding is the same as the state.encoding the string is
721cb0ef41Sopenharmony_ci      // saved as is
731cb0ef41Sopenharmony_ci      const expect = encoding !== streamEncoding ?
741cb0ef41Sopenharmony_ci        Buffer.from(string, encoding).toString(streamEncoding) : string;
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci      expected.push({ encoding, string: expect });
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci      readable.unshift(string, encoding);
791cb0ef41Sopenharmony_ci    }
801cb0ef41Sopenharmony_ci  }
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci  const r1 = new Readable({ read() {} });
831cb0ef41Sopenharmony_ci  r1.setEncoding(streamEncoding);
841cb0ef41Sopenharmony_ci  checkEncoding(r1);
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci  const r2 = new Readable({ read() {}, encoding: streamEncoding });
871cb0ef41Sopenharmony_ci  checkEncoding(r2);
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci}
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci{
921cb0ef41Sopenharmony_ci  // Both .push & .unshift should have the same behaviour
931cb0ef41Sopenharmony_ci  // When setting an encoding, each chunk should be emitted with that encoding
941cb0ef41Sopenharmony_ci  const encoding = 'base64';
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci  function checkEncoding(readable) {
971cb0ef41Sopenharmony_ci    const string = 'abc';
981cb0ef41Sopenharmony_ci    readable.on('data', common.mustCall((chunk) => {
991cb0ef41Sopenharmony_ci      assert.strictEqual(chunk, Buffer.from(string).toString(encoding));
1001cb0ef41Sopenharmony_ci    }, 2));
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci    readable.push(string);
1031cb0ef41Sopenharmony_ci    readable.unshift(string);
1041cb0ef41Sopenharmony_ci  }
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci  const r1 = new Readable({ read() {} });
1071cb0ef41Sopenharmony_ci  r1.setEncoding(encoding);
1081cb0ef41Sopenharmony_ci  checkEncoding(r1);
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  const r2 = new Readable({ read() {}, encoding });
1111cb0ef41Sopenharmony_ci  checkEncoding(r2);
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci}
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci{
1161cb0ef41Sopenharmony_ci  // Check that ObjectMode works
1171cb0ef41Sopenharmony_ci  const readable = new Readable({ objectMode: true, read() {} });
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci  const chunks = ['a', 1, {}, []];
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ci  readable.on('data', common.mustCall((chunk) => {
1221cb0ef41Sopenharmony_ci    assert.strictEqual(chunk, chunks.pop());
1231cb0ef41Sopenharmony_ci  }, chunks.length));
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci  for (const chunk of chunks) {
1261cb0ef41Sopenharmony_ci    readable.unshift(chunk);
1271cb0ef41Sopenharmony_ci  }
1281cb0ef41Sopenharmony_ci}
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci{
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci  // Should not throw: https://github.com/nodejs/node/issues/27192
1331cb0ef41Sopenharmony_ci  const highWaterMark = 50;
1341cb0ef41Sopenharmony_ci  class ArrayReader extends Readable {
1351cb0ef41Sopenharmony_ci    constructor(opt) {
1361cb0ef41Sopenharmony_ci      super({ highWaterMark });
1371cb0ef41Sopenharmony_ci      // The error happened only when pushing above hwm
1381cb0ef41Sopenharmony_ci      this.buffer = new Array(highWaterMark * 2).fill(0).map(String);
1391cb0ef41Sopenharmony_ci    }
1401cb0ef41Sopenharmony_ci    _read(size) {
1411cb0ef41Sopenharmony_ci      while (this.buffer.length) {
1421cb0ef41Sopenharmony_ci        const chunk = this.buffer.shift();
1431cb0ef41Sopenharmony_ci        if (!this.buffer.length) {
1441cb0ef41Sopenharmony_ci          this.push(chunk);
1451cb0ef41Sopenharmony_ci          this.push(null);
1461cb0ef41Sopenharmony_ci          return true;
1471cb0ef41Sopenharmony_ci        }
1481cb0ef41Sopenharmony_ci        if (!this.push(chunk))
1491cb0ef41Sopenharmony_ci          return;
1501cb0ef41Sopenharmony_ci      }
1511cb0ef41Sopenharmony_ci    }
1521cb0ef41Sopenharmony_ci  }
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci  function onRead() {
1551cb0ef41Sopenharmony_ci    while (null !== (stream.read())) {
1561cb0ef41Sopenharmony_ci      // Remove the 'readable' listener before unshifting
1571cb0ef41Sopenharmony_ci      stream.removeListener('readable', onRead);
1581cb0ef41Sopenharmony_ci      stream.unshift('a');
1591cb0ef41Sopenharmony_ci      stream.on('data', (chunk) => {
1601cb0ef41Sopenharmony_ci        console.log(chunk.length);
1611cb0ef41Sopenharmony_ci      });
1621cb0ef41Sopenharmony_ci      break;
1631cb0ef41Sopenharmony_ci    }
1641cb0ef41Sopenharmony_ci  }
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci  const stream = new ArrayReader();
1671cb0ef41Sopenharmony_ci  stream.once('readable', common.mustCall(onRead));
1681cb0ef41Sopenharmony_ci  stream.on('end', common.mustCall());
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci}
171