Skip to content

Commit 7156608

Browse files
committed
fix(@schematics/angular): support testRunner option in library schematic
This commit introduces the `testRunner` option to the library schematic, allowing users to explicitly select between `vitest` and `karma` as their test runner. Additionally, the `ng-new` schematic has been updated to configure the default `testRunner` for libraries in `angular.json` based on the workspace creation options. Closes #31887
1 parent 0fe572e commit 7156608

File tree

6 files changed

+44
-35
lines changed

6 files changed

+44
-35
lines changed

packages/schematics/angular/application/index.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -392,17 +392,15 @@ function addAppToWorkspaceFile(options: ApplicationOptions, appDir: string): Rul
392392
test:
393393
options.skipTests || options.minimal
394394
? undefined
395-
: options.testRunner === 'vitest'
396-
? {
397-
builder: Builders.BuildUnitTest,
398-
options: {},
399-
}
400-
: {
401-
builder: Builders.BuildUnitTest,
402-
options: {
403-
runner: 'karma',
404-
},
405-
},
395+
: {
396+
builder: Builders.BuildUnitTest,
397+
options:
398+
options.testRunner === 'vitest'
399+
? {}
400+
: {
401+
runner: 'karma',
402+
},
403+
},
406404
},
407405
};
408406

packages/schematics/angular/library/index.ts

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ function addLibToWorkspaceFile(
9191
projectRoot: string,
9292
projectName: string,
9393
hasZoneDependency: boolean,
94-
hasVitest: boolean,
9594
): Rule {
9695
return updateWorkspace((workspace) => {
9796
workspace.projects.add({
@@ -113,20 +112,21 @@ function addLibToWorkspaceFile(
113112
},
114113
},
115114
},
116-
test: hasVitest
117-
? {
118-
builder: Builders.BuildUnitTest,
119-
options: {
120-
tsConfig: `${projectRoot}/tsconfig.spec.json`,
115+
test:
116+
options.testRunner === 'vitest'
117+
? {
118+
builder: Builders.BuildUnitTest,
119+
options: {
120+
tsConfig: `${projectRoot}/tsconfig.spec.json`,
121+
},
122+
}
123+
: {
124+
builder: Builders.BuildKarma,
125+
options: {
126+
tsConfig: `${projectRoot}/tsconfig.spec.json`,
127+
polyfills: hasZoneDependency ? ['zone.js', 'zone.js/testing'] : undefined,
128+
},
121129
},
122-
}
123-
: {
124-
builder: Builders.BuildKarma,
125-
options: {
126-
tsConfig: `${projectRoot}/tsconfig.spec.json`,
127-
polyfills: hasZoneDependency ? ['zone.js', 'zone.js/testing'] : undefined,
128-
},
129-
},
130130
},
131131
});
132132
});
@@ -158,7 +158,6 @@ export default function (options: LibraryOptions): Rule {
158158

159159
const distRoot = `dist/${folderName}`;
160160
const sourceDir = `${libDir}/src/lib`;
161-
const hasVitest = getDependency(host, 'vitest') !== null;
162161

163162
const templateSource = apply(url('./files'), [
164163
applyTemplates({
@@ -172,7 +171,7 @@ export default function (options: LibraryOptions): Rule {
172171
angularLatestVersion: latestVersions.Angular.replace(/~|\^/, ''),
173172
tsLibLatestVersion: latestVersions['tslib'].replace(/~|\^/, ''),
174173
folderName,
175-
testTypesPackage: hasVitest ? 'vitest/globals' : 'jasmine',
174+
testTypesPackage: options.testRunner === 'vitest' ? 'vitest/globals' : 'jasmine',
176175
}),
177176
move(libDir),
178177
]);
@@ -181,7 +180,7 @@ export default function (options: LibraryOptions): Rule {
181180

182181
return chain([
183182
mergeWith(templateSource),
184-
addLibToWorkspaceFile(options, libDir, packageName, hasZoneDependency, hasVitest),
183+
addLibToWorkspaceFile(options, libDir, packageName, hasZoneDependency),
185184
options.skipPackageJson ? noop() : addDependenciesToPackageJson(!!options.skipInstall),
186185
options.skipTsConfig ? noop() : updateTsConfig(packageName, './' + distRoot),
187186
options.skipTsConfig

packages/schematics/angular/library/index_spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,11 +407,11 @@ describe('Library Schematic', () => {
407407
expect(workspace.projects.foo.architect.build.builder).toBe('@angular/build:ng-packagr');
408408
});
409409

410-
it(`should add 'karma' test builder`, async () => {
410+
it(`should add 'unit-test' test builder`, async () => {
411411
const tree = await schematicRunner.runSchematic('library', defaultOptions, workspaceTree);
412412

413413
const workspace = JSON.parse(tree.readContent('/angular.json'));
414-
expect(workspace.projects.foo.architect.test.builder).toBe('@angular/build:karma');
414+
expect(workspace.projects.foo.architect.test.builder).toBe('@angular/build:unit-test');
415415
});
416416

417417
it(`should add 'unit-test' test builder`, async () => {

packages/schematics/angular/library/schema.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@
5353
"type": "boolean",
5454
"default": true,
5555
"x-user-analytics": "ep.ng_standalone"
56+
},
57+
"testRunner": {
58+
"description": "The unit testing runner to use.",
59+
"type": "string",
60+
"enum": ["vitest", "karma"],
61+
"default": "vitest"
5662
}
5763
},
5864
"required": ["name"]

packages/schematics/angular/ng-new/index.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,21 @@ export default function (options: NgNewOptions): Rule {
6767
mergeWith(
6868
apply(empty(), [
6969
schematic('workspace', workspaceOptions),
70-
options.createApplication ? schematic('application', applicationOptions) : noop,
71-
schematic('ai-config', {
72-
tool: options.aiConfig?.length ? options.aiConfig : undefined,
73-
}),
7470
(tree: Tree) => {
7571
if (options.testRunner === 'karma') {
7672
const file = new JSONFile(tree, 'angular.json');
77-
file.modify(['schematics', '@schematics/angular:application', 'testRunner'], 'karma');
73+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
74+
const schematics = file.get(['schematics']) ?? ({} as any);
75+
(schematics['@schematics/angular:application'] ??= {}).testRunner = 'karma';
76+
(schematics['@schematics/angular:library'] ??= {}).testRunner = 'karma';
77+
78+
file.modify(['schematics'], schematics);
7879
}
7980
},
81+
options.createApplication ? schematic('application', applicationOptions) : noop,
82+
schematic('ai-config', {
83+
tool: options.aiConfig?.length ? options.aiConfig : undefined,
84+
}),
8085
move(options.directory),
8186
]),
8287
),

packages/schematics/angular/ng-new/index_spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ describe('Ng New Schematic', () => {
183183

184184
const { schematics } = JSON.parse(tree.readContent('/bar/angular.json'));
185185
expect(schematics['@schematics/angular:application'].testRunner).toBe('karma');
186+
expect(schematics['@schematics/angular:library'].testRunner).toBe('karma');
186187
});
187188

188189
it(`should not add type to class name when file name style guide is '2016'`, async () => {

0 commit comments

Comments
 (0)