// deno-fmt-ignore-file // deno-lint-ignore-file // Copyright Joyent and Node contributors. All rights reserved. MIT license. // Taken from Node 20.11.1 // This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually. 'use strict'; const common = require('../common'); const assert = require('assert'); const { EventEmitter, captureRejectionSymbol } = require('events'); const { inherits } = require('util'); // Inherits from EE without a call to the // parent constructor. function NoConstructor() { } // captureRejections param validation { [1, [], function() {}, {}, Infinity, Math.PI, 'meow'].forEach((arg) => { assert.throws( () => new EventEmitter({ captureRejections: arg }), { name: 'TypeError', code: 'ERR_INVALID_ARG_TYPE', message: 'The "options.captureRejections" property must be of type boolean.' + common.invalidArgTypeHelper(arg), } ); }); } inherits(NoConstructor, EventEmitter); function captureRejections() { const ee = new EventEmitter({ captureRejections: true }); const _err = new Error('kaboom'); ee.on('something', common.mustCall(async (value) => { throw _err; })); ee.on('error', common.mustCall((err) => { assert.strictEqual(err, _err); process.nextTick(captureRejectionsTwoHandlers); })); ee.emit('something'); } function captureRejectionsTwoHandlers() { const ee = new EventEmitter({ captureRejections: true }); const _err = new Error('kaboom'); ee.on('something', common.mustCall(async (value) => { throw _err; })); // throw twice ee.on('something', common.mustCall(async (value) => { throw _err; })); let count = 0; ee.on('error', common.mustCall((err) => { assert.strictEqual(err, _err); if (++count === 2) { process.nextTick(defaultValue); } }, 2)); ee.emit('something'); } function defaultValue() { const ee = new EventEmitter(); const _err = new Error('kaboom'); ee.on('something', common.mustCall(async (value) => { throw _err; })); process.removeAllListeners('unhandledRejection'); process.once('unhandledRejection', common.mustCall((err) => { // restore default process.on('unhandledRejection', (err) => { throw err; }); assert.strictEqual(err, _err); process.nextTick(globalSetting); })); ee.emit('something'); } function globalSetting() { assert.strictEqual(EventEmitter.captureRejections, false); EventEmitter.captureRejections = true; const ee = new EventEmitter(); const _err = new Error('kaboom'); ee.on('something', common.mustCall(async (value) => { throw _err; })); ee.on('error', common.mustCall((err) => { assert.strictEqual(err, _err); // restore default EventEmitter.captureRejections = false; process.nextTick(configurable); })); ee.emit('something'); } // We need to be able to configure this for streams, as we would // like to call destroy(err) there. function configurable() { const ee = new EventEmitter({ captureRejections: true }); const _err = new Error('kaboom'); ee.on('something', common.mustCall(async (...args) => { assert.deepStrictEqual(args, [42, 'foobar']); throw _err; })); assert.strictEqual(captureRejectionSymbol, Symbol.for('nodejs.rejection')); ee[captureRejectionSymbol] = common.mustCall((err, type, ...args) => { assert.strictEqual(err, _err); assert.strictEqual(type, 'something'); assert.deepStrictEqual(args, [42, 'foobar']); process.nextTick(globalSettingNoConstructor); }); ee.emit('something', 42, 'foobar'); } function globalSettingNoConstructor() { assert.strictEqual(EventEmitter.captureRejections, false); EventEmitter.captureRejections = true; const ee = new NoConstructor(); const _err = new Error('kaboom'); ee.on('something', common.mustCall(async (value) => { throw _err; })); ee.on('error', common.mustCall((err) => { assert.strictEqual(err, _err); // restore default EventEmitter.captureRejections = false; process.nextTick(thenable); })); ee.emit('something'); } function thenable() { const ee = new EventEmitter({ captureRejections: true }); const _err = new Error('kaboom'); ee.on('something', common.mustCall((value) => { const obj = {}; Object.defineProperty(obj, 'then', { get: common.mustCall(() => { return common.mustCall((resolved, rejected) => { assert.strictEqual(resolved, undefined); rejected(_err); }); }, 1), // Only 1 call for Promises/A+ compat. }); return obj; })); ee.on('error', common.mustCall((err) => { assert.strictEqual(err, _err); process.nextTick(avoidLoopOnRejection); })); ee.emit('something'); } function avoidLoopOnRejection() { const ee = new EventEmitter({ captureRejections: true }); const _err1 = new Error('kaboom'); const _err2 = new Error('kaboom2'); ee.on('something', common.mustCall(async (value) => { throw _err1; })); ee[captureRejectionSymbol] = common.mustCall(async (err) => { assert.strictEqual(err, _err1); throw _err2; }); process.removeAllListeners('unhandledRejection'); process.once('unhandledRejection', common.mustCall((err) => { // restore default process.on('unhandledRejection', (err) => { throw err; }); assert.strictEqual(err, _err2); process.nextTick(avoidLoopOnError); })); ee.emit('something'); } function avoidLoopOnError() { const ee = new EventEmitter({ captureRejections: true }); const _err1 = new Error('kaboom'); const _err2 = new Error('kaboom2'); ee.on('something', common.mustCall(async (value) => { throw _err1; })); ee.on('error', common.mustCall(async (err) => { assert.strictEqual(err, _err1); throw _err2; })); process.removeAllListeners('unhandledRejection'); process.once('unhandledRejection', common.mustCall((err) => { // restore default process.on('unhandledRejection', (err) => { throw err; }); assert.strictEqual(err, _err2); process.nextTick(thenableThatThrows); })); ee.emit('something'); } function thenableThatThrows() { const ee = new EventEmitter({ captureRejections: true }); const _err = new Error('kaboom'); ee.on('something', common.mustCall((value) => { const obj = {}; Object.defineProperty(obj, 'then', { get: common.mustCall(() => { throw _err; }, 1), // Only 1 call for Promises/A+ compat. }); return obj; })); ee.on('error', common.mustCall((err) => { assert.strictEqual(err, _err); process.nextTick(resetCaptureOnThrowInError); })); ee.emit('something'); } function resetCaptureOnThrowInError() { const ee = new EventEmitter({ captureRejections: true }); ee.on('something', common.mustCall(async (value) => { throw new Error('kaboom'); })); ee.once('error', common.mustCall((err) => { throw err; })); process.removeAllListeners('uncaughtException'); process.once('uncaughtException', common.mustCall((err) => { process.nextTick(next); })); ee.emit('something'); function next() { process.on('uncaughtException', common.mustNotCall()); const _err = new Error('kaboom2'); ee.on('something2', common.mustCall(async (value) => { throw _err; })); ee.on('error', common.mustCall((err) => { assert.strictEqual(err, _err); process.removeAllListeners('uncaughtException'); // restore default process.on('uncaughtException', (err) => { throw err; }); process.nextTick(argValidation); })); ee.emit('something2'); } } function argValidation() { function testType(obj) { const received = obj.constructor.name !== 'Number' ? `an instance of ${obj.constructor.name}` : `type number (${obj})`; assert.throws(() => new EventEmitter({ captureRejections: obj }), { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', message: 'The "options.captureRejections" property must be of type ' + `boolean. Received ${received}`, }); assert.throws(() => EventEmitter.captureRejections = obj, { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', message: 'The "EventEmitter.captureRejections" property must be of ' + `type boolean. Received ${received}`, }); } testType([]); testType({ hello: 42 }); testType(42); } captureRejections();