1'use strict'; 2require('../common'); 3const assert = require('assert'); 4const { Writable } = require('stream'); 5 6// Test interaction between calling .destroy() on a writable and pending 7// writes. 8 9for (const withPendingData of [ false, true ]) { 10 for (const useEnd of [ false, true ]) { 11 const callbacks = []; 12 13 const w = new Writable({ 14 write(data, enc, cb) { 15 callbacks.push(cb); 16 }, 17 // Effectively disable the HWM to observe 'drain' events more easily. 18 highWaterMark: 1 19 }); 20 21 let chunksWritten = 0; 22 let drains = 0; 23 let finished = false; 24 w.on('drain', () => drains++); 25 w.on('finish', () => finished = true); 26 27 function onWrite(err) { 28 if (err) { 29 assert.strictEqual(w.destroyed, true); 30 assert.strictEqual(err.code, 'ERR_STREAM_DESTROYED'); 31 } else { 32 chunksWritten++; 33 } 34 } 35 36 w.write('abc', onWrite); 37 assert.strictEqual(chunksWritten, 0); 38 assert.strictEqual(drains, 0); 39 callbacks.shift()(); 40 assert.strictEqual(chunksWritten, 1); 41 assert.strictEqual(drains, 1); 42 43 if (withPendingData) { 44 // Test 2 cases: There either is or is not data still in the write queue. 45 // (The second write will never actually get executed either way.) 46 w.write('def', onWrite); 47 } 48 if (useEnd) { 49 // Again, test 2 cases: Either we indicate that we want to end the 50 // writable or not. 51 w.end('ghi', onWrite); 52 } else { 53 w.write('ghi', onWrite); 54 } 55 56 assert.strictEqual(chunksWritten, 1); 57 w.destroy(); 58 assert.strictEqual(chunksWritten, 1); 59 callbacks.shift()(); 60 assert.strictEqual(chunksWritten, 2); 61 assert.strictEqual(callbacks.length, 0); 62 assert.strictEqual(drains, 1); 63 64 // When we used `.end()`, we see the 'finished' event if and only if 65 // we actually finished processing the write queue. 66 assert.strictEqual(finished, !withPendingData && useEnd); 67 } 68} 69