From 3fda352efd6d9a4cea99d514cbcff925c30b7600 Mon Sep 17 00:00:00 2001 From: Erick Wendel Date: Fri, 1 Sep 2023 14:07:12 -0300 Subject: [PATCH 1/3] test_runner: preserve original property descriptor --- lib/internal/test_runner/mock/mock_timers.js | 172 +++++++++++++++---- 1 file changed, 137 insertions(+), 35 deletions(-) diff --git a/lib/internal/test_runner/mock/mock_timers.js b/lib/internal/test_runner/mock/mock_timers.js index a718bf34d5ba50..873f03066fd02e 100644 --- a/lib/internal/test_runner/mock/mock_timers.js +++ b/lib/internal/test_runner/mock/mock_timers.js @@ -11,6 +11,8 @@ const { DateNow, FunctionPrototypeApply, FunctionPrototypeBind, + ObjectDefineProperty, + ObjectGetOwnPropertyDescriptor, Promise, SymbolAsyncIterator, SymbolDispose, @@ -239,11 +241,26 @@ class MockTimers { toFake: { __proto__: null, setTimeout: () => { - this.#realSetTimeout = globalThis.setTimeout; - this.#realClearTimeout = globalThis.clearTimeout; - this.#realTimersSetTimeout = nodeTimers.setTimeout; - this.#realTimersClearTimeout = nodeTimers.clearTimeout; - this.#realPromisifiedSetTimeout = nodeTimersPromises.setTimeout; + this.#realSetTimeout = ObjectGetOwnPropertyDescriptor( + globalThis, + 'setTimeout', + ); + this.#realClearTimeout = ObjectGetOwnPropertyDescriptor( + globalThis, + 'clearTimeout', + ); + this.#realTimersSetTimeout = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'setTimeout', + ); + this.#realTimersClearTimeout = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'clearTimeout', + ); + this.#realPromisifiedSetTimeout = ObjectGetOwnPropertyDescriptor( + nodeTimersPromises, + 'setTimeout', + ); globalThis.setTimeout = this.#setTimeout; globalThis.clearTimeout = this.#clearTimeout; @@ -257,11 +274,26 @@ class MockTimers { ); }, setInterval: () => { - this.#realSetInterval = globalThis.setInterval; - this.#realClearInterval = globalThis.clearInterval; - this.#realTimersSetInterval = nodeTimers.setInterval; - this.#realTimersClearInterval = nodeTimers.clearInterval; - this.#realPromisifiedSetInterval = nodeTimersPromises.setInterval; + this.#realSetInterval = ObjectGetOwnPropertyDescriptor( + globalThis, + 'setInterval', + ); + this.#realClearInterval = ObjectGetOwnPropertyDescriptor( + globalThis, + 'clearInterval', + ); + this.#realTimersSetInterval = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'setInterval', + ); + this.#realTimersClearInterval = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'clearInterval', + ); + this.#realPromisifiedSetInterval = ObjectGetOwnPropertyDescriptor( + nodeTimersPromises, + 'setInterval', + ); globalThis.setInterval = this.#setInterval; globalThis.clearInterval = this.#clearInterval; @@ -275,10 +307,26 @@ class MockTimers { ); }, setImmediate: () => { - this.#realSetImmediate = globalThis.setImmediate; - this.#realClearImmediate = globalThis.clearImmediate; - this.#realTimersSetImmediate = nodeTimers.setImmediate; - this.#realTimersClearImmediate = nodeTimers.clearImmediate; + this.#realSetImmediate = ObjectGetOwnPropertyDescriptor( + globalThis, + 'setImmediate', + ); + this.#realClearImmediate = ObjectGetOwnPropertyDescriptor( + globalThis, + 'clearImmediate', + ); + this.#realTimersSetImmediate = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'setImmediate', + ); + this.#realTimersClearImmediate = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'clearImmediate', + ); + this.#realPromisifiedSetImmediate = ObjectGetOwnPropertyDescriptor( + nodeTimersPromises, + 'setImmediate', + ); globalThis.setImmediate = this.#setImmediate; globalThis.clearImmediate = this.#clearImmediate; @@ -295,31 +343,85 @@ class MockTimers { toReal: { __proto__: null, setTimeout: () => { - globalThis.setTimeout = this.#realSetTimeout; - globalThis.clearTimeout = this.#realClearTimeout; - - nodeTimers.setTimeout = this.#realTimersSetTimeout; - nodeTimers.clearTimeout = this.#realTimersClearTimeout; - - nodeTimersPromises.setTimeout = this.#realPromisifiedSetTimeout; + ObjectDefineProperty( + globalThis, + 'setTimeout', + this.#realSetTimeout, + ); + ObjectDefineProperty( + globalThis, + 'clearTimeout', + this.#realClearTimeout, + ); + ObjectDefineProperty( + nodeTimers, + 'setTimeout', + this.#realSetTimeout, + ); + ObjectDefineProperty( + nodeTimers, + 'clearTimeout', + this.#realTimersClearTimeout, + ); + ObjectDefineProperty( + nodeTimersPromises, + 'setTimeout', + this.#realPromisifiedSetTimeout, + ); }, setInterval: () => { - globalThis.setInterval = this.#realSetInterval; - globalThis.clearInterval = this.#realClearInterval; - - nodeTimers.setInterval = this.#realTimersSetInterval; - nodeTimers.clearInterval = this.#realTimersClearInterval; - - nodeTimersPromises.setInterval = this.#realPromisifiedSetInterval; + ObjectDefineProperty( + globalThis, + 'setInterval', + this.#realSetInterval, + ); + ObjectDefineProperty( + globalThis, + 'clearInterval', + this.#realClearInterval, + ); + ObjectDefineProperty( + nodeTimers, + 'setInterval', + this.#realTimersSetInterval, + ); + ObjectDefineProperty( + nodeTimers, + 'clearInterval', + this.#realTimersClearInterval, + ); + ObjectDefineProperty( + nodeTimersPromises, + 'setInterval', + this.#realPromisifiedSetInterval, + ); }, setImmediate: () => { - globalThis.setImmediate = this.#realSetImmediate; - globalThis.clearImmediate = this.#realClearImmediate; - - nodeTimers.setImmediate = this.#realTimersSetImmediate; - nodeTimers.clearImmediate = this.#realTimersClearImmediate; - - nodeTimersPromises.setImmediate = this.#realPromisifiedSetImmediate; + ObjectDefineProperty( + globalThis, + 'setImmediate', + this.#realSetImmediate, + ); + ObjectDefineProperty( + globalThis, + 'clearImmediate', + this.#realClearImmediate, + ); + ObjectDefineProperty( + nodeTimers, + 'setImmediate', + this.#realTimersSetImmediate, + ); + ObjectDefineProperty( + nodeTimers, + 'clearImmediate', + this.#realTimersClearImmediate, + ); + ObjectDefineProperty( + nodeTimersPromises, + 'setImmediate', + this.#realPromisifiedSetImmediate, + ); }, }, }; From 77caf13f18cdd75aeee73a8580169122bd2e9b46 Mon Sep 17 00:00:00 2001 From: Erick Wendel Date: Fri, 1 Sep 2023 15:55:26 -0300 Subject: [PATCH 2/3] test_runner: add test for checking the property descriptor state Signed-off-by: Erick Wendel --- test/parallel/test-runner-mock-timers.js | 49 ++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/test/parallel/test-runner-mock-timers.js b/test/parallel/test-runner-mock-timers.js index 7b37c6ae4b8d74..0fc24471fee995 100644 --- a/test/parallel/test-runner-mock-timers.js +++ b/test/parallel/test-runner-mock-timers.js @@ -47,6 +47,55 @@ describe('Mock Timers Test Suite', () => { }); }); + it('should check that propertyDescriptor gets back after reseting timers', (t) => { + const getDescriptor = (ctx, fn) => Object.getOwnPropertyDescriptor(ctx, fn); + const getCurrentTimersDescriptors = () => { + const timers = [ + 'setTimeout', + 'clearTimeout', + 'setInterval', + 'clearInterval', + 'setImmediate', + 'clearImmediate', + ] + + const globalTimersDescriptors = timers.map((fn) => getDescriptor(global, fn)); + const nodeTimersDescriptors = timers.map((fn) => getDescriptor(nodeTimers, fn)); + const nodeTimersPromisesDescriptors = timers + .filter((fn) => !fn.includes('clear')) + .map((fn) => getDescriptor(nodeTimersPromises, fn)); + + return { + global: globalTimersDescriptors, + nodeTimers: nodeTimersDescriptors, + nodeTimersPromises: nodeTimersPromisesDescriptors, + } + } + const before = getCurrentTimersDescriptors(); + t.mock.timers.enable(); + const during = getCurrentTimersDescriptors(); + t.mock.timers.reset(); + const after = getCurrentTimersDescriptors(); + + assert.deepStrictEqual( + before, + after, + 'after reseting timers, the original propertyDescriptor should be preserved', + ); + + assert.notDeepStrictEqual( + before, + during, + 'after enabling timers, the original propertyDescriptor should be changed', + ); + + assert.notDeepStrictEqual( + during, + after, + 'after reseting timers, the original propertyDescriptor should be changed', + ); + }); + it('should reset all timers when calling .reset function', (t) => { t.mock.timers.enable(); const fn = t.mock.fn(); From 64f872a28f867fa3a4c2ccd101e8328f4f57d807 Mon Sep 17 00:00:00 2001 From: Erick Wendel Date: Fri, 1 Sep 2023 15:59:39 -0300 Subject: [PATCH 3/3] test_runner: refactoring functions Signed-off-by: Erick Wendel --- lib/internal/test_runner/mock/mock_timers.js | 294 ++++++++++--------- test/parallel/test-runner-mock-timers.js | 9 +- 2 files changed, 162 insertions(+), 141 deletions(-) diff --git a/lib/internal/test_runner/mock/mock_timers.js b/lib/internal/test_runner/mock/mock_timers.js index 873f03066fd02e..7e38f9f7b5113c 100644 --- a/lib/internal/test_runner/mock/mock_timers.js +++ b/lib/internal/test_runner/mock/mock_timers.js @@ -241,26 +241,7 @@ class MockTimers { toFake: { __proto__: null, setTimeout: () => { - this.#realSetTimeout = ObjectGetOwnPropertyDescriptor( - globalThis, - 'setTimeout', - ); - this.#realClearTimeout = ObjectGetOwnPropertyDescriptor( - globalThis, - 'clearTimeout', - ); - this.#realTimersSetTimeout = ObjectGetOwnPropertyDescriptor( - nodeTimers, - 'setTimeout', - ); - this.#realTimersClearTimeout = ObjectGetOwnPropertyDescriptor( - nodeTimers, - 'clearTimeout', - ); - this.#realPromisifiedSetTimeout = ObjectGetOwnPropertyDescriptor( - nodeTimersPromises, - 'setTimeout', - ); + this.#storeOriginalSetTimeout(); globalThis.setTimeout = this.#setTimeout; globalThis.clearTimeout = this.#clearTimeout; @@ -274,26 +255,7 @@ class MockTimers { ); }, setInterval: () => { - this.#realSetInterval = ObjectGetOwnPropertyDescriptor( - globalThis, - 'setInterval', - ); - this.#realClearInterval = ObjectGetOwnPropertyDescriptor( - globalThis, - 'clearInterval', - ); - this.#realTimersSetInterval = ObjectGetOwnPropertyDescriptor( - nodeTimers, - 'setInterval', - ); - this.#realTimersClearInterval = ObjectGetOwnPropertyDescriptor( - nodeTimers, - 'clearInterval', - ); - this.#realPromisifiedSetInterval = ObjectGetOwnPropertyDescriptor( - nodeTimersPromises, - 'setInterval', - ); + this.#storeOriginalSetInterval(); globalThis.setInterval = this.#setInterval; globalThis.clearInterval = this.#clearInterval; @@ -307,26 +269,7 @@ class MockTimers { ); }, setImmediate: () => { - this.#realSetImmediate = ObjectGetOwnPropertyDescriptor( - globalThis, - 'setImmediate', - ); - this.#realClearImmediate = ObjectGetOwnPropertyDescriptor( - globalThis, - 'clearImmediate', - ); - this.#realTimersSetImmediate = ObjectGetOwnPropertyDescriptor( - nodeTimers, - 'setImmediate', - ); - this.#realTimersClearImmediate = ObjectGetOwnPropertyDescriptor( - nodeTimers, - 'clearImmediate', - ); - this.#realPromisifiedSetImmediate = ObjectGetOwnPropertyDescriptor( - nodeTimersPromises, - 'setImmediate', - ); + this.#storeOriginalSetImmediate(); globalThis.setImmediate = this.#setImmediate; globalThis.clearImmediate = this.#clearImmediate; @@ -343,85 +286,13 @@ class MockTimers { toReal: { __proto__: null, setTimeout: () => { - ObjectDefineProperty( - globalThis, - 'setTimeout', - this.#realSetTimeout, - ); - ObjectDefineProperty( - globalThis, - 'clearTimeout', - this.#realClearTimeout, - ); - ObjectDefineProperty( - nodeTimers, - 'setTimeout', - this.#realSetTimeout, - ); - ObjectDefineProperty( - nodeTimers, - 'clearTimeout', - this.#realTimersClearTimeout, - ); - ObjectDefineProperty( - nodeTimersPromises, - 'setTimeout', - this.#realPromisifiedSetTimeout, - ); + this.#restoreOriginalSetTimeout(); }, setInterval: () => { - ObjectDefineProperty( - globalThis, - 'setInterval', - this.#realSetInterval, - ); - ObjectDefineProperty( - globalThis, - 'clearInterval', - this.#realClearInterval, - ); - ObjectDefineProperty( - nodeTimers, - 'setInterval', - this.#realTimersSetInterval, - ); - ObjectDefineProperty( - nodeTimers, - 'clearInterval', - this.#realTimersClearInterval, - ); - ObjectDefineProperty( - nodeTimersPromises, - 'setInterval', - this.#realPromisifiedSetInterval, - ); + this.#restoreOriginalSetInterval(); }, setImmediate: () => { - ObjectDefineProperty( - globalThis, - 'setImmediate', - this.#realSetImmediate, - ); - ObjectDefineProperty( - globalThis, - 'clearImmediate', - this.#realClearImmediate, - ); - ObjectDefineProperty( - nodeTimers, - 'setImmediate', - this.#realTimersSetImmediate, - ); - ObjectDefineProperty( - nodeTimers, - 'clearImmediate', - this.#realTimersClearImmediate, - ); - ObjectDefineProperty( - nodeTimersPromises, - 'setImmediate', - this.#realPromisifiedSetImmediate, - ); + this.#restoreSetImmediate(); }, }, }; @@ -431,6 +302,159 @@ class MockTimers { this.#isEnabled = activate; } + #restoreSetImmediate() { + ObjectDefineProperty( + globalThis, + 'setImmediate', + this.#realSetImmediate, + ); + ObjectDefineProperty( + globalThis, + 'clearImmediate', + this.#realClearImmediate, + ); + ObjectDefineProperty( + nodeTimers, + 'setImmediate', + this.#realTimersSetImmediate, + ); + ObjectDefineProperty( + nodeTimers, + 'clearImmediate', + this.#realTimersClearImmediate, + ); + ObjectDefineProperty( + nodeTimersPromises, + 'setImmediate', + this.#realPromisifiedSetImmediate, + ); + } + + #restoreOriginalSetInterval() { + ObjectDefineProperty( + globalThis, + 'setInterval', + this.#realSetInterval, + ); + ObjectDefineProperty( + globalThis, + 'clearInterval', + this.#realClearInterval, + ); + ObjectDefineProperty( + nodeTimers, + 'setInterval', + this.#realTimersSetInterval, + ); + ObjectDefineProperty( + nodeTimers, + 'clearInterval', + this.#realTimersClearInterval, + ); + ObjectDefineProperty( + nodeTimersPromises, + 'setInterval', + this.#realPromisifiedSetInterval, + ); + } + + #restoreOriginalSetTimeout() { + ObjectDefineProperty( + globalThis, + 'setTimeout', + this.#realSetTimeout, + ); + ObjectDefineProperty( + globalThis, + 'clearTimeout', + this.#realClearTimeout, + ); + ObjectDefineProperty( + nodeTimers, + 'setTimeout', + this.#realSetTimeout, + ); + ObjectDefineProperty( + nodeTimers, + 'clearTimeout', + this.#realTimersClearTimeout, + ); + ObjectDefineProperty( + nodeTimersPromises, + 'setTimeout', + this.#realPromisifiedSetTimeout, + ); + } + + #storeOriginalSetImmediate() { + this.#realSetImmediate = ObjectGetOwnPropertyDescriptor( + globalThis, + 'setImmediate', + ); + this.#realClearImmediate = ObjectGetOwnPropertyDescriptor( + globalThis, + 'clearImmediate', + ); + this.#realTimersSetImmediate = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'setImmediate', + ); + this.#realTimersClearImmediate = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'clearImmediate', + ); + this.#realPromisifiedSetImmediate = ObjectGetOwnPropertyDescriptor( + nodeTimersPromises, + 'setImmediate', + ); + } + + #storeOriginalSetInterval() { + this.#realSetInterval = ObjectGetOwnPropertyDescriptor( + globalThis, + 'setInterval', + ); + this.#realClearInterval = ObjectGetOwnPropertyDescriptor( + globalThis, + 'clearInterval', + ); + this.#realTimersSetInterval = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'setInterval', + ); + this.#realTimersClearInterval = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'clearInterval', + ); + this.#realPromisifiedSetInterval = ObjectGetOwnPropertyDescriptor( + nodeTimersPromises, + 'setInterval', + ); + } + + #storeOriginalSetTimeout() { + this.#realSetTimeout = ObjectGetOwnPropertyDescriptor( + globalThis, + 'setTimeout', + ); + this.#realClearTimeout = ObjectGetOwnPropertyDescriptor( + globalThis, + 'clearTimeout', + ); + this.#realTimersSetTimeout = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'setTimeout', + ); + this.#realTimersClearTimeout = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'clearTimeout', + ); + this.#realPromisifiedSetTimeout = ObjectGetOwnPropertyDescriptor( + nodeTimersPromises, + 'setTimeout', + ); + } + tick(time = 1) { if (!this.#isEnabled) { throw new ERR_INVALID_STATE( diff --git a/test/parallel/test-runner-mock-timers.js b/test/parallel/test-runner-mock-timers.js index 0fc24471fee995..c740aa3b4958d4 100644 --- a/test/parallel/test-runner-mock-timers.js +++ b/test/parallel/test-runner-mock-timers.js @@ -57,7 +57,7 @@ describe('Mock Timers Test Suite', () => { 'clearInterval', 'setImmediate', 'clearImmediate', - ] + ]; const globalTimersDescriptors = timers.map((fn) => getDescriptor(global, fn)); const nodeTimersDescriptors = timers.map((fn) => getDescriptor(nodeTimers, fn)); @@ -69,8 +69,8 @@ describe('Mock Timers Test Suite', () => { global: globalTimersDescriptors, nodeTimers: nodeTimersDescriptors, nodeTimersPromises: nodeTimersPromisesDescriptors, - } - } + }; + }; const before = getCurrentTimersDescriptors(); t.mock.timers.enable(); const during = getCurrentTimersDescriptors(); @@ -80,19 +80,16 @@ describe('Mock Timers Test Suite', () => { assert.deepStrictEqual( before, after, - 'after reseting timers, the original propertyDescriptor should be preserved', ); assert.notDeepStrictEqual( before, during, - 'after enabling timers, the original propertyDescriptor should be changed', ); assert.notDeepStrictEqual( during, after, - 'after reseting timers, the original propertyDescriptor should be changed', ); });