1'use strict'; 2 3const common = require('../common'); 4const { Writable, Readable, Transform, finished } = require('stream'); 5const assert = require('assert'); 6const EE = require('events'); 7const fs = require('fs'); 8const { promisify } = require('util'); 9 10{ 11 const rs = new Readable({ 12 read() {} 13 }); 14 15 finished(rs, common.mustCall((err) => { 16 assert(!err, 'no error'); 17 })); 18 19 rs.push(null); 20 rs.resume(); 21} 22 23{ 24 const ws = new Writable({ 25 write(data, enc, cb) { 26 cb(); 27 } 28 }); 29 30 finished(ws, common.mustCall((err) => { 31 assert(!err, 'no error'); 32 })); 33 34 ws.end(); 35} 36 37{ 38 const tr = new Transform({ 39 transform(data, enc, cb) { 40 cb(); 41 } 42 }); 43 44 let finish = false; 45 let ended = false; 46 47 tr.on('end', () => { 48 ended = true; 49 }); 50 51 tr.on('finish', () => { 52 finish = true; 53 }); 54 55 finished(tr, common.mustCall((err) => { 56 assert(!err, 'no error'); 57 assert(finish); 58 assert(ended); 59 })); 60 61 tr.end(); 62 tr.resume(); 63} 64 65{ 66 const rs = fs.createReadStream(__filename); 67 68 rs.resume(); 69 finished(rs, common.mustCall()); 70} 71 72{ 73 const finishedPromise = promisify(finished); 74 75 async function run() { 76 const rs = fs.createReadStream(__filename); 77 const done = common.mustCall(); 78 79 let ended = false; 80 rs.resume(); 81 rs.on('end', () => { 82 ended = true; 83 }); 84 await finishedPromise(rs); 85 assert(ended); 86 done(); 87 } 88 89 run(); 90} 91 92{ 93 const rs = fs.createReadStream('file-does-not-exist'); 94 95 finished(rs, common.expectsError({ 96 code: 'ENOENT' 97 })); 98} 99 100{ 101 const rs = new Readable(); 102 103 finished(rs, common.mustCall((err) => { 104 assert(!err, 'no error'); 105 })); 106 107 rs.push(null); 108 rs.emit('close'); // Should not trigger an error 109 rs.resume(); 110} 111 112{ 113 const rs = new Readable(); 114 115 finished(rs, common.mustCall((err) => { 116 assert(err, 'premature close error'); 117 })); 118 119 rs.emit('close'); // Should trigger error 120 rs.push(null); 121 rs.resume(); 122} 123 124// Test faulty input values and options. 125{ 126 const rs = new Readable({ 127 read() {} 128 }); 129 130 assert.throws( 131 () => finished(rs, 'foo'), 132 { 133 code: 'ERR_INVALID_ARG_TYPE', 134 message: /callback/ 135 } 136 ); 137 assert.throws( 138 () => finished(rs, 'foo', () => {}), 139 { 140 code: 'ERR_INVALID_ARG_TYPE', 141 message: /opts/ 142 } 143 ); 144 assert.throws( 145 () => finished(rs, {}, 'foo'), 146 { 147 code: 'ERR_INVALID_ARG_TYPE', 148 message: /callback/ 149 } 150 ); 151 152 finished(rs, null, common.mustCall()); 153 154 rs.push(null); 155 rs.resume(); 156} 157 158// Test that calling returned function removes listeners 159{ 160 const ws = new Writable({ 161 write(data, env, cb) { 162 cb(); 163 } 164 }); 165 const removeListener = finished(ws, common.mustNotCall()); 166 removeListener(); 167 ws.end(); 168} 169 170{ 171 const rs = new Readable(); 172 const removeListeners = finished(rs, common.mustNotCall()); 173 removeListeners(); 174 175 rs.emit('close'); 176 rs.push(null); 177 rs.resume(); 178} 179 180{ 181 const streamLike = new EE(); 182 streamLike.readableEnded = true; 183 streamLike.readable = true; 184 finished(streamLike, common.mustCall); 185 streamLike.emit('close'); 186} 187 188 189{ 190 // Test is readable check through readable 191 const streamLike = new EE(); 192 streamLike.readable = false; 193 finished(streamLike, common.mustCall()); 194 streamLike.emit('end'); 195} 196 197{ 198 // Test is readable check through readableEnded 199 const streamLike = new EE(); 200 streamLike.readableEnded = true; 201 finished(streamLike, common.mustCall()); 202 streamLike.emit('end'); 203} 204 205{ 206 // Test is readable check through _readableState 207 const streamLike = new EE(); 208 streamLike._readableState = {}; 209 finished(streamLike, common.mustCall()); 210 streamLike.emit('end'); 211} 212 213{ 214 // Test is writable check through writable 215 const streamLike = new EE(); 216 streamLike.writable = false; 217 finished(streamLike, common.mustCall()); 218 streamLike.emit('finish'); 219} 220 221{ 222 // Test is writable check through writableEnded 223 const streamLike = new EE(); 224 streamLike.writableEnded = true; 225 finished(streamLike, common.mustCall()); 226 streamLike.emit('finish'); 227} 228 229{ 230 // Test is writable check through _writableState 231 const streamLike = new EE(); 232 streamLike._writableState = {}; 233 finished(streamLike, common.mustCall()); 234 streamLike.emit('finish'); 235} 236