1'use strict'; 2 3const common = require('../common'); 4const { Writable, Readable, Duplex } = require('stream'); 5const assert = require('assert'); 6 7{ 8 // Multiple callback. 9 new Writable({ 10 construct: common.mustCall((callback) => { 11 callback(); 12 callback(); 13 }) 14 }).on('error', common.expectsError({ 15 name: 'Error', 16 code: 'ERR_MULTIPLE_CALLBACK' 17 })); 18} 19 20{ 21 // Multiple callback. 22 new Readable({ 23 construct: common.mustCall((callback) => { 24 callback(); 25 callback(); 26 }) 27 }).on('error', common.expectsError({ 28 name: 'Error', 29 code: 'ERR_MULTIPLE_CALLBACK' 30 })); 31} 32 33{ 34 // Synchronous error. 35 36 new Writable({ 37 construct: common.mustCall((callback) => { 38 callback(new Error('test')); 39 }) 40 }).on('error', common.expectsError({ 41 name: 'Error', 42 message: 'test' 43 })); 44} 45 46{ 47 // Synchronous error. 48 49 new Readable({ 50 construct: common.mustCall((callback) => { 51 callback(new Error('test')); 52 }) 53 }).on('error', common.expectsError({ 54 name: 'Error', 55 message: 'test' 56 })); 57} 58 59{ 60 // Asynchronous error. 61 62 new Writable({ 63 construct: common.mustCall((callback) => { 64 process.nextTick(callback, new Error('test')); 65 }) 66 }).on('error', common.expectsError({ 67 name: 'Error', 68 message: 'test' 69 })); 70} 71 72{ 73 // Asynchronous error. 74 75 new Readable({ 76 construct: common.mustCall((callback) => { 77 process.nextTick(callback, new Error('test')); 78 }) 79 }).on('error', common.expectsError({ 80 name: 'Error', 81 message: 'test' 82 })); 83} 84 85function testDestroy(factory) { 86 { 87 let constructed = false; 88 const s = factory({ 89 construct: common.mustCall((cb) => { 90 constructed = true; 91 process.nextTick(cb); 92 }) 93 }); 94 s.on('close', common.mustCall(() => { 95 assert.strictEqual(constructed, true); 96 })); 97 s.destroy(); 98 } 99 100 { 101 let constructed = false; 102 const s = factory({ 103 construct: common.mustCall((cb) => { 104 constructed = true; 105 process.nextTick(cb); 106 }) 107 }); 108 s.on('close', common.mustCall(() => { 109 assert.strictEqual(constructed, true); 110 })); 111 s.destroy(null, () => { 112 assert.strictEqual(constructed, true); 113 }); 114 } 115 116 { 117 let constructed = false; 118 const s = factory({ 119 construct: common.mustCall((cb) => { 120 constructed = true; 121 process.nextTick(cb); 122 }) 123 }); 124 s.on('close', common.mustCall(() => { 125 assert.strictEqual(constructed, true); 126 })); 127 s.destroy(); 128 } 129 130 131 { 132 let constructed = false; 133 const s = factory({ 134 construct: common.mustCall((cb) => { 135 constructed = true; 136 process.nextTick(cb); 137 }) 138 }); 139 s.on('close', common.mustCall(() => { 140 assert.strictEqual(constructed, true); 141 })); 142 s.on('error', common.mustCall((err) => { 143 assert.strictEqual(err.message, 'kaboom'); 144 })); 145 s.destroy(new Error('kaboom'), (err) => { 146 assert.strictEqual(err.message, 'kaboom'); 147 assert.strictEqual(constructed, true); 148 }); 149 } 150 151 { 152 let constructed = false; 153 const s = factory({ 154 construct: common.mustCall((cb) => { 155 constructed = true; 156 process.nextTick(cb); 157 }) 158 }); 159 s.on('error', common.mustCall(() => { 160 assert.strictEqual(constructed, true); 161 })); 162 s.on('close', common.mustCall(() => { 163 assert.strictEqual(constructed, true); 164 })); 165 s.destroy(new Error()); 166 } 167} 168testDestroy((opts) => new Readable({ 169 read: common.mustNotCall(), 170 ...opts 171})); 172testDestroy((opts) => new Writable({ 173 write: common.mustNotCall(), 174 final: common.mustNotCall(), 175 ...opts 176})); 177 178{ 179 let constructed = false; 180 const r = new Readable({ 181 autoDestroy: true, 182 construct: common.mustCall((cb) => { 183 constructed = true; 184 process.nextTick(cb); 185 }), 186 read: common.mustCall(() => { 187 assert.strictEqual(constructed, true); 188 r.push(null); 189 }) 190 }); 191 r.on('close', common.mustCall(() => { 192 assert.strictEqual(constructed, true); 193 })); 194 r.on('data', common.mustNotCall()); 195} 196 197{ 198 let constructed = false; 199 const w = new Writable({ 200 autoDestroy: true, 201 construct: common.mustCall((cb) => { 202 constructed = true; 203 process.nextTick(cb); 204 }), 205 write: common.mustCall((chunk, encoding, cb) => { 206 assert.strictEqual(constructed, true); 207 process.nextTick(cb); 208 }), 209 final: common.mustCall((cb) => { 210 assert.strictEqual(constructed, true); 211 process.nextTick(cb); 212 }) 213 }); 214 w.on('close', common.mustCall(() => { 215 assert.strictEqual(constructed, true); 216 })); 217 w.end('data'); 218} 219 220{ 221 let constructed = false; 222 const w = new Writable({ 223 autoDestroy: true, 224 construct: common.mustCall((cb) => { 225 constructed = true; 226 process.nextTick(cb); 227 }), 228 write: common.mustNotCall(), 229 final: common.mustCall((cb) => { 230 assert.strictEqual(constructed, true); 231 process.nextTick(cb); 232 }) 233 }); 234 w.on('close', common.mustCall(() => { 235 assert.strictEqual(constructed, true); 236 })); 237 w.end(); 238} 239 240{ 241 new Duplex({ 242 construct: common.mustCall() 243 }); 244} 245 246{ 247 // https://github.com/nodejs/node/issues/34448 248 249 let constructed = false; 250 const d = new Duplex({ 251 readable: false, 252 construct: common.mustCall((callback) => { 253 setImmediate(common.mustCall(() => { 254 constructed = true; 255 callback(); 256 })); 257 }), 258 write(chunk, encoding, callback) { 259 callback(); 260 }, 261 read() { 262 this.push(null); 263 } 264 }); 265 d.resume(); 266 d.end('foo'); 267 d.on('close', common.mustCall(() => { 268 assert.strictEqual(constructed, true); 269 })); 270} 271 272{ 273 // Construct should not cause stream to read. 274 new Readable({ 275 construct: common.mustCall((callback) => { 276 callback(); 277 }), 278 read: common.mustNotCall() 279 }); 280} 281