Skip to content

Commit 0142183

Browse files
Han5991juanarbol
authored andcommitted
test_runner: align mock timeout api
Expose Timeout.close() and Timeout[Symbol.dispose]() from MockTimers. This keeps fake setTimeout() handles aligned with the public Timeout API so disposal-based patterns do not throw. Add targeted coverage for Timeout.close() and Timeout[Symbol.dispose](). Signed-off-by: sangwook <rewq5991@gmail.com> PR-URL: #62820 Fixes: #62815 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Jacob Smith <jacob@frende.me>
1 parent f149860 commit 0142183

2 files changed

Lines changed: 39 additions & 0 deletions

File tree

lib/internal/test_runner/mock/mock_timers.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,15 @@ const TIMERS_DEFAULT_INTERVAL = {
7272
};
7373

7474
class Timeout {
75+
#clear;
76+
7577
constructor(opts) {
7678
this.id = opts.id;
7779
this.callback = opts.callback;
7880
this.runAt = opts.runAt;
7981
this.interval = opts.interval;
8082
this.args = opts.args;
83+
this.#clear = opts.clear;
8184
}
8285

8386
hasRef() {
@@ -95,6 +98,15 @@ class Timeout {
9598
refresh() {
9699
return this;
97100
}
101+
102+
close() {
103+
this.#clear(this);
104+
return this;
105+
}
106+
107+
[SymbolDispose]() {
108+
this.#clear(this);
109+
}
98110
}
99111

100112
class MockTimers {
@@ -317,6 +329,7 @@ class MockTimers {
317329
runAt: this.#now + delay,
318330
interval: isInterval ? delay : undefined,
319331
args,
332+
clear: this.#clearTimeout,
320333
};
321334

322335
const timer = new Timeout(opts);

test/parallel/test-runner-mock-timers.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,32 @@ describe('Mock Timers Test Suite', () => {
266266
assert.deepStrictEqual(fn.mock.calls[0].arguments, args);
267267
});
268268

269+
it('should expose Timeout.prototype[Symbol.dispose]', (t) => {
270+
t.mock.timers.enable({ apis: ['setTimeout'] });
271+
const fn = t.mock.fn();
272+
const timeout = globalThis.setTimeout(fn, 2000);
273+
274+
assert.strictEqual(typeof timeout[Symbol.dispose], 'function');
275+
276+
timeout[Symbol.dispose]();
277+
t.mock.timers.tick(2000);
278+
279+
assert.strictEqual(fn.mock.callCount(), 0);
280+
});
281+
282+
it('should expose Timeout.prototype.close()', (t) => {
283+
t.mock.timers.enable({ apis: ['setTimeout'] });
284+
const fn = t.mock.fn();
285+
const timeout = globalThis.setTimeout(fn, 2000);
286+
287+
assert.strictEqual(typeof timeout.close, 'function');
288+
assert.strictEqual(timeout.close(), timeout);
289+
290+
t.mock.timers.tick(2000);
291+
292+
assert.strictEqual(fn.mock.callCount(), 0);
293+
});
294+
269295
it('should keep setTimeout working if timers are disabled', (t, done) => {
270296
const now = Date.now();
271297
const timeout = 2;

0 commit comments

Comments
 (0)