Skip to content

Commit bfcee38

Browse files
committed
fix(@angular/build): allow vitest-based unit testing to use watch option
When using the `application` build system with the experimental `unit-test` vitest support, the `watch` option will now be passed through to the underlying test runner. This allows vitest to be used for watch-based test development. Incremental test file updates from the build system are also enabled in watch mode as well to remove the need to rewrite all output files on a rebuild.
1 parent 8d46742 commit bfcee38

File tree

2 files changed

+46
-37
lines changed

2 files changed

+46
-37
lines changed

packages/angular/build/src/builders/unit-test/builder.ts

+43-34
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ export async function* execute(
100100
const buildOptions: ApplicationBuilderInternalOptions = {
101101
...buildTargetOptions,
102102
watch: normalizedOptions.watch,
103+
incrementalResults: normalizedOptions.watch,
103104
outputPath,
104105
index: false,
105106
browser: undefined,
@@ -171,44 +172,52 @@ export async function* execute(
171172
};
172173
}
173174

174-
for await (const result of buildApplicationInternal(buildOptions, context, extensions)) {
175-
if (result.kind === ResultKind.Failure) {
176-
continue;
177-
} else if (result.kind !== ResultKind.Full) {
178-
assert.fail('A full build result is required from the application builder.');
179-
}
180-
181-
assert(result.files, 'Builder did not provide result files.');
182-
183-
await writeTestFiles(result.files, outputPath);
184-
185-
const setupFiles = ['init-testbed.js'];
186-
if (buildTargetOptions?.polyfills?.length) {
187-
setupFiles.push('polyfills.js');
188-
}
175+
const setupFiles = ['init-testbed.js'];
176+
if (buildTargetOptions?.polyfills?.length) {
177+
setupFiles.push('polyfills.js');
178+
}
189179

190-
instance ??= await startVitest('test', undefined /* cliFilters */, undefined /* options */, {
191-
test: {
192-
root: outputPath,
193-
setupFiles,
194-
// Use `jsdom` if no browsers are explicitly configured.
195-
// `node` is effectively no "environment" and the default.
196-
environment: browser ? 'node' : 'jsdom',
197-
watch: normalizedOptions.watch,
198-
browser,
199-
reporters: normalizedOptions.reporters ?? ['default'],
200-
coverage: {
201-
enabled: normalizedOptions.codeCoverage,
202-
exclude: normalizedOptions.codeCoverageExclude,
203-
excludeAfterRemap: true,
180+
try {
181+
for await (const result of buildApplicationInternal(buildOptions, context, extensions)) {
182+
if (result.kind === ResultKind.Failure) {
183+
continue;
184+
} else if (result.kind !== ResultKind.Full && result.kind !== ResultKind.Incremental) {
185+
assert.fail(
186+
'A full and/or incremental build result is required from the application builder.',
187+
);
188+
}
189+
assert(result.files, 'Builder did not provide result files.');
190+
191+
await writeTestFiles(result.files, outputPath);
192+
193+
instance ??= await startVitest('test', undefined /* cliFilters */, undefined /* options */, {
194+
test: {
195+
root: outputPath,
196+
setupFiles,
197+
// Use `jsdom` if no browsers are explicitly configured.
198+
// `node` is effectively no "environment" and the default.
199+
environment: browser ? 'node' : 'jsdom',
200+
watch: normalizedOptions.watch,
201+
browser,
202+
reporters: normalizedOptions.reporters ?? ['default'],
203+
coverage: {
204+
enabled: normalizedOptions.codeCoverage,
205+
exclude: normalizedOptions.codeCoverageExclude,
206+
excludeAfterRemap: true,
207+
},
204208
},
205-
},
206-
});
209+
});
207210

208-
// Check if all the tests pass to calculate the result
209-
const testModules = instance.state.getTestModules();
211+
// Check if all the tests pass to calculate the result
212+
const testModules = instance.state.getTestModules();
210213

211-
yield { success: testModules.every((testModule) => testModule.ok()) };
214+
yield { success: testModules.every((testModule) => testModule.ok()) };
215+
}
216+
} finally {
217+
if (normalizedOptions.watch) {
218+
// Vitest will automatically close if not using watch mode
219+
await instance?.close();
220+
}
212221
}
213222
}
214223

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ export async function normalizeOptions(
3232
const buildTargetSpecifier = options.buildTarget ?? `::development`;
3333
const buildTarget = targetFromTargetString(buildTargetSpecifier, projectName, 'build');
3434

35-
const { codeCoverage, codeCoverageExclude, tsConfig, runner, reporters, browsers } = options;
35+
const { codeCoverage, codeCoverageExclude, tsConfig, runner, reporters, browsers, watch } =
36+
options;
3637

3738
return {
3839
// Project/workspace information
@@ -50,8 +51,7 @@ export async function normalizeOptions(
5051
tsConfig,
5152
reporters,
5253
browsers,
53-
// TODO: Implement watch support
54-
watch: false,
54+
watch,
5555
};
5656
}
5757

0 commit comments

Comments
 (0)