Skip to content

Commit a7fef26

Browse files
kyliauKeen Yee Liau
authored and
Keen Yee Liau
committed
feat(@angular-devkit/build-angular): Switch to karma-coverage
This commit switches coverage tooling from karma-coverage-istanbul-reporter to karma-coverage since it's better supported.
1 parent bb2c109 commit a7fef26

File tree

13 files changed

+120
-71
lines changed

13 files changed

+120
-71
lines changed

integration/angular_cli/karma.conf.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,19 @@ module.exports = function (config) {
1212
require('karma-jasmine'),
1313
require('karma-chrome-launcher'),
1414
require('karma-jasmine-html-reporter'),
15-
require('karma-coverage-istanbul-reporter'),
15+
require('karma-coverage'),
1616
require('@angular-devkit/build-angular/plugins/karma'),
1717
],
1818
client: {
1919
clearContext: false, // leave Jasmine Spec Runner output visible in browser
2020
},
21-
coverageIstanbulReporter: {
21+
coverageReporter: {
2222
dir: path.join(__dirname, 'coverage'),
23-
reports: ['html', 'lcovonly'],
24-
fixWebpackSourcePaths: true,
23+
subdir: '.',
24+
reporters: [
25+
{type: 'html'},
26+
{type: 'lcov'},
27+
],
2528
},
2629
reporters: ['progress', 'kjhtml'],
2730
port: 9876,

integration/angular_cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"jasmine-spec-reporter": "~5.0.0",
3737
"karma": "~4.4.1",
3838
"karma-chrome-launcher": "~3.1.0",
39-
"karma-coverage-istanbul-reporter": "~2.1.0",
39+
"karma-coverage": "~2.0.2",
4040
"karma-jasmine": "~3.3.0",
4141
"karma-jasmine-html-reporter": "^1.5.0",
4242
"protractor": "~5.4.3",

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@
159159
"jquery": "^3.3.1",
160160
"karma": "~5.0.0",
161161
"karma-chrome-launcher": "~3.1.0",
162-
"karma-coverage-istanbul-reporter": "~3.0.0",
162+
"karma-coverage": "~2.0.2",
163163
"karma-jasmine": "~3.3.0",
164164
"karma-jasmine-html-reporter": "^1.5.0",
165165
"karma-source-map-support": "1.4.0",

packages/angular_devkit/build_angular/BUILD.bazel

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,10 +267,11 @@ LARGE_SPECS = {
267267
"extra_deps": [
268268
"@npm//karma",
269269
"@npm//karma-chrome-launcher",
270-
"@npm//karma-coverage-istanbul-reporter",
270+
"@npm//karma-coverage",
271271
"@npm//karma-jasmine",
272272
"@npm//karma-jasmine-html-reporter",
273273
"@npm//puppeteer",
274+
"@npm//@types/karma",
274275
],
275276
},
276277
"protractor": {

packages/angular_devkit/build_angular/src/angular-cli-files/plugins/karma.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { createConsoleLogger } from '@angular-devkit/core/node';
2020
import { logging } from '@angular-devkit/core';
2121
import { WebpackTestOptions } from '../models/build-options';
2222
import { normalizeSourceMaps } from '../../utils/index';
23+
import {TestResults} from 'karma';
2324

2425
/**
2526
* Enumerate needed (but not require/imported) dependencies from this file
@@ -33,8 +34,8 @@ import { normalizeSourceMaps } from '../../utils/index';
3334
let blocked: any[] = [];
3435
let isBlocked = false;
3536
let webpackMiddleware: any;
36-
let successCb: () => void;
37-
let failureCb: () => void;
37+
let successCb: (results: TestResults) => void;
38+
let failureCb: (results: TestResults) => void;
3839

3940
// Add files to the Karma files array.
4041
function addKarmaFiles(files: any[], newFiles: any[], prepend = false) {
@@ -72,8 +73,13 @@ const init: any = (config: any, emitter: any, customFileHandlers: any) => {
7273

7374
// When using code-coverage, auto-add coverage-istanbul.
7475
config.reporters = config.reporters || [];
75-
if (options.codeCoverage && config.reporters.indexOf('coverage-istanbul') === -1) {
76-
config.reporters.push('coverage-istanbul');
76+
// 'coverage-istanbul' comes from karma-coverage-istanbul-reporter package.
77+
// It is deprecated in favor of karma-coverage.
78+
const hasCoverageIstanbul = config.reporters.includes('coverage-istanbul');
79+
// 'coverage' comes from karma-coverage package.
80+
const hasKarmaCoverage = config.reporters.includes('coverage');
81+
if (options.codeCoverage && !hasCoverageIstanbul && !hasKarmaCoverage) {
82+
config.reporters.push('coverage');
7783
}
7884

7985
// Add a reporter that fixes sourcemap urls.
@@ -188,7 +194,13 @@ const init: any = (config: any, emitter: any, customFileHandlers: any) => {
188194
logger.error(statsErrorsToString(json, statsConfig));
189195
lastCompilationHash = undefined;
190196
// Emit a failure build event if there are compilation errors.
191-
failureCb && failureCb();
197+
failureCb({
198+
disconnected: false,
199+
error: true,
200+
exitCode: 1,
201+
failed: 0,
202+
success: 0,
203+
});
192204
} else if (stats.hash != lastCompilationHash) {
193205
// Refresh karma only when there are no webpack errors, and if the compilation changed.
194206
lastCompilationHash = stats.hash;
@@ -269,9 +281,9 @@ const eventReporter: any = function (this: any, baseReporterDecorator: any, conf
269281

270282
this.onRunComplete = function (_browsers: any, results: any) {
271283
if (results.exitCode === 0) {
272-
successCb && successCb();
284+
successCb(results);
273285
} else {
274-
failureCb && failureCb();
286+
failureCb(results);
275287
}
276288
}
277289

packages/angular_devkit/build_angular/src/karma/code-coverage_spec.ts

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,19 @@
77
*/
88
import { Architect } from '@angular-devkit/architect';
99
import { normalize, virtualFs } from '@angular-devkit/core';
10+
import { TestResults } from 'karma';
11+
import { promisify } from 'util';
1012
import { createArchitect, host, karmaTargetSpec } from '../test-utils';
1113

14+
// In each of the test below we'll have to call setTimeout to wait for the coverage
15+
// analysis to be done. This is because karma-coverage performs the analysis
16+
// asynchronously but the promise that it returns is not awaited by Karma.
17+
// Coverage analysis begins when onRunComplete() is invoked, and output files
18+
// are subsequently written to disk. For more information, see
19+
// https://github.com/karma-runner/karma-coverage/blob/32acafa90ed621abd1df730edb44ae55a4009c2c/lib/reporter.js#L221
20+
21+
const setTimeoutPromise = promisify(setTimeout);
22+
1223
describe('Karma Builder code coverage', () => {
1324
const coverageFilePath = normalize('coverage/lcov.info');
1425
let architect: Architect;
@@ -27,12 +38,14 @@ describe('Karma Builder code coverage', () => {
2738

2839
await run.stop();
2940

41+
await setTimeoutPromise(1000);
42+
3043
const exists = host.scopedSync().exists(coverageFilePath);
31-
expect(exists).toBe(true);
44+
expect(exists).toBe(true, `${coverageFilePath} does not exist`);
3245

3346
if (exists) {
3447
const content = virtualFs.fileBufferToString(host.scopedSync().read(coverageFilePath));
35-
expect(content).toContain('polyfills.ts');
48+
expect(content).toContain('app.component.ts');
3649
expect(content).toContain('test.ts');
3750
}
3851
}, 120000);
@@ -41,7 +54,6 @@ describe('Karma Builder code coverage', () => {
4154
const overrides = {
4255
codeCoverage: true,
4356
codeCoverageExclude: [
44-
'src/polyfills.ts',
4557
'**/test.ts',
4658
],
4759
};
@@ -52,12 +64,13 @@ describe('Karma Builder code coverage', () => {
5264

5365
await run.stop();
5466

67+
await setTimeoutPromise(1000);
68+
5569
const exists = host.scopedSync().exists(coverageFilePath);
5670
expect(exists).toBe(true);
5771

5872
if (exists) {
5973
const content = virtualFs.fileBufferToString(host.scopedSync().read(coverageFilePath));
60-
expect(content).not.toContain('polyfills.ts');
6174
expect(content).not.toContain('test.ts');
6275
}
6376
}, 120000);
@@ -102,6 +115,8 @@ describe('Karma Builder code coverage', () => {
102115

103116
await run.stop();
104117

118+
await setTimeoutPromise(1000);
119+
105120
const exists = host.scopedSync().exists(coverageFilePath);
106121
expect(exists).toBe(true);
107122

@@ -112,19 +127,17 @@ describe('Karma Builder code coverage', () => {
112127
}, 120000);
113128

114129
it(`should fail when coverage is below threhold and 'emitWarning' is false`, async () => {
115-
host.replaceInFile('karma.conf.js', 'fixWebpackSourcePaths: true',
116-
`
117-
fixWebpackSourcePaths: true,
118-
thresholds: {
119-
emitWarning: false,
120-
global: {
121-
statements: 100,
122-
lines: 100,
123-
branches: 100,
124-
functions: 100
130+
host.replaceInFile('karma.conf.js', 'coverageReporter: {', `
131+
coverageReporter: {
132+
check: {
133+
global: {
134+
statements: 100,
135+
lines: 100,
136+
branches: 100,
137+
functions: 100
138+
}
125139
},
126-
}`,
127-
);
140+
`);
128141

129142
host.appendToFile('src/app/app.component.ts', `
130143
export function nonCovered(): boolean {
@@ -133,7 +146,13 @@ describe('Karma Builder code coverage', () => {
133146
`);
134147

135148
const run = await architect.scheduleTarget(karmaTargetSpec, { codeCoverage: true });
136-
await expectAsync(run.result).toBeResolvedTo(jasmine.objectContaining({ success: false }));
137149
await run.stop();
150+
151+
const result = await run.result;
152+
// success is true because all tests passed
153+
expect(result.success).toBeTrue();
154+
const karmaResults: TestResults = result.karmaResults as never;
155+
// exitCode is non-zero because coverage failed
156+
expect(karmaResults.exitCode).toBe(1);
138157
}, 120000);
139158
});

packages/angular_devkit/build_angular/src/karma/index.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
9-
import { getSystemPath, join, normalize } from '@angular-devkit/core';
9+
import { JsonObject, getSystemPath, join, normalize } from '@angular-devkit/core';
1010
import { dirname, resolve } from 'path';
1111
import { Observable, from } from 'rxjs';
1212
import { defaultIfEmpty, switchMap } from 'rxjs/operators';
@@ -143,8 +143,14 @@ export function execute(
143143
options,
144144
webpackConfig,
145145
// Pass onto Karma to emit BuildEvents.
146-
successCb: () => subscriber.next({ success: true }),
147-
failureCb: () => subscriber.next({ success: false }),
146+
successCb: (karmaResults: JsonObject) => subscriber.next({
147+
success: true,
148+
karmaResults,
149+
}),
150+
failureCb: (karmaResults: JsonObject) => subscriber.next({
151+
success: false,
152+
karmaResults,
153+
}),
148154
// Workaround for https://github.com/karma-runner/karma/issues/3154
149155
// When this workaround is removed, user projects need to be updated to use a Karma
150156
// version that has a fix for this issue.

packages/angular_devkit/build_angular/test/hello-world-app/karma.conf.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,19 @@ module.exports = function(config) {
1919
require('karma-jasmine'),
2020
require('karma-chrome-launcher'),
2121
require('karma-jasmine-html-reporter'),
22-
require('karma-coverage-istanbul-reporter'),
22+
require('karma-coverage'),
2323
require('@angular-devkit/build-angular/plugins/karma'),
2424
],
2525
client: {
2626
clearContext: false, // leave Jasmine Spec Runner output visible in browser
2727
},
28-
coverageIstanbulReporter: {
29-
dir: path.join(__dirname, 'coverage'),
30-
reports: ['html', 'lcovonly'],
31-
fixWebpackSourcePaths: true,
28+
coverageReporter: {
29+
dir: path.join(__dirname, './coverage'),
30+
subdir: '.',
31+
reporters: [
32+
{type: 'html'},
33+
{type: 'lcov'},
34+
],
3235
},
3336
reporters: ['progress', 'kjhtml'],
3437
port: 9876,

packages/angular_devkit/build_ng_packagr/test/ng-packaged/projects/lib/karma.conf.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,19 @@ module.exports = function (config) {
1616
require('karma-jasmine'),
1717
require('karma-chrome-launcher'),
1818
require('karma-jasmine-html-reporter'),
19-
require('karma-coverage-istanbul-reporter'),
19+
require('karma-coverage'),
2020
require('@angular-devkit/build-angular/plugins/karma')
2121
],
2222
client: {
2323
clearContext: false // leave Jasmine Spec Runner output visible in browser
2424
},
25-
coverageIstanbulReporter: {
25+
coverageReporter: {
2626
dir: require('path').join(__dirname, 'coverage'),
27-
reports: ['html', 'lcovonly'],
28-
fixWebpackSourcePaths: true
27+
subdir: '.',
28+
reporters: [
29+
{type: 'html'},
30+
{type: 'lcov'},
31+
],
2932
},
3033
reporters: ['progress', 'kjhtml'],
3134
port: 9876,

packages/schematics/angular/application/files/karma.conf.js.template

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,20 @@ module.exports = function (config) {
99
require('karma-jasmine'),
1010
require('karma-chrome-launcher'),
1111
require('karma-jasmine-html-reporter'),
12-
require('karma-coverage-istanbul-reporter'),
12+
require('karma-coverage'),
1313
require('@angular-devkit/build-angular/plugins/karma')
1414
],
1515
client: {
1616
clearContext: false // leave Jasmine Spec Runner output visible in browser
1717
},
18-
coverageIstanbulReporter: {
18+
coverageReporter: {
1919
dir: require('path').join(__dirname, '<%= relativePathToWorkspaceRoot %>/coverage/<%= appName%>'),
20-
reports: ['html', 'lcovonly', 'text-summary'],
21-
fixWebpackSourcePaths: true
20+
subdir: '.',
21+
reporters: [
22+
{type: 'html'},
23+
{type: 'lcov'},
24+
{type: 'text-summary'},
25+
],
2226
},
2327
reporters: ['progress', 'kjhtml'],
2428
port: 9876,

packages/schematics/angular/library/files/karma.conf.js.template

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,20 @@ module.exports = function (config) {
99
require('karma-jasmine'),
1010
require('karma-chrome-launcher'),
1111
require('karma-jasmine-html-reporter'),
12-
require('karma-coverage-istanbul-reporter'),
12+
require('karma-coverage'),
1313
require('@angular-devkit/build-angular/plugins/karma')
1414
],
1515
client: {
1616
clearContext: false // leave Jasmine Spec Runner output visible in browser
1717
},
18-
coverageIstanbulReporter: {
18+
coverageReporter: {
1919
dir: require('path').join(__dirname, '<%= relativePathToWorkspaceRoot %>/coverage/<%= folderName %>'),
20-
reports: ['html', 'lcovonly', 'text-summary'],
21-
fixWebpackSourcePaths: true
20+
subdir: '.',
21+
reporters: [
22+
{type: 'html'},
23+
{type: 'lcov'},
24+
{type: 'text-summary'},
25+
],
2226
},
2327
reporters: ['progress', 'kjhtml'],
2428
port: 9876,

packages/schematics/angular/workspace/files/package.json.template

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"jasmine-spec-reporter": "~5.0.0",
3535
"karma": "~5.0.0",
3636
"karma-chrome-launcher": "~3.1.0",
37-
"karma-coverage-istanbul-reporter": "~3.0.2",
37+
"karma-coverage": "~2.0.2",
3838
"karma-jasmine": "~3.3.0",
3939
"karma-jasmine-html-reporter": "^1.5.0",
4040
"protractor": "~7.0.0",<% } %>

0 commit comments

Comments
 (0)