Skip to content

Commit 1b47d83

Browse files
MeAkibalan-agius4
authored andcommitted
fix(@angular/build): only require karma-coverage when coverage is enabled
The upfront dependency validation of the unit-test builder's karma runner checks the truthiness of the normalized `coverage` option, which is always an object since the introduction of the advanced coverage options. As a result, `ng test` with the karma runner fails with a `MissingDependenciesError` requesting the `karma-coverage` package even when coverage is disabled. Check the `enabled` property instead, matching the vitest runner and the karma executor. A new unit spec for the karma runner's dependency validation fails without this change.
1 parent a68d0df commit 1b47d83

2 files changed

Lines changed: 57 additions & 1 deletion

File tree

‎packages/angular/build/src/builders/unit-test/runners/karma/index.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const KarmaTestRunner: TestRunner = {
3030
}
3131
}
3232

33-
if (options.coverage) {
33+
if (options.coverage.enabled) {
3434
checker.check('karma-coverage');
3535
}
3636

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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 assert from 'node:assert';
10+
import { mkdir, mkdtemp, writeFile } from 'node:fs/promises';
11+
import { join } from 'node:path';
12+
import type { NormalizedUnitTestBuilderOptions } from '../../options';
13+
import KarmaTestRunner from './index';
14+
15+
describe('KarmaTestRunner', () => {
16+
describe('validateDependencies', () => {
17+
let projectSourceRoot: string;
18+
19+
function createOptions(coverageEnabled: boolean): NormalizedUnitTestBuilderOptions {
20+
return {
21+
projectSourceRoot,
22+
coverage: { enabled: coverageEnabled },
23+
} as NormalizedUnitTestBuilderOptions;
24+
}
25+
26+
beforeAll(async () => {
27+
const baseTmpDir = process.env['TEST_TMPDIR'];
28+
assert(baseTmpDir, 'TEST_TMPDIR is not set');
29+
projectSourceRoot = await mkdtemp(join(baseTmpDir, 'angular-cli-karma-runner-'));
30+
31+
// A project with karma and karma-jasmine installed but not karma-coverage
32+
await writeFile(join(projectSourceRoot, 'package.json'), '{"name": "test-project"}');
33+
for (const packageName of ['karma', 'karma-jasmine']) {
34+
const packageRoot = join(projectSourceRoot, 'node_modules', packageName);
35+
await mkdir(packageRoot, { recursive: true });
36+
await writeFile(
37+
join(packageRoot, 'package.json'),
38+
JSON.stringify({ name: packageName, version: '0.0.0', main: 'index.js' }),
39+
);
40+
await writeFile(join(packageRoot, 'index.js'), '');
41+
}
42+
});
43+
44+
it('does not require karma-coverage when coverage is disabled', async () => {
45+
await expectAsync(
46+
Promise.resolve().then(() => KarmaTestRunner.validateDependencies?.(createOptions(false))),
47+
).toBeResolved();
48+
});
49+
50+
it('requires karma-coverage when coverage is enabled', async () => {
51+
await expectAsync(
52+
Promise.resolve().then(() => KarmaTestRunner.validateDependencies?.(createOptions(true))),
53+
).toBeRejectedWithError(/karma-coverage/);
54+
});
55+
});
56+
});

0 commit comments

Comments
 (0)