Skip to content

Commit dd3a042

Browse files
committed
fix(@angular/build): add update option to vitest unit-test builder
Closes #32218
1 parent 7fbc715 commit dd3a042

File tree

4 files changed

+93
-0
lines changed

4 files changed

+93
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ export async function normalizeOptions(
127127
: [],
128128
dumpVirtualFiles: options.dumpVirtualFiles,
129129
listTests: options.listTests,
130+
update: options.update ?? false,
130131
runnerConfig:
131132
typeof runnerConfig === 'string'
132133
? runnerConfig.length === 0
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
10+
import { tmpdir } from 'node:os';
11+
import { join } from 'node:path';
12+
import { normalizeOptions } from './options';
13+
import type { Schema as UnitTestBuilderOptions } from './schema';
14+
15+
function createMockContext(workspaceRoot: string) {
16+
return {
17+
workspaceRoot,
18+
target: { project: 'test-project', target: 'test', configuration: '' },
19+
logger: { warn: () => {}, info: () => {}, error: () => {}, debug: () => {} },
20+
getProjectMetadata: async (_projectName: string) => ({
21+
root: '.',
22+
sourceRoot: 'src',
23+
}),
24+
getBuilderNameForTarget: async () => '@angular/build:application',
25+
};
26+
}
27+
28+
describe('normalizeOptions', () => {
29+
let workspaceRoot: string;
30+
31+
beforeEach(async () => {
32+
workspaceRoot = await mkdtemp(join(tmpdir(), 'angular-cli-options-spec-'));
33+
// Write a minimal package.json so cache normalization works
34+
await writeFile(join(workspaceRoot, 'package.json'), '{}');
35+
// Create a tsconfig.spec.json so tsConfig resolution succeeds
36+
await mkdir(join(workspaceRoot, 'src'), { recursive: true });
37+
await writeFile(join(workspaceRoot, 'tsconfig.spec.json'), '{}');
38+
});
39+
40+
afterEach(async () => {
41+
await rm(workspaceRoot, { recursive: true, force: true });
42+
});
43+
44+
it('should set update to false by default', async () => {
45+
const options: UnitTestBuilderOptions = {};
46+
const context = createMockContext(workspaceRoot);
47+
48+
const normalized = await normalizeOptions(
49+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
50+
context as any,
51+
'test-project',
52+
options,
53+
);
54+
55+
expect(normalized.update).toBeFalse();
56+
});
57+
58+
it('should set update to true when update option is true', async () => {
59+
const options: UnitTestBuilderOptions = { update: true };
60+
const context = createMockContext(workspaceRoot);
61+
62+
const normalized = await normalizeOptions(
63+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
64+
context as any,
65+
'test-project',
66+
options,
67+
);
68+
69+
expect(normalized.update).toBeTrue();
70+
});
71+
72+
it('should set update to false when update option is explicitly false', async () => {
73+
const options: UnitTestBuilderOptions = { update: false };
74+
const context = createMockContext(workspaceRoot);
75+
76+
const normalized = await normalizeOptions(
77+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
78+
context as any,
79+
'test-project',
80+
options,
81+
);
82+
83+
expect(normalized.update).toBeFalse();
84+
});
85+
});

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ export class VitestExecutor implements TestExecutor {
240240
runnerConfig,
241241
projectSourceRoot,
242242
cacheOptions,
243+
update,
243244
} = this.options;
244245
const projectName = this.projectName;
245246

@@ -355,6 +356,7 @@ export class VitestExecutor implements TestExecutor {
355356
cache: cacheOptions.enabled ? undefined : (false as const),
356357
testNamePattern: this.options.filter,
357358
watch,
359+
...(update ? { update } : {}),
358360
...(typeof ui === 'boolean' ? { ui } : {}),
359361
...debugOptions,
360362
};

packages/angular/build/src/builders/unit-test/schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@
262262
"type": "boolean",
263263
"description": "Shows build progress information in the console. Defaults to the `progress` setting of the specified `buildTarget`."
264264
},
265+
"update": {
266+
"type": "boolean",
267+
"description": "Updates existing snapshots when they fail instead of failing the test. Only available for the Vitest runner.",
268+
"default": false
269+
},
265270
"listTests": {
266271
"type": "boolean",
267272
"description": "Lists all discovered test files and exits the process without building or executing the tests.",

0 commit comments

Comments
 (0)