179 lines
4.1 KiB
JavaScript
179 lines
4.1 KiB
JavaScript
'use strict';
|
|
|
|
const common = require('../common');
|
|
const { once, EventEmitter } = require('events');
|
|
const { strictEqual, deepStrictEqual } = require('assert');
|
|
|
|
class EventTargetMock {
|
|
constructor() {
|
|
this.events = {};
|
|
}
|
|
|
|
addEventListener = common.mustCall(function(name, listener, options) {
|
|
if (!(name in this.events)) {
|
|
this.events[name] = { listeners: [], options };
|
|
}
|
|
this.events[name].listeners.push(listener);
|
|
});
|
|
|
|
removeEventListener = common.mustCall(function(name, callback) {
|
|
if (!(name in this.events)) {
|
|
return;
|
|
}
|
|
const event = this.events[name];
|
|
const stack = event.listeners;
|
|
|
|
for (let i = 0, l = stack.length; i < l; i++) {
|
|
if (stack[i] === callback) {
|
|
stack.splice(i, 1);
|
|
if (stack.length === 0) {
|
|
Reflect.deleteProperty(this.events, name);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
});
|
|
|
|
dispatchEvent = function(name, ...arg) {
|
|
if (!(name in this.events)) {
|
|
return true;
|
|
}
|
|
const event = this.events[name];
|
|
const stack = event.listeners.slice();
|
|
|
|
for (let i = 0, l = stack.length; i < l; i++) {
|
|
stack[i].apply(this, arg);
|
|
if (event.options.once) {
|
|
this.removeEventListener(name, stack[i]);
|
|
}
|
|
}
|
|
return !name.defaultPrevented;
|
|
};
|
|
}
|
|
|
|
async function onceAnEvent() {
|
|
const ee = new EventEmitter();
|
|
|
|
process.nextTick(() => {
|
|
ee.emit('myevent', 42);
|
|
});
|
|
|
|
const [value] = await once(ee, 'myevent');
|
|
strictEqual(value, 42);
|
|
strictEqual(ee.listenerCount('error'), 0);
|
|
strictEqual(ee.listenerCount('myevent'), 0);
|
|
}
|
|
|
|
async function onceAnEventWithTwoArgs() {
|
|
const ee = new EventEmitter();
|
|
|
|
process.nextTick(() => {
|
|
ee.emit('myevent', 42, 24);
|
|
});
|
|
|
|
const value = await once(ee, 'myevent');
|
|
deepStrictEqual(value, [42, 24]);
|
|
}
|
|
|
|
async function catchesErrors() {
|
|
const ee = new EventEmitter();
|
|
|
|
const expected = new Error('kaboom');
|
|
let err;
|
|
process.nextTick(() => {
|
|
ee.emit('error', expected);
|
|
});
|
|
|
|
try {
|
|
await once(ee, 'myevent');
|
|
} catch (_e) {
|
|
err = _e;
|
|
}
|
|
strictEqual(err, expected);
|
|
strictEqual(ee.listenerCount('error'), 0);
|
|
strictEqual(ee.listenerCount('myevent'), 0);
|
|
}
|
|
|
|
async function stopListeningAfterCatchingError() {
|
|
const ee = new EventEmitter();
|
|
|
|
const expected = new Error('kaboom');
|
|
let err;
|
|
process.nextTick(() => {
|
|
ee.emit('error', expected);
|
|
ee.emit('myevent', 42, 24);
|
|
});
|
|
|
|
process.on('multipleResolves', common.mustNotCall());
|
|
|
|
try {
|
|
await once(ee, 'myevent');
|
|
} catch (_e) {
|
|
err = _e;
|
|
}
|
|
process.removeAllListeners('multipleResolves');
|
|
strictEqual(err, expected);
|
|
strictEqual(ee.listenerCount('error'), 0);
|
|
strictEqual(ee.listenerCount('myevent'), 0);
|
|
}
|
|
|
|
async function onceError() {
|
|
const ee = new EventEmitter();
|
|
|
|
const expected = new Error('kaboom');
|
|
process.nextTick(() => {
|
|
ee.emit('error', expected);
|
|
});
|
|
|
|
const [err] = await once(ee, 'error');
|
|
strictEqual(err, expected);
|
|
strictEqual(ee.listenerCount('error'), 0);
|
|
strictEqual(ee.listenerCount('myevent'), 0);
|
|
}
|
|
|
|
async function onceWithEventTarget() {
|
|
const et = new EventTargetMock();
|
|
|
|
process.nextTick(() => {
|
|
et.dispatchEvent('myevent', 42);
|
|
});
|
|
const [ value ] = await once(et, 'myevent');
|
|
strictEqual(value, 42);
|
|
strictEqual(Reflect.has(et.events, 'myevent'), false);
|
|
}
|
|
|
|
async function onceWithEventTargetTwoArgs() {
|
|
const et = new EventTargetMock();
|
|
|
|
process.nextTick(() => {
|
|
et.dispatchEvent('myevent', 42, 24);
|
|
});
|
|
|
|
const value = await once(et, 'myevent');
|
|
deepStrictEqual(value, [42, 24]);
|
|
}
|
|
|
|
async function onceWithEventTargetError() {
|
|
const et = new EventTargetMock();
|
|
|
|
const expected = new Error('kaboom');
|
|
process.nextTick(() => {
|
|
et.dispatchEvent('error', expected);
|
|
});
|
|
|
|
const [err] = await once(et, 'error');
|
|
strictEqual(err, expected);
|
|
strictEqual(Reflect.has(et.events, 'error'), false);
|
|
}
|
|
|
|
Promise.all([
|
|
onceAnEvent(),
|
|
onceAnEventWithTwoArgs(),
|
|
catchesErrors(),
|
|
stopListeningAfterCatchingError(),
|
|
onceError(),
|
|
onceWithEventTarget(),
|
|
onceWithEventTargetTwoArgs(),
|
|
onceWithEventTargetError(),
|
|
]).then(common.mustCall());
|