Skip to content

Commit 36763fa

Browse files
ErickWendelUlisesGascon
authored andcommitted
test_runner: preserve original property descriptor
PR-URL: #49433 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Raz Luvaton <rluvaton@gmail.com> Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
1 parent 83fc4dc commit 36763fa

File tree

2 files changed

+207
-35
lines changed

2 files changed

+207
-35
lines changed

lib/internal/test_runner/mock/mock_timers.js

+161-35
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ const {
1111
DateNow,
1212
FunctionPrototypeApply,
1313
FunctionPrototypeBind,
14+
ObjectDefineProperty,
15+
ObjectGetOwnPropertyDescriptor,
1416
Promise,
1517
SymbolAsyncIterator,
1618
SymbolDispose,
@@ -239,11 +241,7 @@ class MockTimers {
239241
toFake: {
240242
__proto__: null,
241243
setTimeout: () => {
242-
this.#realSetTimeout = globalThis.setTimeout;
243-
this.#realClearTimeout = globalThis.clearTimeout;
244-
this.#realTimersSetTimeout = nodeTimers.setTimeout;
245-
this.#realTimersClearTimeout = nodeTimers.clearTimeout;
246-
this.#realPromisifiedSetTimeout = nodeTimersPromises.setTimeout;
244+
this.#storeOriginalSetTimeout();
247245

248246
globalThis.setTimeout = this.#setTimeout;
249247
globalThis.clearTimeout = this.#clearTimeout;
@@ -257,11 +255,7 @@ class MockTimers {
257255
);
258256
},
259257
setInterval: () => {
260-
this.#realSetInterval = globalThis.setInterval;
261-
this.#realClearInterval = globalThis.clearInterval;
262-
this.#realTimersSetInterval = nodeTimers.setInterval;
263-
this.#realTimersClearInterval = nodeTimers.clearInterval;
264-
this.#realPromisifiedSetInterval = nodeTimersPromises.setInterval;
258+
this.#storeOriginalSetInterval();
265259

266260
globalThis.setInterval = this.#setInterval;
267261
globalThis.clearInterval = this.#clearInterval;
@@ -275,10 +269,7 @@ class MockTimers {
275269
);
276270
},
277271
setImmediate: () => {
278-
this.#realSetImmediate = globalThis.setImmediate;
279-
this.#realClearImmediate = globalThis.clearImmediate;
280-
this.#realTimersSetImmediate = nodeTimers.setImmediate;
281-
this.#realTimersClearImmediate = nodeTimers.clearImmediate;
272+
this.#storeOriginalSetImmediate();
282273

283274
globalThis.setImmediate = this.#setImmediate;
284275
globalThis.clearImmediate = this.#clearImmediate;
@@ -295,31 +286,13 @@ class MockTimers {
295286
toReal: {
296287
__proto__: null,
297288
setTimeout: () => {
298-
globalThis.setTimeout = this.#realSetTimeout;
299-
globalThis.clearTimeout = this.#realClearTimeout;
300-
301-
nodeTimers.setTimeout = this.#realTimersSetTimeout;
302-
nodeTimers.clearTimeout = this.#realTimersClearTimeout;
303-
304-
nodeTimersPromises.setTimeout = this.#realPromisifiedSetTimeout;
289+
this.#restoreOriginalSetTimeout();
305290
},
306291
setInterval: () => {
307-
globalThis.setInterval = this.#realSetInterval;
308-
globalThis.clearInterval = this.#realClearInterval;
309-
310-
nodeTimers.setInterval = this.#realTimersSetInterval;
311-
nodeTimers.clearInterval = this.#realTimersClearInterval;
312-
313-
nodeTimersPromises.setInterval = this.#realPromisifiedSetInterval;
292+
this.#restoreOriginalSetInterval();
314293
},
315294
setImmediate: () => {
316-
globalThis.setImmediate = this.#realSetImmediate;
317-
globalThis.clearImmediate = this.#realClearImmediate;
318-
319-
nodeTimers.setImmediate = this.#realTimersSetImmediate;
320-
nodeTimers.clearImmediate = this.#realTimersClearImmediate;
321-
322-
nodeTimersPromises.setImmediate = this.#realPromisifiedSetImmediate;
295+
this.#restoreSetImmediate();
323296
},
324297
},
325298
};
@@ -329,6 +302,159 @@ class MockTimers {
329302
this.#isEnabled = activate;
330303
}
331304

305+
#restoreSetImmediate() {
306+
ObjectDefineProperty(
307+
globalThis,
308+
'setImmediate',
309+
this.#realSetImmediate,
310+
);
311+
ObjectDefineProperty(
312+
globalThis,
313+
'clearImmediate',
314+
this.#realClearImmediate,
315+
);
316+
ObjectDefineProperty(
317+
nodeTimers,
318+
'setImmediate',
319+
this.#realTimersSetImmediate,
320+
);
321+
ObjectDefineProperty(
322+
nodeTimers,
323+
'clearImmediate',
324+
this.#realTimersClearImmediate,
325+
);
326+
ObjectDefineProperty(
327+
nodeTimersPromises,
328+
'setImmediate',
329+
this.#realPromisifiedSetImmediate,
330+
);
331+
}
332+
333+
#restoreOriginalSetInterval() {
334+
ObjectDefineProperty(
335+
globalThis,
336+
'setInterval',
337+
this.#realSetInterval,
338+
);
339+
ObjectDefineProperty(
340+
globalThis,
341+
'clearInterval',
342+
this.#realClearInterval,
343+
);
344+
ObjectDefineProperty(
345+
nodeTimers,
346+
'setInterval',
347+
this.#realTimersSetInterval,
348+
);
349+
ObjectDefineProperty(
350+
nodeTimers,
351+
'clearInterval',
352+
this.#realTimersClearInterval,
353+
);
354+
ObjectDefineProperty(
355+
nodeTimersPromises,
356+
'setInterval',
357+
this.#realPromisifiedSetInterval,
358+
);
359+
}
360+
361+
#restoreOriginalSetTimeout() {
362+
ObjectDefineProperty(
363+
globalThis,
364+
'setTimeout',
365+
this.#realSetTimeout,
366+
);
367+
ObjectDefineProperty(
368+
globalThis,
369+
'clearTimeout',
370+
this.#realClearTimeout,
371+
);
372+
ObjectDefineProperty(
373+
nodeTimers,
374+
'setTimeout',
375+
this.#realSetTimeout,
376+
);
377+
ObjectDefineProperty(
378+
nodeTimers,
379+
'clearTimeout',
380+
this.#realTimersClearTimeout,
381+
);
382+
ObjectDefineProperty(
383+
nodeTimersPromises,
384+
'setTimeout',
385+
this.#realPromisifiedSetTimeout,
386+
);
387+
}
388+
389+
#storeOriginalSetImmediate() {
390+
this.#realSetImmediate = ObjectGetOwnPropertyDescriptor(
391+
globalThis,
392+
'setImmediate',
393+
);
394+
this.#realClearImmediate = ObjectGetOwnPropertyDescriptor(
395+
globalThis,
396+
'clearImmediate',
397+
);
398+
this.#realTimersSetImmediate = ObjectGetOwnPropertyDescriptor(
399+
nodeTimers,
400+
'setImmediate',
401+
);
402+
this.#realTimersClearImmediate = ObjectGetOwnPropertyDescriptor(
403+
nodeTimers,
404+
'clearImmediate',
405+
);
406+
this.#realPromisifiedSetImmediate = ObjectGetOwnPropertyDescriptor(
407+
nodeTimersPromises,
408+
'setImmediate',
409+
);
410+
}
411+
412+
#storeOriginalSetInterval() {
413+
this.#realSetInterval = ObjectGetOwnPropertyDescriptor(
414+
globalThis,
415+
'setInterval',
416+
);
417+
this.#realClearInterval = ObjectGetOwnPropertyDescriptor(
418+
globalThis,
419+
'clearInterval',
420+
);
421+
this.#realTimersSetInterval = ObjectGetOwnPropertyDescriptor(
422+
nodeTimers,
423+
'setInterval',
424+
);
425+
this.#realTimersClearInterval = ObjectGetOwnPropertyDescriptor(
426+
nodeTimers,
427+
'clearInterval',
428+
);
429+
this.#realPromisifiedSetInterval = ObjectGetOwnPropertyDescriptor(
430+
nodeTimersPromises,
431+
'setInterval',
432+
);
433+
}
434+
435+
#storeOriginalSetTimeout() {
436+
this.#realSetTimeout = ObjectGetOwnPropertyDescriptor(
437+
globalThis,
438+
'setTimeout',
439+
);
440+
this.#realClearTimeout = ObjectGetOwnPropertyDescriptor(
441+
globalThis,
442+
'clearTimeout',
443+
);
444+
this.#realTimersSetTimeout = ObjectGetOwnPropertyDescriptor(
445+
nodeTimers,
446+
'setTimeout',
447+
);
448+
this.#realTimersClearTimeout = ObjectGetOwnPropertyDescriptor(
449+
nodeTimers,
450+
'clearTimeout',
451+
);
452+
this.#realPromisifiedSetTimeout = ObjectGetOwnPropertyDescriptor(
453+
nodeTimersPromises,
454+
'setTimeout',
455+
);
456+
}
457+
332458
tick(time = 1) {
333459
if (!this.#isEnabled) {
334460
throw new ERR_INVALID_STATE(

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

+46
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,52 @@ describe('Mock Timers Test Suite', () => {
4747
});
4848
});
4949

50+
it('should check that propertyDescriptor gets back after reseting timers', (t) => {
51+
const getDescriptor = (ctx, fn) => Object.getOwnPropertyDescriptor(ctx, fn);
52+
const getCurrentTimersDescriptors = () => {
53+
const timers = [
54+
'setTimeout',
55+
'clearTimeout',
56+
'setInterval',
57+
'clearInterval',
58+
'setImmediate',
59+
'clearImmediate',
60+
];
61+
62+
const globalTimersDescriptors = timers.map((fn) => getDescriptor(global, fn));
63+
const nodeTimersDescriptors = timers.map((fn) => getDescriptor(nodeTimers, fn));
64+
const nodeTimersPromisesDescriptors = timers
65+
.filter((fn) => !fn.includes('clear'))
66+
.map((fn) => getDescriptor(nodeTimersPromises, fn));
67+
68+
return {
69+
global: globalTimersDescriptors,
70+
nodeTimers: nodeTimersDescriptors,
71+
nodeTimersPromises: nodeTimersPromisesDescriptors,
72+
};
73+
};
74+
const before = getCurrentTimersDescriptors();
75+
t.mock.timers.enable();
76+
const during = getCurrentTimersDescriptors();
77+
t.mock.timers.reset();
78+
const after = getCurrentTimersDescriptors();
79+
80+
assert.deepStrictEqual(
81+
before,
82+
after,
83+
);
84+
85+
assert.notDeepStrictEqual(
86+
before,
87+
during,
88+
);
89+
90+
assert.notDeepStrictEqual(
91+
during,
92+
after,
93+
);
94+
});
95+
5096
it('should reset all timers when calling .reset function', (t) => {
5197
t.mock.timers.enable();
5298
const fn = t.mock.fn();

0 commit comments

Comments
 (0)