| 'use strict'; |
| |
| const common = require('../common'); |
| const { Writable } = require('stream'); |
| const assert = require('assert'); |
| |
| { |
| const write = new Writable({ |
| write(chunk, enc, cb) { cb(); } |
| }); |
| |
| write.on('finish', common.mustNotCall()); |
| write.on('close', common.mustCall()); |
| |
| write.destroy(); |
| assert.strictEqual(write.destroyed, true); |
| } |
| |
| { |
| const write = new Writable({ |
| write(chunk, enc, cb) { cb(); } |
| }); |
| |
| const expected = new Error('kaboom'); |
| |
| write.on('finish', common.mustNotCall()); |
| write.on('close', common.mustCall()); |
| write.on('error', common.mustCall((err) => { |
| assert.strictEqual(err, expected); |
| })); |
| |
| write.destroy(expected); |
| assert.strictEqual(write.destroyed, true); |
| } |
| |
| { |
| const write = new Writable({ |
| write(chunk, enc, cb) { cb(); } |
| }); |
| |
| write._destroy = function(err, cb) { |
| assert.strictEqual(err, expected); |
| cb(err); |
| }; |
| |
| const expected = new Error('kaboom'); |
| |
| write.on('finish', common.mustNotCall('no finish event')); |
| write.on('close', common.mustCall()); |
| write.on('error', common.mustCall((err) => { |
| assert.strictEqual(err, expected); |
| })); |
| |
| write.destroy(expected); |
| assert.strictEqual(write.destroyed, true); |
| } |
| |
| { |
| const write = new Writable({ |
| write(chunk, enc, cb) { cb(); }, |
| destroy: common.mustCall(function(err, cb) { |
| assert.strictEqual(err, expected); |
| cb(); |
| }) |
| }); |
| |
| const expected = new Error('kaboom'); |
| |
| write.on('finish', common.mustNotCall('no finish event')); |
| write.on('close', common.mustCall()); |
| |
| // Error is swallowed by the custom _destroy |
| write.on('error', common.mustNotCall('no error event')); |
| |
| write.destroy(expected); |
| assert.strictEqual(write.destroyed, true); |
| } |
| |
| { |
| const write = new Writable({ |
| write(chunk, enc, cb) { cb(); } |
| }); |
| |
| write._destroy = common.mustCall(function(err, cb) { |
| assert.strictEqual(err, null); |
| cb(); |
| }); |
| |
| write.destroy(); |
| assert.strictEqual(write.destroyed, true); |
| } |
| |
| { |
| const write = new Writable({ |
| write(chunk, enc, cb) { cb(); } |
| }); |
| |
| write._destroy = common.mustCall(function(err, cb) { |
| assert.strictEqual(err, null); |
| process.nextTick(() => { |
| this.end(); |
| cb(); |
| }); |
| }); |
| |
| const fail = common.mustNotCall('no finish event'); |
| |
| write.on('finish', fail); |
| write.on('close', common.mustCall()); |
| |
| write.destroy(); |
| |
| write.removeListener('finish', fail); |
| write.on('finish', common.mustCall()); |
| assert.strictEqual(write.destroyed, true); |
| } |
| |
| { |
| const write = new Writable({ |
| write(chunk, enc, cb) { cb(); } |
| }); |
| |
| const expected = new Error('kaboom'); |
| |
| write._destroy = common.mustCall(function(err, cb) { |
| assert.strictEqual(err, null); |
| cb(expected); |
| }); |
| |
| write.on('close', common.mustCall()); |
| write.on('finish', common.mustNotCall('no finish event')); |
| write.on('error', common.mustCall((err) => { |
| assert.strictEqual(err, expected); |
| })); |
| |
| write.destroy(); |
| assert.strictEqual(write.destroyed, true); |
| } |
| |
| { |
| // double error case |
| const write = new Writable({ |
| write(chunk, enc, cb) { cb(); } |
| }); |
| |
| write.on('close', common.mustCall()); |
| write.on('error', common.mustCall()); |
| |
| write.destroy(new Error('kaboom 1')); |
| write.destroy(new Error('kaboom 2')); |
| assert.strictEqual(write._writableState.errorEmitted, true); |
| assert.strictEqual(write.destroyed, true); |
| } |
| |
| { |
| const writable = new Writable({ |
| destroy: common.mustCall(function(err, cb) { |
| process.nextTick(cb, new Error('kaboom 1')); |
| }), |
| write(chunk, enc, cb) { |
| cb(); |
| } |
| }); |
| |
| writable.on('close', common.mustCall()); |
| writable.on('error', common.expectsError({ |
| type: Error, |
| message: 'kaboom 2' |
| })); |
| |
| writable.destroy(); |
| assert.strictEqual(writable.destroyed, true); |
| assert.strictEqual(writable._writableState.errorEmitted, false); |
| |
| // Test case where `writable.destroy()` is called again with an error before |
| // the `_destroy()` callback is called. |
| writable.destroy(new Error('kaboom 2')); |
| assert.strictEqual(writable._writableState.errorEmitted, true); |
| } |
| |
| { |
| const write = new Writable({ |
| write(chunk, enc, cb) { cb(); } |
| }); |
| |
| write.destroyed = true; |
| assert.strictEqual(write.destroyed, true); |
| |
| // The internal destroy() mechanism should not be triggered |
| write.on('close', common.mustNotCall()); |
| write.destroy(); |
| } |
| |
| { |
| function MyWritable() { |
| assert.strictEqual(this.destroyed, false); |
| this.destroyed = false; |
| Writable.call(this); |
| } |
| |
| Object.setPrototypeOf(MyWritable.prototype, Writable.prototype); |
| Object.setPrototypeOf(MyWritable, Writable); |
| |
| new MyWritable(); |
| } |
| |
| { |
| // Destroy and destroy callback |
| const write = new Writable({ |
| write(chunk, enc, cb) { cb(); } |
| }); |
| |
| write.destroy(); |
| |
| const expected = new Error('kaboom'); |
| |
| write.destroy(expected, common.mustCall(function(err) { |
| assert.strictEqual(err, expected); |
| })); |
| } |
| |
| { |
| // Checks that `._undestroy()` restores the state so that `final` will be |
| // called again. |
| const write = new Writable({ |
| write: common.mustNotCall(), |
| final: common.mustCall((cb) => cb(), 2) |
| }); |
| |
| write.end(); |
| write.destroy(); |
| write._undestroy(); |
| write.end(); |
| } |