1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 07:14:47 -05:00
denoland-deno/tests/node_compat/test/parallel/test-event-capture-rejections.js

328 lines
8.3 KiB
JavaScript
Raw Normal View History

// 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();