Skip to content

Commit 864a502

Browse files
committed
feat(@schematics/angular): add migration to add istanbul-lib-instrument
Add a new schematic migration to automatically add istanbul-lib-instrument to devDependencies for projects that use Karma. Covered builders: - @angular-devkit/build-angular:karma - @angular/build:karma - @angular/build:unit-test (when runner is 'karma')
1 parent 16ad264 commit 864a502

File tree

4 files changed

+161
-0
lines changed

4 files changed

+161
-0
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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 { Rule } from '@angular-devkit/schematics';
10+
import { DependencyType, ExistingBehavior, addDependency } from '../../utility/dependency';
11+
import { latestVersions } from '../../utility/latest-versions';
12+
import { allTargetOptions, getWorkspace } from '../../utility/workspace';
13+
import { Builders } from '../../utility/workspace-models';
14+
15+
export default function (): Rule {
16+
return async (tree) => {
17+
const workspace = await getWorkspace(tree);
18+
let needInstrumenter = false;
19+
20+
for (const [, project] of workspace.projects) {
21+
for (const [, target] of project.targets) {
22+
if (target.builder === Builders.Karma || target.builder === Builders.BuildKarma) {
23+
needInstrumenter = true;
24+
break;
25+
}
26+
27+
if (target.builder === Builders.BuildUnitTest) {
28+
for (const [, options] of allTargetOptions(target)) {
29+
if (options['runner'] === 'karma') {
30+
needInstrumenter = true;
31+
break;
32+
}
33+
}
34+
}
35+
36+
if (needInstrumenter) {
37+
break;
38+
}
39+
}
40+
if (needInstrumenter) {
41+
break;
42+
}
43+
}
44+
45+
if (needInstrumenter) {
46+
return addDependency('istanbul-lib-instrument', latestVersions['istanbul-lib-instrument'], {
47+
type: DependencyType.Dev,
48+
existing: ExistingBehavior.Skip,
49+
});
50+
}
51+
};
52+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
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+
/* eslint-disable @typescript-eslint/no-explicit-any */
10+
11+
import { EmptyTree } from '@angular-devkit/schematics';
12+
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
13+
14+
describe('Migration to add istanbul-lib-instrument', () => {
15+
const schematicRunner = new SchematicTestRunner(
16+
'migrations',
17+
require.resolve('../migration-collection.json'),
18+
);
19+
20+
let tree: UnitTestTree;
21+
beforeEach(() => {
22+
tree = new UnitTestTree(new EmptyTree());
23+
tree.create(
24+
'/package.json',
25+
JSON.stringify({
26+
devDependencies: {},
27+
}),
28+
);
29+
});
30+
31+
function createWorkspace(builder: string, options?: any, configurations?: any) {
32+
tree.create(
33+
'/angular.json',
34+
JSON.stringify({
35+
version: 1,
36+
projects: {
37+
app: {
38+
root: '',
39+
targets: {
40+
test: {
41+
builder,
42+
options,
43+
configurations,
44+
},
45+
},
46+
},
47+
},
48+
}),
49+
);
50+
}
51+
52+
async function expectDependency(defined: boolean) {
53+
const newTree = await schematicRunner.runSchematic('add-istanbul-instrumenter', {}, tree);
54+
const { devDependencies } = newTree.readJson('/package.json') as any;
55+
if (defined) {
56+
expect(devDependencies['istanbul-lib-instrument']).toBeDefined();
57+
} else {
58+
expect(devDependencies['istanbul-lib-instrument']).toBeUndefined();
59+
}
60+
}
61+
62+
it('should add istanbul-lib-instrument for @angular-devkit/build-angular:karma', async () => {
63+
createWorkspace('@angular-devkit/build-angular:karma');
64+
65+
await expectDependency(true);
66+
});
67+
68+
it('should add istanbul-lib-instrument for @angular/build:karma', async () => {
69+
createWorkspace('@angular/build:karma');
70+
71+
await expectDependency(true);
72+
});
73+
74+
it('should add istanbul-lib-instrument for @angular/build:unit-test with runner: karma', async () => {
75+
createWorkspace('@angular/build:unit-test', { runner: 'karma' });
76+
77+
await expectDependency(true);
78+
});
79+
80+
it('should add istanbul-lib-instrument if runner: karma is in configuration', async () => {
81+
createWorkspace('@angular/build:unit-test', undefined, { ci: { runner: 'karma' } });
82+
83+
await expectDependency(true);
84+
});
85+
86+
it('should NOT add istanbul-lib-instrument for @angular/build:unit-test with runner: vitest', async () => {
87+
createWorkspace('@angular/build:unit-test', { runner: 'vitest' });
88+
89+
await expectDependency(false);
90+
});
91+
92+
it('should NOT add istanbul-lib-instrument for @angular/build:unit-test with no runner specified (default vitest)', async () => {
93+
createWorkspace('@angular/build:unit-test', {});
94+
95+
await expectDependency(false);
96+
});
97+
98+
it('should NOT add istanbul-lib-instrument if no karma builder is used', async () => {
99+
createWorkspace('@angular-devkit/build-angular:browser');
100+
101+
await expectDependency(false);
102+
});
103+
});

packages/schematics/angular/migrations/migration-collection.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
{
22
"encapsulation": false,
33
"schematics": {
4+
"add-istanbul-instrumenter": {
5+
"version": "22.0.0",
6+
"factory": "./add-istanbul-instrumenter/migration",
7+
"description": "Add istanbul-lib-instrument to devDependencies if Karma unit testing is used."
8+
},
49
"use-application-builder": {
510
"version": "22.0.0",
611
"factory": "./use-application-builder/migration",

packages/schematics/angular/utility/latest-versions/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"@types/node": "^20.17.19",
99
"browser-sync": "^3.0.0",
1010
"express": "^5.1.0",
11+
"istanbul-lib-instrument": "^6.0.3",
1112
"jasmine-core": "~6.1.0",
1213
"jasmine-spec-reporter": "~7.0.0",
1314
"karma-chrome-launcher": "~3.2.0",

0 commit comments

Comments
 (0)