node/test/parallel/test-eventemitter-asyncresource.js
Rich Trott d5d7a416c7
test: add trailing commas in event tests
As much as I would like to do this everywhere and then modify the lint
rule to enforce it, the churn would be too big. However if we're going
to have relatively frequent nits for this sort of thing (as we do), I'd
prefer we migrate a few files at a time to never actually getting around
to doing it.

Ref: https://github.com/nodejs/node/pull/45448#pullrequestreview-1179370442
PR-URL: https://github.com/nodejs/node/pull/45466
Reviewed-By: James M Snell <jasnell@gmail.com>
2022-11-22 23:03:33 +00:00

157 lines
3.4 KiB
JavaScript

'use strict';
const common = require('../common');
const { EventEmitterAsyncResource } = require('events');
const {
createHook,
executionAsyncId,
} = require('async_hooks');
const {
deepStrictEqual,
strictEqual,
throws,
} = require('assert');
const {
setImmediate: tick,
} = require('timers/promises');
function makeHook(trackedTypes) {
const eventMap = new Map();
function log(asyncId, name) {
const entry = eventMap.get(asyncId);
if (entry !== undefined) entry.push({ name });
}
const hook = createHook({
init(asyncId, type, triggerAsyncId, resource) {
if (trackedTypes.includes(type)) {
eventMap.set(asyncId, [
{
name: 'init',
type,
triggerAsyncId,
resource,
},
]);
}
},
before(asyncId) { log(asyncId, 'before'); },
after(asyncId) { log(asyncId, 'after'); },
destroy(asyncId) { log(asyncId, 'destroy'); },
}).enable();
return {
done() {
hook.disable();
return new Set(eventMap.values());
},
ids() {
return new Set(eventMap.keys());
},
};
}
// Tracks emit() calls correctly using async_hooks
(async () => {
const tracer = makeHook(['Foo']);
class Foo extends EventEmitterAsyncResource {}
const origExecutionAsyncId = executionAsyncId();
const foo = new Foo();
foo.on('someEvent', common.mustCall());
foo.emit('someEvent');
deepStrictEqual([foo.asyncId], [...tracer.ids()]);
strictEqual(foo.triggerAsyncId, origExecutionAsyncId);
strictEqual(foo.asyncResource.eventEmitter, foo);
foo.emitDestroy();
await tick();
deepStrictEqual(tracer.done(), new Set([
[
{
name: 'init',
type: 'Foo',
triggerAsyncId: origExecutionAsyncId,
resource: foo.asyncResource,
},
{ name: 'before' },
{ name: 'after' },
{ name: 'destroy' },
],
]));
})().then(common.mustCall());
// Can explicitly specify name as positional arg
(async () => {
const tracer = makeHook(['ResourceName']);
const origExecutionAsyncId = executionAsyncId();
class Foo extends EventEmitterAsyncResource {}
const foo = new Foo('ResourceName');
deepStrictEqual(tracer.done(), new Set([
[
{
name: 'init',
type: 'ResourceName',
triggerAsyncId: origExecutionAsyncId,
resource: foo.asyncResource,
},
],
]));
})().then(common.mustCall());
// Can explicitly specify name as option
(async () => {
const tracer = makeHook(['ResourceName']);
const origExecutionAsyncId = executionAsyncId();
class Foo extends EventEmitterAsyncResource {}
const foo = new Foo({ name: 'ResourceName' });
deepStrictEqual(tracer.done(), new Set([
[
{
name: 'init',
type: 'ResourceName',
triggerAsyncId: origExecutionAsyncId,
resource: foo.asyncResource,
},
],
]));
})().then(common.mustCall());
// Member methods ERR_INVALID_THIS
throws(
() => EventEmitterAsyncResource.prototype.emit(),
{ code: 'ERR_INVALID_THIS' }
);
throws(
() => EventEmitterAsyncResource.prototype.emitDestroy(),
{ code: 'ERR_INVALID_THIS' }
);
['asyncId', 'triggerAsyncId', 'asyncResource'].forEach((getter) => {
throws(
() => Reflect.get(EventEmitterAsyncResource.prototype, getter, {}),
{
code: 'ERR_INVALID_THIS',
name: /TypeError/,
message: 'Value of "this" must be of type EventEmitterAsyncResource',
stack: new RegExp(`at get ${getter}`),
}
);
});