Skip to content

Commit 8fc1420

Browse files
committed
refactor(@angular/build): cleanup Vitest build options utilities
Extract zone testing strategy resolution to a separate function and reduce complexity of template literals.
1 parent f1ed025 commit 8fc1420

File tree

1 file changed

+73
-26
lines changed

1 file changed

+73
-26
lines changed

packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts

Lines changed: 73 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9+
/**
10+
* @fileoverview
11+
* Provides Vitest-specific build options and virtual file contents for Angular unit testing.
12+
*/
13+
914
import { createRequire } from 'node:module';
1015
import path from 'node:path';
1116
import { toPosixPath } from '../../../../utils/path';
@@ -15,6 +20,15 @@ import { NormalizedUnitTestBuilderOptions } from '../../options';
1520
import { findTests, getTestEntrypoints } from '../../test-discovery';
1621
import { RunnerOptions } from '../api';
1722

23+
/**
24+
* Creates the virtual file contents to initialize the Angular testing environment (TestBed).
25+
*
26+
* @param providersFile Optional path to a file that exports default providers.
27+
* @param projectSourceRoot The root directory of the project source.
28+
* @param teardown Whether to configure TestBed to destroy after each test.
29+
* @param zoneTestingStrategy How zone.js should be loaded during initialization.
30+
* @returns The string content of the virtual initialization file.
31+
*/
1832
function createTestBedInitVirtualFile(
1933
providersFile: string | undefined,
2034
projectSourceRoot: string,
@@ -29,6 +43,17 @@ function createTestBedInitVirtualFile(
2943
providersImport = `import providers from './${importPath}';`;
3044
}
3145

46+
let zoneTestingSnippet = '';
47+
if (zoneTestingStrategy === 'static') {
48+
zoneTestingSnippet = `import 'zone.js/testing';`;
49+
} else if (zoneTestingStrategy === 'dynamic') {
50+
zoneTestingSnippet = `if (typeof Zone !== 'undefined') {
51+
// 'zone.js/testing' is used to initialize the ZoneJS testing environment.
52+
// It must be imported dynamically to avoid a static dependency on 'zone.js'.
53+
await import('zone.js/testing');
54+
}`;
55+
}
56+
3257
return `
3358
// Initialize the Angular testing environment
3459
import { NgModule, provideZoneChangeDetection } from '@angular/core';
@@ -37,18 +62,7 @@ function createTestBedInitVirtualFile(
3762
import { afterEach, beforeEach } from 'vitest';
3863
${providersImport}
3964
40-
${
41-
zoneTestingStrategy === 'static'
42-
? `import 'zone.js/testing';`
43-
: zoneTestingStrategy === 'dynamic'
44-
? `
45-
if (typeof Zone !== 'undefined') {
46-
// 'zone.js/testing' is used to initialize the ZoneJS testing environment.
47-
// It must be imported dynamically to avoid a static dependency on 'zone.js'.
48-
await import('zone.js/testing');
49-
}`
50-
: ''
51-
}
65+
${zoneTestingSnippet}
5266
5367
// The beforeEach and afterEach hooks are registered outside the globalThis guard.
5468
// This ensures that the hooks are always applied, even in non-isolated browser environments.
@@ -81,6 +95,13 @@ function createTestBedInitVirtualFile(
8195
`;
8296
}
8397

98+
/**
99+
* Adjusts output hashing settings for testing purposes. For example, ensuring media
100+
* is continued to be hashed to avoid overwriting assets, but turning off JavaScript hashing.
101+
*
102+
* @param hashing The original OutputHashing configuration.
103+
* @returns The adjusted OutputHashing configuration.
104+
*/
84105
function adjustOutputHashing(hashing?: OutputHashing): OutputHashing {
85106
switch (hashing) {
86107
case OutputHashing.All:
@@ -92,6 +113,45 @@ function adjustOutputHashing(hashing?: OutputHashing): OutputHashing {
92113
}
93114
}
94115

116+
/**
117+
* Resolves the Zone.js testing strategy by inspecting polyfills and resolving zone.js package.
118+
*
119+
* @param buildOptions The partial application builder options.
120+
* @param projectSourceRoot The root directory of the project source.
121+
* @returns The resolved zone testing strategy ('none', 'static', 'dynamic').
122+
*/
123+
function getZoneTestingStrategy(
124+
buildOptions: Partial<ApplicationBuilderInternalOptions>,
125+
projectSourceRoot: string,
126+
): 'none' | 'static' | 'dynamic' {
127+
if (buildOptions.polyfills?.includes('zone.js/testing')) {
128+
return 'none';
129+
}
130+
131+
if (buildOptions.polyfills?.includes('zone.js')) {
132+
return 'static';
133+
}
134+
135+
try {
136+
const projectRequire = createRequire(path.join(projectSourceRoot, 'package.json'));
137+
projectRequire.resolve('zone.js');
138+
139+
return 'dynamic';
140+
} catch {
141+
return 'none';
142+
}
143+
}
144+
145+
/**
146+
* Generates options and virtual files for the Vitest test runner.
147+
*
148+
* Discovers specs matchers, creates entry points, decides polyfills strategy, and orchestrates
149+
* internal ApplicationBuilder options.
150+
*
151+
* @param options The normalized unit test builder options.
152+
* @param baseBuildOptions The base build config to derive testing config from.
153+
* @returns An async RunnerOptions configuration.
154+
*/
95155
export async function getVitestBuildOptions(
96156
options: NormalizedUnitTestBuilderOptions,
97157
baseBuildOptions: Partial<ApplicationBuilderInternalOptions>,
@@ -162,20 +222,7 @@ export async function getVitestBuildOptions(
162222
};
163223

164224
// Inject the zone.js testing polyfill if Zone.js is installed.
165-
let zoneTestingStrategy: 'none' | 'static' | 'dynamic';
166-
if (buildOptions.polyfills?.includes('zone.js/testing')) {
167-
zoneTestingStrategy = 'none';
168-
} else if (buildOptions.polyfills?.includes('zone.js')) {
169-
zoneTestingStrategy = 'static';
170-
} else {
171-
try {
172-
const projectRequire = createRequire(path.join(projectSourceRoot, 'package.json'));
173-
projectRequire.resolve('zone.js');
174-
zoneTestingStrategy = 'dynamic';
175-
} catch {
176-
zoneTestingStrategy = 'none';
177-
}
178-
}
225+
const zoneTestingStrategy = getZoneTestingStrategy(buildOptions, projectSourceRoot);
179226

180227
const testBedInitContents = createTestBedInitVirtualFile(
181228
providersFile,

0 commit comments

Comments
 (0)