Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
test_runner: cancel abort listener when promisified timer settles
  • Loading branch information
Renegade334 committed Jun 24, 2025
commit d28af81bd82db043bab171ae257d3f96d3d31c3c
56 changes: 24 additions & 32 deletions lib/internal/test_runner/mock/mock_timers.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const {
ObjectDefineProperty,
ObjectGetOwnPropertyDescriptor,
ObjectGetOwnPropertyDescriptors,
Promise,
PromiseWithResolvers,
Symbol,
SymbolDispose,
globalThis,
Expand Down Expand Up @@ -42,7 +42,6 @@ const nodeTimers = require('timers');
const nodeTimersPromises = require('timers/promises');
const EventEmitter = require('events');

let kResistStopPropagation;
// Internal reference to the MockTimers class inside MockDate
let kMock;
// Initial epoch to which #now should be set to
Expand Down Expand Up @@ -464,38 +463,31 @@ class MockTimers {
);
}

#promisifyTimer({ timerFn, clearFn, ms, result, options }) {
return new Promise((resolve, reject) => {
if (options?.signal) {
try {
validateAbortSignal(options.signal, 'options.signal');
} catch (err) {
return reject(err);
}

if (options.signal.aborted) {
return reject(abortIt(options.signal));
}
}
async #promisifyTimer({ timerFn, clearFn, ms, result, options }) {
const { promise, resolve, reject } = PromiseWithResolvers();

let abortListener;
if (options?.signal) {
validateAbortSignal(options.signal, 'options.signal');

const onabort = () => {
clearFn(timer);
return reject(abortIt(options.signal));
};

const timer = timerFn(() => {
return resolve(result);
}, ms);

if (options?.signal) {
kResistStopPropagation ??= require('internal/event_target').kResistStopPropagation;
options.signal.addEventListener('abort', onabort, {
__proto__: null,
once: true,
[kResistStopPropagation]: true,
});
if (options.signal.aborted) {
throw abortIt(options.signal);
}
});

abortListener = addAbortListener(options.signal, () => {
reject(abortIt(options.signal));
});
}

const timer = timerFn(resolve, ms);

try {
await promise;
return result;
} finally {
abortListener?.[SymbolDispose]();
clearFn(timer);
}
}

#setImmediatePromisified(result, options) {
Expand Down
16 changes: 16 additions & 0 deletions test/parallel/test-runner-mock-timers.js
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,22 @@ describe('Mock Timers Test Suite', () => {
});
});

it('should clear the abort listener when the timer resolves', async (t) => {
t.mock.timers.enable({ apis: ['setTimeout'] });
const expectedResult = 'result';
const controller = new AbortController();
const p = nodeTimersPromises.setTimeout(500, expectedResult, {
ref: true,
signal: controller.signal,
});

assert(hasAbortListener(controller.signal));

t.mock.timers.tick(500);
await p;
assert(!hasAbortListener(controller.signal));
});

it('should reject given an an invalid signal instance', async (t) => {
t.mock.timers.enable({ apis: ['setTimeout'] });
const expectedResult = 'result';
Expand Down
Loading