deno.land / std@0.166.0 / node / _tools / test / parallel / test-events-on-async-iterator.js
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400// 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
// Flags: --expose-internals --no-warnings'use strict';
const common = require('../common');const assert = require('assert');const { on, EventEmitter } = require('events');const { NodeEventTarget} = require('internal/event_target');
async function basic() { const ee = new EventEmitter(); process.nextTick(() => { ee.emit('foo', 'bar'); // 'bar' is a spurious event, we are testing // that it does not show up in the iterable ee.emit('bar', 24); ee.emit('foo', 42); });
const iterable = on(ee, 'foo');
const expected = [['bar'], [42]];
for await (const event of iterable) { const current = expected.shift();
assert.deepStrictEqual(current, event);
if (expected.length === 0) { break; } } assert.strictEqual(ee.listenerCount('foo'), 0); assert.strictEqual(ee.listenerCount('error'), 0);}
async function invalidArgType() { assert.throws(() => on({}, 'foo'), common.expectsError({ code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', }));}
async function error() { const ee = new EventEmitter(); const _err = new Error('kaboom'); process.nextTick(() => { ee.emit('error', _err); });
const iterable = on(ee, 'foo'); let looped = false; let thrown = false;
try { // eslint-disable-next-line no-unused-vars for await (const event of iterable) { looped = true; } } catch (err) { thrown = true; assert.strictEqual(err, _err); } assert.strictEqual(thrown, true); assert.strictEqual(looped, false);}
async function errorDelayed() { const ee = new EventEmitter(); const _err = new Error('kaboom'); process.nextTick(() => { ee.emit('foo', 42); ee.emit('error', _err); });
const iterable = on(ee, 'foo'); const expected = [[42]]; let thrown = false;
try { for await (const event of iterable) { const current = expected.shift(); assert.deepStrictEqual(current, event); } } catch (err) { thrown = true; assert.strictEqual(err, _err); } assert.strictEqual(thrown, true); assert.strictEqual(ee.listenerCount('foo'), 0); assert.strictEqual(ee.listenerCount('error'), 0);}
async function throwInLoop() { const ee = new EventEmitter(); const _err = new Error('kaboom');
process.nextTick(() => { ee.emit('foo', 42); });
try { for await (const event of on(ee, 'foo')) { assert.deepStrictEqual(event, [42]); throw _err; } } catch (err) { assert.strictEqual(err, _err); }
assert.strictEqual(ee.listenerCount('foo'), 0); assert.strictEqual(ee.listenerCount('error'), 0);}
async function next() { const ee = new EventEmitter(); const iterable = on(ee, 'foo');
process.nextTick(function() { ee.emit('foo', 'bar'); ee.emit('foo', 42); iterable.return(); });
const results = await Promise.all([ iterable.next(), iterable.next(), iterable.next(), ]);
assert.deepStrictEqual(results, [{ value: ['bar'], done: false }, { value: [42], done: false }, { value: undefined, done: true }]);
assert.deepStrictEqual(await iterable.next(), { value: undefined, done: true });}
async function nextError() { const ee = new EventEmitter(); const iterable = on(ee, 'foo'); const _err = new Error('kaboom'); process.nextTick(function() { ee.emit('error', _err); }); const results = await Promise.allSettled([ iterable.next(), iterable.next(), iterable.next(), ]); assert.deepStrictEqual(results, [{ status: 'rejected', reason: _err }, { status: 'fulfilled', value: { value: undefined, done: true } }, { status: 'fulfilled', value: { value: undefined, done: true } }]); assert.strictEqual(ee.listeners('error').length, 0);}
async function iterableThrow() { const ee = new EventEmitter(); const iterable = on(ee, 'foo');
process.nextTick(() => { ee.emit('foo', 'bar'); ee.emit('foo', 42); // lost in the queue iterable.throw(_err); });
const _err = new Error('kaboom'); let thrown = false;
assert.throws(() => { // No argument iterable.throw(); }, { message: 'The "EventEmitter.AsyncIterator" property must be' + ' an instance of Error. Received undefined', name: 'TypeError' });
const expected = [['bar'], [42]];
try { for await (const event of iterable) { assert.deepStrictEqual(event, expected.shift()); } } catch (err) { thrown = true; assert.strictEqual(err, _err); } assert.strictEqual(thrown, true); assert.strictEqual(expected.length, 0); assert.strictEqual(ee.listenerCount('foo'), 0); assert.strictEqual(ee.listenerCount('error'), 0);}
async function eventTarget() { const et = new EventTarget(); const tick = () => et.dispatchEvent(new Event('tick')); const interval = setInterval(tick, 0); let count = 0; for await (const [ event ] of on(et, 'tick')) { count++; assert.strictEqual(event.type, 'tick'); if (count >= 5) { break; } } assert.strictEqual(count, 5); clearInterval(interval);}
async function errorListenerCount() { const et = new EventEmitter(); on(et, 'foo'); assert.strictEqual(et.listenerCount('error'), 1);}
async function nodeEventTarget() { const et = new NodeEventTarget(); const tick = () => et.dispatchEvent(new Event('tick')); const interval = setInterval(tick, 0); let count = 0; for await (const [ event] of on(et, 'tick')) { count++; assert.strictEqual(event.type, 'tick'); if (count >= 5) { break; } } assert.strictEqual(count, 5); clearInterval(interval);}
async function abortableOnBefore() { const ee = new EventEmitter(); const abortedSignal = AbortSignal.abort(); [1, {}, null, false, 'hi'].forEach((signal) => { assert.throws(() => on(ee, 'foo', { signal }), { code: 'ERR_INVALID_ARG_TYPE' }); }); assert.throws(() => on(ee, 'foo', { signal: abortedSignal }), { name: 'AbortError' });}
async function eventTargetAbortableOnBefore() { const et = new EventTarget(); const abortedSignal = AbortSignal.abort(); [1, {}, null, false, 'hi'].forEach((signal) => { assert.throws(() => on(et, 'foo', { signal }), { code: 'ERR_INVALID_ARG_TYPE' }); }); assert.throws(() => on(et, 'foo', { signal: abortedSignal }), { name: 'AbortError' });}
async function abortableOnAfter() { const ee = new EventEmitter(); const ac = new AbortController();
const i = setInterval(() => ee.emit('foo', 'foo'), 10);
async function foo() { for await (const f of on(ee, 'foo', { signal: ac.signal })) { assert.strictEqual(f, 'foo'); } }
foo().catch(common.mustCall((error) => { assert.strictEqual(error.name, 'AbortError'); })).finally(() => { clearInterval(i); });
process.nextTick(() => ac.abort());}
async function eventTargetAbortableOnAfter() { const et = new EventTarget(); const ac = new AbortController();
const i = setInterval(() => et.dispatchEvent(new Event('foo')), 10);
async function foo() { for await (const f of on(et, 'foo', { signal: ac.signal })) { assert(f); } }
foo().catch(common.mustCall((error) => { assert.strictEqual(error.name, 'AbortError'); })).finally(() => { clearInterval(i); });
process.nextTick(() => ac.abort());}
async function eventTargetAbortableOnAfter2() { const et = new EventTarget(); const ac = new AbortController();
const i = setInterval(() => et.dispatchEvent(new Event('foo')), 10);
async function foo() { for await (const f of on(et, 'foo', { signal: ac.signal })) { assert(f); // Cancel after a single event has been triggered. ac.abort(); } }
foo().catch(common.mustCall((error) => { assert.strictEqual(error.name, 'AbortError'); })).finally(() => { clearInterval(i); });}
async function abortableOnAfterDone() { const ee = new EventEmitter(); const ac = new AbortController();
const i = setInterval(() => ee.emit('foo', 'foo'), 1); let count = 0;
async function foo() { for await (const f of on(ee, 'foo', { signal: ac.signal })) { assert.strictEqual(f[0], 'foo'); if (++count === 5) break; } ac.abort(); // No error will occur }
foo().finally(() => { clearInterval(i); });}
async function run() { const funcs = [ basic, invalidArgType, error, errorDelayed, throwInLoop, next, nextError, iterableThrow, eventTarget, errorListenerCount, nodeEventTarget, abortableOnBefore, abortableOnAfter, eventTargetAbortableOnBefore, eventTargetAbortableOnAfter, eventTargetAbortableOnAfter2, abortableOnAfterDone, ];
for (const fn of funcs) { await fn(); }}
run().then(common.mustCall());
Version Info