• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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