deno.land / std@0.166.0 / node / _tools / test / parallel / test-stream-writable-destroy.js
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497// deno-fmt-ignore-file// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.// Taken from Node 18.12.0// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually
'use strict';
const common = require('../common');const { Writable, addAbortSignal } = 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) { this.destroy(new Error('asd')); cb(); } });
write.on('error', common.mustCall()); write.on('finish', common.mustNotCall()); write.end('asd'); 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();
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(); } });
let ticked = false; write.on('close', common.mustCall(() => { assert.strictEqual(ticked, true); })); write.on('error', common.mustCall((err) => { assert.strictEqual(ticked, true); assert.strictEqual(err.message, 'kaboom 1'); assert.strictEqual(write._writableState.errorEmitted, true); }));
const expected = new Error('kaboom 1'); write.destroy(expected); write.destroy(new Error('kaboom 2')); assert.strictEqual(write._writableState.errored, expected); assert.strictEqual(write._writableState.errorEmitted, false); assert.strictEqual(write.destroyed, true); ticked = true;}
{ const writable = new Writable({ destroy: common.mustCall(function(err, cb) { process.nextTick(cb, new Error('kaboom 1')); }), write(chunk, enc, cb) { cb(); } });
let ticked = false; writable.on('close', common.mustCall(() => { writable.on('error', common.mustNotCall()); writable.destroy(new Error('hello')); assert.strictEqual(ticked, true); assert.strictEqual(writable._writableState.errorEmitted, true); })); writable.on('error', common.mustCall((err) => { assert.strictEqual(ticked, true); assert.strictEqual(err.message, 'kaboom 1'); assert.strictEqual(writable._writableState.errorEmitted, true); }));
writable.destroy(); assert.strictEqual(writable.destroyed, true); assert.strictEqual(writable._writableState.errored, null); 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, false); assert.strictEqual(writable._writableState.errored, null);
ticked = 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((err) => { assert.strictEqual(err, undefined); }));}
{ // 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), autoDestroy: true });
write.end(); write.once('close', common.mustCall(() => { write._undestroy(); write.end(); }));}
{ const write = new Writable();
write.destroy(); write.on('error', common.mustNotCall()); write.write('asd', common.expectsError({ name: 'Error', code: 'ERR_STREAM_DESTROYED', message: 'Cannot call write after a stream was destroyed' }));}
{ const write = new Writable({ write(chunk, enc, cb) { cb(); } });
write.on('error', common.mustNotCall());
write.cork(); write.write('asd', common.mustCall()); write.uncork();
write.cork(); write.write('asd', common.expectsError({ name: 'Error', code: 'ERR_STREAM_DESTROYED', message: 'Cannot call write after a stream was destroyed' })); write.destroy(); write.write('asd', common.expectsError({ name: 'Error', code: 'ERR_STREAM_DESTROYED', message: 'Cannot call write after a stream was destroyed' })); write.uncork();}
{ // Call end(cb) after error & destroy
const write = new Writable({ write(chunk, enc, cb) { cb(new Error('asd')); } }); write.on('error', common.mustCall(() => { write.destroy(); let ticked = false; write.end(common.mustCall((err) => { assert.strictEqual(ticked, true); assert.strictEqual(err.code, 'ERR_STREAM_DESTROYED'); })); ticked = true; })); write.write('asd');}
{ // Call end(cb) after finish & destroy
const write = new Writable({ write(chunk, enc, cb) { cb(); } }); write.on('finish', common.mustCall(() => { write.destroy(); let ticked = false; write.end(common.mustCall((err) => { assert.strictEqual(ticked, true); assert.strictEqual(err.code, 'ERR_STREAM_ALREADY_FINISHED'); })); ticked = true; })); write.end();}
{ // Call end(cb) after error & destroy and don't trigger // unhandled exception.
const write = new Writable({ write(chunk, enc, cb) { process.nextTick(cb); } }); const _err = new Error('asd'); write.once('error', common.mustCall((err) => { assert.strictEqual(err.message, 'asd'); })); write.end('asd', common.mustCall((err) => { assert.strictEqual(err, _err); })); write.destroy(_err);}
{ // Call buffered write callback with error
const _err = new Error('asd'); const write = new Writable({ write(chunk, enc, cb) { process.nextTick(cb, _err); }, autoDestroy: false }); write.cork(); write.write('asd', common.mustCall((err) => { assert.strictEqual(err, _err); })); write.write('asd', common.mustCall((err) => { assert.strictEqual(err, _err); })); write.on('error', common.mustCall((err) => { assert.strictEqual(err, _err); })); write.uncork();}
{ // Ensure callback order.
let state = 0; const write = new Writable({ write(chunk, enc, cb) { // `setImmediate()` is used on purpose to ensure the callback is called // after `process.nextTick()` callbacks. setImmediate(cb); } }); write.write('asd', common.mustCall(() => { assert.strictEqual(state++, 0); })); write.write('asd', common.mustCall((err) => { assert.strictEqual(err.code, 'ERR_STREAM_DESTROYED'); assert.strictEqual(state++, 1); })); write.destroy();}
{ const write = new Writable({ autoDestroy: false, write(chunk, enc, cb) { cb(); cb(); } });
write.on('error', common.mustCall(() => { assert(write._writableState.errored); })); write.write('asd');}
{ const ac = new AbortController(); const write = addAbortSignal(ac.signal, new Writable({ write(chunk, enc, cb) { cb(); } }));
write.on('error', common.mustCall((e) => { assert.strictEqual(e.name, 'AbortError'); assert.strictEqual(write.destroyed, true); })); write.write('asd'); ac.abort();}
{ const ac = new AbortController(); const write = new Writable({ signal: ac.signal, write(chunk, enc, cb) { cb(); } });
write.on('error', common.mustCall((e) => { assert.strictEqual(e.name, 'AbortError'); assert.strictEqual(write.destroyed, true); })); write.write('asd'); ac.abort();}
{ const signal = AbortSignal.abort();
const write = new Writable({ signal, write(chunk, enc, cb) { cb(); } });
write.on('error', common.mustCall((e) => { assert.strictEqual(e.name, 'AbortError'); assert.strictEqual(write.destroyed, true); }));}
{ // Destroy twice const write = new Writable({ write(chunk, enc, cb) { cb(); } });
write.end(common.mustCall()); write.destroy(); write.destroy();}
{ // https://github.com/nodejs/node/issues/39356 const s = new Writable({ final() {} }); const _err = new Error('oh no'); // Remove `callback` and it works s.end(common.mustCall((err) => { assert.strictEqual(err, _err); })); s.on('error', common.mustCall((err) => { assert.strictEqual(err, _err); })); s.destroy(_err);}
Version Info