Skip to content

Commit 4356e85

Browse files
committed
fix(core): fakeAsync should not depend on module import order (#61375)
`fakeAsync` does not work if the zone-testing polyfill is included after @angular/core/testing is loaded. This allows fakeAsync to work even if the zone-testing is included later. PR Close #61375
1 parent e33444e commit 4356e85

File tree

1 file changed

+19
-29
lines changed

1 file changed

+19
-29
lines changed

packages/core/testing/src/fake_async.ts

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,18 @@
1010
import type {} from 'zone.js';
1111

1212
const _Zone: any = typeof Zone !== 'undefined' ? Zone : null;
13-
const fakeAsyncTestModule = _Zone && _Zone[_Zone.__symbol__('fakeAsyncTest')];
13+
function getFakeAsyncTestModule() {
14+
return _Zone && _Zone[_Zone.__symbol__('fakeAsyncTest')];
15+
}
1416

15-
const fakeAsyncTestModuleNotLoadedErrorMessage = `zone-testing.js is needed for the fakeAsync() test helper but could not be found.
16-
Please make sure that your environment includes zone.js/testing`;
17+
function withFakeAsyncTestModule(fn: (fakeAsyncTestModule: any) => any): any {
18+
const fakeAsyncTestModule = getFakeAsyncTestModule();
19+
if (!fakeAsyncTestModule) {
20+
throw new Error(`zone-testing.js is needed for the fakeAsync() test helper but could not be found.
21+
Please make sure that your environment includes zone.js/testing`);
22+
}
23+
return fn(fakeAsyncTestModule);
24+
}
1725

1826
/**
1927
* Clears out the shared fake async zone for a test.
@@ -22,15 +30,12 @@ const fakeAsyncTestModuleNotLoadedErrorMessage = `zone-testing.js is needed for
2230
* @publicApi
2331
*/
2432
export function resetFakeAsyncZone(): void {
25-
if (fakeAsyncTestModule) {
26-
return fakeAsyncTestModule.resetFakeAsyncZone();
27-
}
28-
throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);
33+
withFakeAsyncTestModule((v) => v.resetFakeAsyncZone());
2934
}
3035

3136
export function resetFakeAsyncZoneIfExists(): void {
32-
if (fakeAsyncTestModule && (Zone as any)['ProxyZoneSpec']?.isLoaded()) {
33-
fakeAsyncTestModule.resetFakeAsyncZone();
37+
if (getFakeAsyncTestModule() && (Zone as any)['ProxyZoneSpec']?.isLoaded()) {
38+
getFakeAsyncTestModule().resetFakeAsyncZone();
3439
}
3540
}
3641

@@ -59,10 +64,7 @@ export function resetFakeAsyncZoneIfExists(): void {
5964
* @publicApi
6065
*/
6166
export function fakeAsync(fn: Function, options?: {flush?: boolean}): (...args: any[]) => any {
62-
if (fakeAsyncTestModule) {
63-
return fakeAsyncTestModule.fakeAsync(fn, options);
64-
}
65-
throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);
67+
return withFakeAsyncTestModule((v) => v.fakeAsync(fn, options));
6668
}
6769

6870
/**
@@ -135,10 +137,7 @@ export function tick(
135137
processNewMacroTasksSynchronously: true,
136138
},
137139
): void {
138-
if (fakeAsyncTestModule) {
139-
return fakeAsyncTestModule.tick(millis, tickOptions);
140-
}
141-
throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);
140+
return withFakeAsyncTestModule((m) => m.tick(millis, tickOptions));
142141
}
143142

144143
/**
@@ -153,10 +152,7 @@ export function tick(
153152
* @publicApi
154153
*/
155154
export function flush(maxTurns?: number): number {
156-
if (fakeAsyncTestModule) {
157-
return fakeAsyncTestModule.flush(maxTurns);
158-
}
159-
throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);
155+
return withFakeAsyncTestModule((m) => m.flush(maxTurns));
160156
}
161157

162158
/**
@@ -165,10 +161,7 @@ export function flush(maxTurns?: number): number {
165161
* @publicApi
166162
*/
167163
export function discardPeriodicTasks(): void {
168-
if (fakeAsyncTestModule) {
169-
return fakeAsyncTestModule.discardPeriodicTasks();
170-
}
171-
throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);
164+
return withFakeAsyncTestModule((m) => m.discardPeriodicTasks());
172165
}
173166

174167
/**
@@ -177,8 +170,5 @@ export function discardPeriodicTasks(): void {
177170
* @publicApi
178171
*/
179172
export function flushMicrotasks(): void {
180-
if (fakeAsyncTestModule) {
181-
return fakeAsyncTestModule.flushMicrotasks();
182-
}
183-
throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);
173+
return withFakeAsyncTestModule((m) => m.flushMicrotasks());
184174
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy