|
1 | 1 | 'use strict';
|
2 | 2 |
|
3 | 3 | const common = require('../common');
|
4 |
| -const { Writable, Readable, Transform, finished, Duplex } = require('stream'); |
| 4 | +const { |
| 5 | + Writable, |
| 6 | + Readable, |
| 7 | + Transform, |
| 8 | + finished, |
| 9 | + Duplex, |
| 10 | + PassThrough |
| 11 | +} = require('stream'); |
5 | 12 | const assert = require('assert');
|
6 | 13 | const EE = require('events');
|
7 | 14 | const fs = require('fs');
|
@@ -396,3 +403,80 @@ testClosed((opts) => new Writable({ write() {}, ...opts }));
|
396 | 403 | r.destroyed = true;
|
397 | 404 | r.push(null);
|
398 | 405 | }
|
| 406 | + |
| 407 | +{ |
| 408 | + // Regression https://github.com/nodejs/node/issues/33130 |
| 409 | + const response = new PassThrough(); |
| 410 | + |
| 411 | + class HelloWorld extends Duplex { |
| 412 | + constructor(response) { |
| 413 | + super({ |
| 414 | + autoDestroy: false |
| 415 | + }); |
| 416 | + |
| 417 | + this.response = response; |
| 418 | + this.readMore = false; |
| 419 | + |
| 420 | + response.once('end', () => { |
| 421 | + this.push(null); |
| 422 | + }); |
| 423 | + |
| 424 | + response.on('readable', () => { |
| 425 | + if (this.readMore) { |
| 426 | + this._read(); |
| 427 | + } |
| 428 | + }); |
| 429 | + } |
| 430 | + |
| 431 | + _read() { |
| 432 | + const { response } = this; |
| 433 | + |
| 434 | + this.readMore = true; |
| 435 | + |
| 436 | + if (response.readableLength) { |
| 437 | + this.readMore = false; |
| 438 | + } |
| 439 | + |
| 440 | + let data; |
| 441 | + while ((data = response.read()) !== null) { |
| 442 | + this.push(data); |
| 443 | + } |
| 444 | + } |
| 445 | + } |
| 446 | + |
| 447 | + const instance = new HelloWorld(response); |
| 448 | + instance.setEncoding('utf8'); |
| 449 | + instance.end(); |
| 450 | + |
| 451 | + (async () => { |
| 452 | + await EE.once(instance, 'finish'); |
| 453 | + |
| 454 | + setImmediate(() => { |
| 455 | + response.write('chunk 1'); |
| 456 | + response.write('chunk 2'); |
| 457 | + response.write('chunk 3'); |
| 458 | + response.end(); |
| 459 | + }); |
| 460 | + |
| 461 | + let res = ''; |
| 462 | + for await (const data of instance) { |
| 463 | + res += data; |
| 464 | + } |
| 465 | + |
| 466 | + assert.strictEqual(res, 'chunk 1chunk 2chunk 3'); |
| 467 | + })().then(common.mustCall()); |
| 468 | +} |
| 469 | + |
| 470 | +{ |
| 471 | + const p = new PassThrough(); |
| 472 | + p.end(); |
| 473 | + finished(p, common.mustNotCall()); |
| 474 | +} |
| 475 | + |
| 476 | +{ |
| 477 | + const p = new PassThrough(); |
| 478 | + p.end(); |
| 479 | + p.on('finish', common.mustCall(() => { |
| 480 | + finished(p, common.mustNotCall()); |
| 481 | + })); |
| 482 | +} |
0 commit comments