Skip to content

Commit 760c982

Browse files
ErickWendeltargos
authored andcommitted
test_runner: preserve original property descriptor
PR-URL: #49433 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Raz Luvaton <[email protected]> Reviewed-By: Chemi Atlow <[email protected]> Reviewed-By: Moshe Atlow <[email protected]>
1 parent 95cc98e commit 760c982

File tree

2 files changed

+207
-35
lines changed

2 files changed

+207
-35
lines changed

lib/internal/test_runner/mock/mock_timers.js

Lines changed: 161 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ const {
1010
DateNow,
1111
FunctionPrototypeApply,
1212
FunctionPrototypeBind,
13+
ObjectDefineProperty,
14+
ObjectGetOwnPropertyDescriptor,
1315
Promise,
1416
SymbolAsyncIterator,
1517
SymbolDispose,
@@ -238,11 +240,7 @@ class MockTimers {
238240
toFake: {
239241
__proto__: null,
240242
setTimeout: () => {
241-
this.#realSetTimeout = globalThis.setTimeout;
242-
this.#realClearTimeout = globalThis.clearTimeout;
243-
this.#realTimersSetTimeout = nodeTimers.setTimeout;
244-
this.#realTimersClearTimeout = nodeTimers.clearTimeout;
245-
this.#realPromisifiedSetTimeout = nodeTimersPromises.setTimeout;
243+
this.#storeOriginalSetTimeout();
246244

247245
globalThis.setTimeout = this.#setTimeout;
248246
globalThis.clearTimeout = this.#clearTimeout;
@@ -256,11 +254,7 @@ class MockTimers {
256254
);
257255
},
258256
setInterval: () => {
259-
this.#realSetInterval = globalThis.setInterval;
260-
this.#realClearInterval = globalThis.clearInterval;
261-
this.#realTimersSetInterval = nodeTimers.setInterval;
262-
this.#realTimersClearInterval = nodeTimers.clearInterval;
263-
this.#realPromisifiedSetInterval = nodeTimersPromises.setInterval;
257+
this.#storeOriginalSetInterval();
264258

265259
globalThis.setInterval = this.#setInterval;
266260
globalThis.clearInterval = this.#clearInterval;
@@ -274,10 +268,7 @@ class MockTimers {
274268
);
275269
},
276270
setImmediate: () => {
277-
this.#realSetImmediate = globalThis.setImmediate;
278-
this.#realClearImmediate = globalThis.clearImmediate;
279-
this.#realTimersSetImmediate = nodeTimers.setImmediate;
280-
this.#realTimersClearImmediate = nodeTimers.clearImmediate;
271+
this.#storeOriginalSetImmediate();
281272

282273
globalThis.setImmediate = this.#setImmediate;
283274
globalThis.clearImmediate = this.#clearImmediate;
@@ -294,31 +285,13 @@ class MockTimers {
294285
toReal: {
295286
__proto__: null,
296287
setTimeout: () => {
297-
globalThis.setTimeout = this.#realSetTimeout;
298-
globalThis.clearTimeout = this.#realClearTimeout;
299-
300-
nodeTimers.setTimeout = this.#realTimersSetTimeout;
301-
nodeTimers.clearTimeout = this.#realTimersClearTimeout;
302-
303-
nodeTimersPromises.setTimeout = this.#realPromisifiedSetTimeout;
288+
this.#restoreOriginalSetTimeout();
304289
},
305290
setInterval: () => {
306-
globalThis.setInterval = this.#realSetInterval;
307-
globalThis.clearInterval = this.#realClearInterval;
308-
309-
nodeTimers.setInterval = this.#realTimersSetInterval;
310-
nodeTimers.clearInterval = this.#realTimersClearInterval;
311-
312-
nodeTimersPromises.setInterval = this.#realPromisifiedSetInterval;
291+
this.#restoreOriginalSetInterval();
313292
},
314293
setImmediate: () => {
315-
globalThis.setImmediate = this.#realSetImmediate;
316-
globalThis.clearImmediate = this.#realClearImmediate;
317-
318-
nodeTimers.setImmediate = this.#realTimersSetImmediate;
319-
nodeTimers.clearImmediate = this.#realTimersClearImmediate;
320-
321-
nodeTimersPromises.setImmediate = this.#realPromisifiedSetImmediate;
294+
this.#restoreSetImmediate();
322295
},
323296
},
324297
};
@@ -328,6 +301,159 @@ class MockTimers {
328301
this.#isEnabled = activate;
329302
}
330303

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

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

Lines changed: 46 additions & 0 deletions
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)