Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions test/eslint.config_partial.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ export default [
'wasm-allocation',
'wpt',
].join(',')}}/**/*.{js,mjs,cjs}`,
`test/parallel/test-{${
// 0x61 is code for 'a', this generates a string enumerating latin letters: 'a*,b*,…'
Array.from({ length: 2 }, (_, i) => String.fromCharCode(0x61 + i, 42)).join(',')
}}.{js,mjs,cjs}`,
],
rules: {
'node-core/must-call-assert': 'error',
Expand Down
6 changes: 2 additions & 4 deletions test/parallel/test-abortcontroller-internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
'use strict';
require('../common');

const {
strictEqual,
} = require('assert');
const assert = require('assert');

const {
test,
Expand All @@ -30,5 +28,5 @@ test('A weak event listener should not prevent gc', async () => {

await sleep(10);
globalThis.gc();
strictEqual(ref.deref(), undefined);
assert.strictEqual(ref.deref(), undefined);
});
99 changes: 47 additions & 52 deletions test/parallel/test-abortcontroller.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
// Flags: --expose-gc
'use strict';

require('../common');
const common = require('../common');
const { inspect } = require('util');

const {
ok,
notStrictEqual,
strictEqual,
throws,
} = require('assert');
const assert = require('assert');

const {
test,
Expand All @@ -25,34 +20,34 @@ const { setTimeout: sleep } = require('timers/promises');
test('Abort is fired with the correct event type on AbortControllers', () => {
// Tests that abort is fired with the correct event type on AbortControllers
const ac = new AbortController();
ok(ac.signal);
assert.ok(ac.signal);

const fn = mock.fn((event) => {
ok(event);
strictEqual(event.type, 'abort');
});
const fn = mock.fn(common.mustCall((event) => {
assert.ok(event);
assert.strictEqual(event.type, 'abort');
}, 2));

ac.signal.onabort = fn;
ac.signal.addEventListener('abort', fn);

ac.abort();
ac.abort();
ok(ac.signal.aborted);
assert.ok(ac.signal.aborted);

strictEqual(fn.mock.calls.length, 2);
assert.strictEqual(fn.mock.calls.length, 2);
});

test('Abort events are trusted', () => {
// Tests that abort events are trusted
const ac = new AbortController();

const fn = mock.fn((event) => {
ok(event.isTrusted);
});
const fn = mock.fn(common.mustCall((event) => {
assert.ok(event.isTrusted);
}));

ac.signal.onabort = fn;
ac.abort();
strictEqual(fn.mock.calls.length, 1);
assert.strictEqual(fn.mock.calls.length, 1);
});

test('Abort events have the same isTrusted reference', () => {
Expand All @@ -73,14 +68,14 @@ test('Abort events have the same isTrusted reference', () => {
const firstTrusted = Reflect.getOwnPropertyDescriptor(Object.getPrototypeOf(ev1), 'isTrusted').get;
const secondTrusted = Reflect.getOwnPropertyDescriptor(Object.getPrototypeOf(ev2), 'isTrusted').get;
const untrusted = Reflect.getOwnPropertyDescriptor(Object.getPrototypeOf(ev3), 'isTrusted').get;
strictEqual(firstTrusted, secondTrusted);
strictEqual(untrusted, firstTrusted);
assert.strictEqual(firstTrusted, secondTrusted);
assert.strictEqual(untrusted, firstTrusted);
});

test('AbortSignal is impossible to construct manually', () => {
// Tests that AbortSignal is impossible to construct manually
const ac = new AbortController();
throws(() => new ac.signal.constructor(), {
assert.throws(() => new ac.signal.constructor(), {
code: 'ERR_ILLEGAL_CONSTRUCTOR',
});
});
Expand All @@ -89,13 +84,13 @@ test('Symbol.toStringTag is correct', () => {
// Symbol.toStringTag
const toString = (o) => Object.prototype.toString.call(o);
const ac = new AbortController();
strictEqual(toString(ac), '[object AbortController]');
strictEqual(toString(ac.signal), '[object AbortSignal]');
assert.strictEqual(toString(ac), '[object AbortController]');
assert.strictEqual(toString(ac.signal), '[object AbortSignal]');
});

test('AbortSignal.abort() creates an already aborted signal', () => {
const signal = AbortSignal.abort();
ok(signal.aborted);
assert.ok(signal.aborted);
});

test('AbortController properties and methods valiate the receiver', () => {
Expand All @@ -106,7 +101,7 @@ test('AbortController properties and methods valiate the receiver', () => {
const acAbort = AbortController.prototype.abort;

const goodController = new AbortController();
ok(acSignalGet.call(goodController));
assert.ok(acSignalGet.call(goodController));
acAbort.call(goodController);

const badAbortControllers = [
Expand All @@ -119,11 +114,11 @@ test('AbortController properties and methods valiate the receiver', () => {
{ __proto__: AbortController.prototype },
];
for (const badController of badAbortControllers) {
throws(
assert.throws(
() => acSignalGet.call(badController),
{ name: 'TypeError' }
);
throws(
assert.throws(
() => acAbort.call(badController),
{ name: 'TypeError' }
);
Expand All @@ -137,7 +132,7 @@ test('AbortSignal properties validate the receiver', () => {
).get;

const goodSignal = new AbortController().signal;
strictEqual(signalAbortedGet.call(goodSignal), false);
assert.strictEqual(signalAbortedGet.call(goodSignal), false);

const badAbortSignals = [
null,
Expand All @@ -149,7 +144,7 @@ test('AbortSignal properties validate the receiver', () => {
{ __proto__: AbortSignal.prototype },
];
for (const badSignal of badAbortSignals) {
throws(
assert.throws(
() => signalAbortedGet.call(badSignal),
{ name: 'TypeError' }
);
Expand All @@ -158,38 +153,38 @@ test('AbortSignal properties validate the receiver', () => {

test('AbortController inspection depth 1 or null works', () => {
const ac = new AbortController();
strictEqual(inspect(ac, { depth: 1 }),
'AbortController { signal: [AbortSignal] }');
strictEqual(inspect(ac, { depth: null }),
'AbortController { signal: AbortSignal { aborted: false } }');
assert.strictEqual(inspect(ac, { depth: 1 }),
'AbortController { signal: [AbortSignal] }');
assert.strictEqual(inspect(ac, { depth: null }),
'AbortController { signal: AbortSignal { aborted: false } }');
});

test('AbortSignal reason is set correctly', () => {
// Test AbortSignal.reason
const ac = new AbortController();
ac.abort('reason');
strictEqual(ac.signal.reason, 'reason');
assert.strictEqual(ac.signal.reason, 'reason');
});

test('AbortSignal reasonable is set correctly with AbortSignal.abort()', () => {
// Test AbortSignal.reason
const signal = AbortSignal.abort('reason');
strictEqual(signal.reason, 'reason');
assert.strictEqual(signal.reason, 'reason');
});

test('AbortSignal.timeout() works as expected', async () => {
// Test AbortSignal timeout
const signal = AbortSignal.timeout(10);
ok(!signal.aborted);
assert.ok(!signal.aborted);

const { promise, resolve } = Promise.withResolvers();

const fn = mock.fn(() => {
ok(signal.aborted);
strictEqual(signal.reason.name, 'TimeoutError');
strictEqual(signal.reason.code, 23);
const fn = mock.fn(common.mustCall(() => {
assert.ok(signal.aborted);
assert.strictEqual(signal.reason.name, 'TimeoutError');
assert.strictEqual(signal.reason.code, 23);
resolve();
});
}));

setTimeout(fn, 20);
await promise;
Expand All @@ -205,7 +200,7 @@ test('AbortSignal.timeout() does not prevent the signal from being collected', a

await sleep(10);
globalThis.gc();
strictEqual(ref.deref(), undefined);
assert.strictEqual(ref.deref(), undefined);
});

test('AbortSignal with a timeout is not collected while there is an active listener', async () => {
Expand All @@ -220,14 +215,14 @@ test('AbortSignal with a timeout is not collected while there is an active liste

await sleep(10);
globalThis.gc();
notStrictEqual(ref.deref(), undefined);
ok(ref.deref() instanceof AbortSignal);
assert.notStrictEqual(ref.deref(), undefined);
assert.ok(ref.deref() instanceof AbortSignal);

ref.deref().removeEventListener('abort', handler);

await sleep(10);
globalThis.gc();
strictEqual(ref.deref(), undefined);
assert.strictEqual(ref.deref(), undefined);
});

test('Setting a long timeout should not keep the process open', () => {
Expand All @@ -237,18 +232,18 @@ test('Setting a long timeout should not keep the process open', () => {
test('AbortSignal.reason should default', () => {
// Test AbortSignal.reason default
const signal = AbortSignal.abort();
ok(signal.reason instanceof DOMException);
strictEqual(signal.reason.code, 20);
assert.ok(signal.reason instanceof DOMException);
assert.strictEqual(signal.reason.code, 20);

const ac = new AbortController();
ac.abort();
ok(ac.signal.reason instanceof DOMException);
strictEqual(ac.signal.reason.code, 20);
assert.ok(ac.signal.reason instanceof DOMException);
assert.strictEqual(ac.signal.reason.code, 20);
});

test('abortSignal.throwIfAborted() works as expected', () => {
// Test abortSignal.throwIfAborted()
throws(() => AbortSignal.abort().throwIfAborted(), {
assert.throws(() => AbortSignal.abort().throwIfAborted(), {
code: 20,
name: 'AbortError',
});
Expand All @@ -262,7 +257,7 @@ test('abortSignal.throwIfAobrted() works as expected (2)', () => {
const originalDesc = Reflect.getOwnPropertyDescriptor(AbortSignal.prototype, 'aborted');
const actualReason = new Error();
Reflect.defineProperty(AbortSignal.prototype, 'aborted', { value: false });
throws(() => AbortSignal.abort(actualReason).throwIfAborted(), actualReason);
assert.throws(() => AbortSignal.abort(actualReason).throwIfAborted(), actualReason);
Reflect.defineProperty(AbortSignal.prototype, 'aborted', originalDesc);
});

Expand All @@ -271,6 +266,6 @@ test('abortSignal.throwIfAobrted() works as expected (3)', () => {
const actualReason = new Error();
const fakeExcuse = new Error();
Reflect.defineProperty(AbortSignal.prototype, 'reason', { value: fakeExcuse });
throws(() => AbortSignal.abort(actualReason).throwIfAborted(), actualReason);
assert.throws(() => AbortSignal.abort(actualReason).throwIfAborted(), actualReason);
Reflect.defineProperty(AbortSignal.prototype, 'reason', originalDesc);
});
32 changes: 14 additions & 18 deletions test/parallel/test-aborted-util.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
// Flags: --expose-gc
'use strict';

require('../common');
const common = require('../common');
const { aborted } = require('util');
const {
match,
rejects,
strictEqual,
} = require('assert');
const assert = require('assert');
const { getEventListeners } = require('events');
const { inspect } = require('util');

Expand All @@ -20,8 +16,8 @@ test('Aborted works when provided a resource', async () => {
const promise = aborted(ac.signal, {});
ac.abort();
await promise;
strictEqual(ac.signal.aborted, true);
strictEqual(getEventListeners(ac.signal, 'abort').length, 0);
assert.strictEqual(ac.signal.aborted, true);
assert.strictEqual(getEventListeners(ac.signal, 'abort').length, 0);
});

test('Aborted with gc cleanup', async () => {
Expand All @@ -31,23 +27,23 @@ test('Aborted with gc cleanup', async () => {
const abortedPromise = aborted(ac.signal, {});
const { promise, resolve } = Promise.withResolvers();

setImmediate(() => {
setImmediate(common.mustCall(() => {
globalThis.gc();
ac.abort();
strictEqual(ac.signal.aborted, true);
strictEqual(getEventListeners(ac.signal, 'abort').length, 0);
assert.strictEqual(ac.signal.aborted, true);
assert.strictEqual(getEventListeners(ac.signal, 'abort').length, 0);
resolve();
});
}));

await promise;

// Ensure that the promise is still pending
match(inspect(abortedPromise), /<pending>/);
assert.match(inspect(abortedPromise), /<pending>/);
});

test('Fails with error if not provided AbortSignal', async () => {
await Promise.all([{}, null, undefined, Symbol(), [], 1, 0, 1n, true, false, 'a', () => {}].map((sig) =>
rejects(aborted(sig, {}), {
assert.rejects(aborted(sig, {}), {
code: 'ERR_INVALID_ARG_TYPE',
})
));
Expand All @@ -57,7 +53,7 @@ test('Fails if not provided a resource', async () => {
// Fails if not provided a resource
const ac = new AbortController();
await Promise.all([null, undefined, 0, 1, 0n, 1n, Symbol(), '', 'a'].map((resource) =>
rejects(aborted(ac.signal, resource), {
assert.rejects(aborted(ac.signal, resource), {
code: 'ERR_INVALID_ARG_TYPE',
})
));
Expand All @@ -82,10 +78,10 @@ function lazySpawn() {
test('Does not hang forever', { skip: !lazySpawn() }, async () => {
const { promise, resolve } = Promise.withResolvers();
const childProcess = spawn(process.execPath, ['--input-type=module']);
childProcess.on('exit', (code) => {
strictEqual(code, 13);
childProcess.on('exit', common.mustCall((code) => {
assert.strictEqual(code, 13);
resolve();
});
}));
childProcess.stdin.end(`
import { aborted } from 'node:util';
await aborted(new AbortController().signal, {});
Expand Down
Loading
Loading