diff options
author | Matt Mastracci <matthew@mastracci.com> | 2024-02-10 13:22:13 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-10 20:22:13 +0000 |
commit | f5e46c9bf2f50d66a953fa133161fc829cecff06 (patch) | |
tree | 8faf2f5831c1c7b11d842cd9908d141082c869a5 /tests/node_compat/test/parallel/test-events-once.js | |
parent | d2477f780630a812bfd65e3987b70c0d309385bb (diff) |
chore: move cli/tests/ -> tests/ (#22369)
This looks like a massive PR, but it's only a move from cli/tests ->
tests, and updates of relative paths for files.
This is the first step towards aggregate all of the integration test
files under tests/, which will lead to a set of integration tests that
can run without the CLI binary being built.
While we could leave these tests under `cli`, it would require us to
keep a more complex directory structure for the various test runners. In
addition, we have a lot of complexity to ignore various test files in
the `cli` project itself (cargo publish exclusion rules, autotests =
false, etc).
And finally, the `tests/` folder will eventually house the `test_ffi`,
`test_napi` and other testing code, reducing the size of the root repo
directory.
For easier review, the extremely large and noisy "move" is in the first
commit (with no changes -- just a move), while the remainder of the
changes to actual files is in the second commit.
Diffstat (limited to 'tests/node_compat/test/parallel/test-events-once.js')
-rw-r--r-- | tests/node_compat/test/parallel/test-events-once.js | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/tests/node_compat/test/parallel/test-events-once.js b/tests/node_compat/test/parallel/test-events-once.js new file mode 100644 index 000000000..7236f9830 --- /dev/null +++ b/tests/node_compat/test/parallel/test-events-once.js @@ -0,0 +1,272 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.8.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// TODO(cjihrig): kEvents is an internally used symbol in Node.js. It is not +// implemented in Deno, so parts of this test must be removed in order to pass. + +'use strict'; +// Flags: --no-warnings + +const common = require('../common'); +const { once, EventEmitter } = require('events'); +const { + strictEqual, + deepStrictEqual, + fail, + rejects, +} = require('assert'); + +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 onceAnEventWithNullOptions() { + const ee = new EventEmitter(); + + process.nextTick(() => { + ee.emit('myevent', 42); + }); + + const [value] = await once(ee, 'myevent', null); + strictEqual(value, 42); +} + + +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 catchesErrorsWithAbortSignal() { + const ee = new EventEmitter(); + const ac = new AbortController(); + const signal = ac.signal; + + const expected = new Error('boom'); + let err; + process.nextTick(() => { + ee.emit('error', expected); + }); + + try { + const promise = once(ee, 'myevent', { signal }); + strictEqual(ee.listenerCount('error'), 1); + + await promise; + } 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); + }); + + 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 promise = once(ee, 'error'); + strictEqual(ee.listenerCount('error'), 1); + const [ err ] = await promise; + strictEqual(err, expected); + strictEqual(ee.listenerCount('error'), 0); + strictEqual(ee.listenerCount('myevent'), 0); +} + +async function onceWithEventTarget() { + const et = new EventTarget(); + const event = new Event('myevent'); + process.nextTick(() => { + et.dispatchEvent(event); + }); + const [ value ] = await once(et, 'myevent'); + strictEqual(value, event); +} + +async function onceWithEventTargetError() { + const et = new EventTarget(); + const error = new Event('error'); + process.nextTick(() => { + et.dispatchEvent(error); + }); + + const [ err ] = await once(et, 'error'); + strictEqual(err, error); +} + +async function prioritizesEventEmitter() { + const ee = new EventEmitter(); + ee.addEventListener = fail; + ee.removeAllListeners = fail; + process.nextTick(() => ee.emit('foo')); + await once(ee, 'foo'); +} + +async function abortSignalBefore() { + const ee = new EventEmitter(); + ee.on('error', common.mustNotCall()); + const abortedSignal = AbortSignal.abort(); + + await Promise.all([1, {}, 'hi', null, false].map((signal) => { + return rejects(once(ee, 'foo', { signal }), { + code: 'ERR_INVALID_ARG_TYPE' + }); + })); + + return rejects(once(ee, 'foo', { signal: abortedSignal }), { + name: 'AbortError' + }); +} + +async function abortSignalAfter() { + const ee = new EventEmitter(); + const ac = new AbortController(); + ee.on('error', common.mustNotCall()); + const r = rejects(once(ee, 'foo', { signal: ac.signal }), { + name: 'AbortError' + }); + process.nextTick(() => ac.abort()); + return r; +} + +async function abortSignalAfterEvent() { + const ee = new EventEmitter(); + const ac = new AbortController(); + process.nextTick(() => { + ee.emit('foo'); + ac.abort(); + }); + const promise = once(ee, 'foo', { signal: ac.signal }); + await promise; +} + +async function abortSignalRemoveListener() { + const ee = new EventEmitter(); + const ac = new AbortController(); + + try { + process.nextTick(() => ac.abort()); + await once(ee, 'test', { signal: ac.signal }); + } catch { + strictEqual(ee.listeners('test').length, 0); + strictEqual(ee.listeners('error').length, 0); + } +} + +async function eventTargetAbortSignalBefore() { + const et = new EventTarget(); + const abortedSignal = AbortSignal.abort(); + + await Promise.all([1, {}, 'hi', null, false].map((signal) => { + return rejects(once(et, 'foo', { signal }), { + code: 'ERR_INVALID_ARG_TYPE' + }); + })); + + return rejects(once(et, 'foo', { signal: abortedSignal }), { + name: 'AbortError' + }); +} + +async function eventTargetAbortSignalAfter() { + const et = new EventTarget(); + const ac = new AbortController(); + const r = rejects(once(et, 'foo', { signal: ac.signal }), { + name: 'AbortError' + }); + process.nextTick(() => ac.abort()); + return r; +} + +async function eventTargetAbortSignalAfterEvent() { + const et = new EventTarget(); + const ac = new AbortController(); + process.nextTick(() => { + et.dispatchEvent(new Event('foo')); + ac.abort(); + }); + await once(et, 'foo', { signal: ac.signal }); +} + +Promise.all([ + onceAnEvent(), + onceAnEventWithNullOptions(), + onceAnEventWithTwoArgs(), + catchesErrors(), + catchesErrorsWithAbortSignal(), + stopListeningAfterCatchingError(), + onceError(), + onceWithEventTarget(), + onceWithEventTargetError(), + prioritizesEventEmitter(), + abortSignalBefore(), + abortSignalAfter(), + abortSignalAfterEvent(), + abortSignalRemoveListener(), + eventTargetAbortSignalBefore(), + eventTargetAbortSignalAfter(), + eventTargetAbortSignalAfterEvent(), +]).then(common.mustCall()); |