From b334e29d59b39e305ac7b71e4eaed454ababa5f2 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Tue, 30 Jan 2024 14:57:32 -0800 Subject: [PATCH] refactor(zone.js): read patched timers after they are patched (#53443) This moves timer patching from a top-level side effect into the `patchFakeAsyncTest` function. Top-level statements are evaluated before the Node patches run and have a chance to patch them with the Zone versions of these timers, meaning `FakeAsyncTestZoneSpec` was repatching the native versions between tests. The fix here is to grab the patched versions of these timers during the `patchFakeAsyncTest` function where we can be confident Node patches have already run. PR Close #53443 --- .../zone.js/lib/zone-spec/fake-async-test.ts | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/packages/zone.js/lib/zone-spec/fake-async-test.ts b/packages/zone.js/lib/zone-spec/fake-async-test.ts index 014fd0995db..45d9096e757 100644 --- a/packages/zone.js/lib/zone-spec/fake-async-test.ts +++ b/packages/zone.js/lib/zone-spec/fake-async-test.ts @@ -61,12 +61,12 @@ FakeDate.UTC = OriginalDate.UTC; FakeDate.parse = OriginalDate.parse; // keep a reference for zone patched timer function -const timers = { - setTimeout: global.setTimeout, - setInterval: global.setInterval, - clearTimeout: global.clearTimeout, - clearInterval: global.clearInterval -}; +let patchedTimers: { + setTimeout: typeof setTimeout, + setInterval: typeof setInterval, + clearTimeout: typeof clearTimeout, + clearInterval: typeof clearInterval, +}|undefined; class Scheduler { // Next scheduler id. @@ -475,13 +475,17 @@ class FakeAsyncTestZoneSpec implements ZoneSpec { } static checkTimerPatch() { - if (global.setTimeout !== timers.setTimeout) { - global.setTimeout = timers.setTimeout; - global.clearTimeout = timers.clearTimeout; + if (!patchedTimers) { + throw new Error('Expected timers to have been patched.'); } - if (global.setInterval !== timers.setInterval) { - global.setInterval = timers.setInterval; - global.clearInterval = timers.clearInterval; + + if (global.setTimeout !== patchedTimers.setTimeout) { + global.setTimeout = patchedTimers.setTimeout; + global.clearTimeout = patchedTimers.clearTimeout; + } + if (global.setInterval !== patchedTimers.setInterval) { + global.setInterval = patchedTimers.setInterval; + global.clearInterval = patchedTimers.clearInterval; } } @@ -868,4 +872,11 @@ export function patchFakeAsyncTest(Zone: ZoneType): void { (Zone as any)[api.symbol('fakeAsyncTest')] = {resetFakeAsyncZone, flushMicrotasks, discardPeriodicTasks, tick, flush, fakeAsync}; }, true); + + patchedTimers = { + setTimeout: global.setTimeout, + setInterval: global.setInterval, + clearTimeout: global.clearTimeout, + clearInterval: global.clearInterval + }; }