• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4const { Readable } = require('stream');
5const assert = require('assert');
6
7{
8  const read = new Readable({
9    read() {}
10  });
11  read.resume();
12
13  read.on('close', common.mustCall());
14
15  read.destroy();
16  assert.strictEqual(read.destroyed, true);
17}
18
19{
20  const read = new Readable({
21    read() {}
22  });
23  read.resume();
24
25  const expected = new Error('kaboom');
26
27  read.on('end', common.mustNotCall('no end event'));
28  read.on('close', common.mustCall());
29  read.on('error', common.mustCall((err) => {
30    assert.strictEqual(err, expected);
31  }));
32
33  read.destroy(expected);
34  assert.strictEqual(read.destroyed, true);
35}
36
37{
38  const read = new Readable({
39    read() {}
40  });
41
42  read._destroy = common.mustCall(function(err, cb) {
43    assert.strictEqual(err, expected);
44    cb(err);
45  });
46
47  const expected = new Error('kaboom');
48
49  read.on('end', common.mustNotCall('no end event'));
50  read.on('close', common.mustCall());
51  read.on('error', common.mustCall((err) => {
52    assert.strictEqual(err, expected);
53  }));
54
55  read.destroy(expected);
56  assert.strictEqual(read.destroyed, true);
57}
58
59{
60  const read = new Readable({
61    read() {},
62    destroy: common.mustCall(function(err, cb) {
63      assert.strictEqual(err, expected);
64      cb();
65    })
66  });
67
68  const expected = new Error('kaboom');
69
70  read.on('end', common.mustNotCall('no end event'));
71
72  // Error is swallowed by the custom _destroy
73  read.on('error', common.mustNotCall('no error event'));
74  read.on('close', common.mustCall());
75
76  read.destroy(expected);
77  assert.strictEqual(read.destroyed, true);
78}
79
80{
81  const read = new Readable({
82    read() {}
83  });
84
85  read._destroy = common.mustCall(function(err, cb) {
86    assert.strictEqual(err, null);
87    cb();
88  });
89
90  read.destroy();
91  assert.strictEqual(read.destroyed, true);
92}
93
94{
95  const read = new Readable({
96    read() {}
97  });
98  read.resume();
99
100  read._destroy = common.mustCall(function(err, cb) {
101    assert.strictEqual(err, null);
102    process.nextTick(() => {
103      this.push(null);
104      cb();
105    });
106  });
107
108  const fail = common.mustNotCall('no end event');
109
110  read.on('end', fail);
111  read.on('close', common.mustCall());
112
113  read.destroy();
114
115  read.removeListener('end', fail);
116  read.on('end', common.mustNotCall());
117  assert.strictEqual(read.destroyed, true);
118}
119
120{
121  const read = new Readable({
122    read() {}
123  });
124
125  const expected = new Error('kaboom');
126
127  read._destroy = common.mustCall(function(err, cb) {
128    assert.strictEqual(err, null);
129    cb(expected);
130  });
131
132  let ticked = false;
133  read.on('end', common.mustNotCall('no end event'));
134  read.on('error', common.mustCall((err) => {
135    assert.strictEqual(ticked, true);
136    assert.strictEqual(read._readableState.errorEmitted, true);
137    assert.strictEqual(read._readableState.errored, expected);
138    assert.strictEqual(err, expected);
139  }));
140
141  read.destroy();
142  assert.strictEqual(read._readableState.errorEmitted, false);
143  assert.strictEqual(read._readableState.errored, expected);
144  assert.strictEqual(read.destroyed, true);
145  ticked = true;
146}
147
148{
149  const read = new Readable({
150    read() {}
151  });
152  read.resume();
153
154  read.destroyed = true;
155  assert.strictEqual(read.destroyed, true);
156
157  // The internal destroy() mechanism should not be triggered
158  read.on('end', common.mustNotCall());
159  read.destroy();
160}
161
162{
163  function MyReadable() {
164    assert.strictEqual(this.destroyed, false);
165    this.destroyed = false;
166    Readable.call(this);
167  }
168
169  Object.setPrototypeOf(MyReadable.prototype, Readable.prototype);
170  Object.setPrototypeOf(MyReadable, Readable);
171
172  new MyReadable();
173}
174
175{
176  // Destroy and destroy callback
177  const read = new Readable({
178    read() {}
179  });
180  read.resume();
181
182  const expected = new Error('kaboom');
183
184  let ticked = false;
185  read.on('close', common.mustCall(() => {
186    assert.strictEqual(read._readableState.errorEmitted, true);
187    assert.strictEqual(ticked, true);
188  }));
189  read.on('error', common.mustCall((err) => {
190    assert.strictEqual(err, expected);
191  }));
192
193  assert.strictEqual(read._readableState.errored, null);
194  assert.strictEqual(read._readableState.errorEmitted, false);
195
196  read.destroy(expected, common.mustCall(function(err) {
197    assert.strictEqual(read._readableState.errored, expected);
198    assert.strictEqual(err, expected);
199  }));
200  assert.strictEqual(read._readableState.errorEmitted, false);
201  assert.strictEqual(read._readableState.errored, expected);
202  ticked = true;
203}
204
205{
206  const readable = new Readable({
207    destroy: common.mustCall(function(err, cb) {
208      process.nextTick(cb, new Error('kaboom 1'));
209    }),
210    read() {}
211  });
212
213  let ticked = false;
214  readable.on('close', common.mustCall(() => {
215    assert.strictEqual(ticked, true);
216    assert.strictEqual(readable._readableState.errorEmitted, true);
217  }));
218  readable.on('error', common.mustCall((err) => {
219    assert.strictEqual(ticked, true);
220    assert.strictEqual(err.message, 'kaboom 1');
221    assert.strictEqual(readable._readableState.errorEmitted, true);
222  }));
223
224  readable.destroy();
225  assert.strictEqual(readable.destroyed, true);
226  assert.strictEqual(readable._readableState.errored, null);
227  assert.strictEqual(readable._readableState.errorEmitted, false);
228
229  // Test case where `readable.destroy()` is called again with an error before
230  // the `_destroy()` callback is called.
231  readable.destroy(new Error('kaboom 2'));
232  assert.strictEqual(readable._readableState.errorEmitted, false);
233  assert.strictEqual(readable._readableState.errored, null);
234
235  ticked = true;
236}
237
238{
239  const read = new Readable({
240    read() {}
241  });
242
243  read.destroy();
244  read.push('hi');
245  read.on('data', common.mustNotCall());
246}
247
248{
249  const read = new Readable({
250    read: common.mustNotCall(function() {})
251  });
252  read.destroy();
253  assert.strictEqual(read.destroyed, true);
254  read.read();
255}
256
257{
258  const read = new Readable({
259    autoDestroy: false,
260    read() {
261      this.push(null);
262      this.push('asd');
263    }
264  });
265
266  read.on('error', common.mustCall(() => {
267    assert(read._readableState.errored);
268  }));
269  read.resume();
270}
271