1'use strict'; 2 3const common = require('../common'); 4const assert = require('assert'); 5const { Readable } = require('stream'); 6 7{ 8 // Check that strings are saved as Buffer 9 const readable = new Readable({ read() {} }); 10 11 const string = 'abc'; 12 13 readable.on('data', common.mustCall((chunk) => { 14 assert(Buffer.isBuffer(chunk)); 15 assert.strictEqual(chunk.toString('utf8'), string); 16 }, 1)); 17 18 readable.unshift(string); 19 20} 21 22{ 23 // Check that data goes at the beginning 24 const readable = new Readable({ read() {} }); 25 const unshift = 'front'; 26 const push = 'back'; 27 28 const expected = [unshift, push]; 29 readable.on('data', common.mustCall((chunk) => { 30 assert.strictEqual(chunk.toString('utf8'), expected.shift()); 31 }, 2)); 32 33 34 readable.push(push); 35 readable.unshift(unshift); 36} 37 38{ 39 // Check that buffer is saved with correct encoding 40 const readable = new Readable({ read() {} }); 41 42 const encoding = 'base64'; 43 const string = Buffer.from('abc').toString(encoding); 44 45 readable.on('data', common.mustCall((chunk) => { 46 assert.strictEqual(chunk.toString(encoding), string); 47 }, 1)); 48 49 readable.unshift(string, encoding); 50 51} 52 53{ 54 55 const streamEncoding = 'base64'; 56 57 function checkEncoding(readable) { 58 59 // chunk encodings 60 const encodings = ['utf8', 'binary', 'hex', 'base64']; 61 const expected = []; 62 63 readable.on('data', common.mustCall((chunk) => { 64 const { encoding, string } = expected.pop(); 65 assert.strictEqual(chunk.toString(encoding), string); 66 }, encodings.length)); 67 68 for (const encoding of encodings) { 69 const string = 'abc'; 70 71 // If encoding is the same as the state.encoding the string is 72 // saved as is 73 const expect = encoding !== streamEncoding ? 74 Buffer.from(string, encoding).toString(streamEncoding) : string; 75 76 expected.push({ encoding, string: expect }); 77 78 readable.unshift(string, encoding); 79 } 80 } 81 82 const r1 = new Readable({ read() {} }); 83 r1.setEncoding(streamEncoding); 84 checkEncoding(r1); 85 86 const r2 = new Readable({ read() {}, encoding: streamEncoding }); 87 checkEncoding(r2); 88 89} 90 91{ 92 // Both .push & .unshift should have the same behaviour 93 // When setting an encoding, each chunk should be emitted with that encoding 94 const encoding = 'base64'; 95 96 function checkEncoding(readable) { 97 const string = 'abc'; 98 readable.on('data', common.mustCall((chunk) => { 99 assert.strictEqual(chunk, Buffer.from(string).toString(encoding)); 100 }, 2)); 101 102 readable.push(string); 103 readable.unshift(string); 104 } 105 106 const r1 = new Readable({ read() {} }); 107 r1.setEncoding(encoding); 108 checkEncoding(r1); 109 110 const r2 = new Readable({ read() {}, encoding }); 111 checkEncoding(r2); 112 113} 114 115{ 116 // Check that ObjectMode works 117 const readable = new Readable({ objectMode: true, read() {} }); 118 119 const chunks = ['a', 1, {}, []]; 120 121 readable.on('data', common.mustCall((chunk) => { 122 assert.strictEqual(chunk, chunks.pop()); 123 }, chunks.length)); 124 125 for (const chunk of chunks) { 126 readable.unshift(chunk); 127 } 128} 129 130{ 131 132 // Should not throw: https://github.com/nodejs/node/issues/27192 133 const highWaterMark = 50; 134 class ArrayReader extends Readable { 135 constructor(opt) { 136 super({ highWaterMark }); 137 // The error happened only when pushing above hwm 138 this.buffer = new Array(highWaterMark * 2).fill(0).map(String); 139 } 140 _read(size) { 141 while (this.buffer.length) { 142 const chunk = this.buffer.shift(); 143 if (!this.buffer.length) { 144 this.push(chunk); 145 this.push(null); 146 return true; 147 } 148 if (!this.push(chunk)) 149 return; 150 } 151 } 152 } 153 154 function onRead() { 155 while (null !== (stream.read())) { 156 // Remove the 'readable' listener before unshifting 157 stream.removeListener('readable', onRead); 158 stream.unshift('a'); 159 stream.on('data', (chunk) => { 160 console.log(chunk.length); 161 }); 162 break; 163 } 164 } 165 166 const stream = new ArrayReader(); 167 stream.once('readable', common.mustCall(onRead)); 168 stream.on('end', common.mustCall()); 169 170} 171