diff --git a/packages/angular/build/src/builders/unit-test/builder.ts b/packages/angular/build/src/builders/unit-test/builder.ts index 84b41f1a280a..15ac0294a2fc 100644 --- a/packages/angular/build/src/builders/unit-test/builder.ts +++ b/packages/angular/build/src/builders/unit-test/builder.ts @@ -237,7 +237,8 @@ export async function* execute( browser, reporters: normalizedOptions.reporters ?? ['default'], coverage: { - enabled: normalizedOptions.codeCoverage, + enabled: !!normalizedOptions.codeCoverage, + reporter: normalizedOptions.codeCoverage?.reporters, excludeAfterRemap: true, }, ...debugOptions, @@ -251,7 +252,7 @@ export async function* execute( // builder's test setup. To workaround this, the excludes are adjusted here to only automatically // exclude the TypeScript source test files. context.project.config.coverage.exclude = [ - ...(normalizedOptions.codeCoverageExclude ?? []), + ...(normalizedOptions.codeCoverage?.exclude ?? []), '**/*.{test,spec}.?(c|m)ts', ]; }, diff --git a/packages/angular/build/src/builders/unit-test/karma-bridge.ts b/packages/angular/build/src/builders/unit-test/karma-bridge.ts index 6bc57de36e3e..3232739829fb 100644 --- a/packages/angular/build/src/builders/unit-test/karma-bridge.ts +++ b/packages/angular/build/src/builders/unit-test/karma-bridge.ts @@ -45,8 +45,8 @@ export async function useKarmaBuilder( poll: buildTargetOptions.poll, preserveSymlinks: buildTargetOptions.preserveSymlinks, browsers: unitTestOptions.browsers?.join(','), - codeCoverage: unitTestOptions.codeCoverage, - codeCoverageExclude: unitTestOptions.codeCoverageExclude, + codeCoverage: !!unitTestOptions.codeCoverage, + codeCoverageExclude: unitTestOptions.codeCoverage?.exclude, fileReplacements: buildTargetOptions.fileReplacements, reporters: unitTestOptions.reporters, webWorkerTsConfig: buildTargetOptions.webWorkerTsConfig, diff --git a/packages/angular/build/src/builders/unit-test/options.ts b/packages/angular/build/src/builders/unit-test/options.ts index 7f1413051f91..69dc0114963b 100644 --- a/packages/angular/build/src/builders/unit-test/options.ts +++ b/packages/angular/build/src/builders/unit-test/options.ts @@ -33,7 +33,7 @@ export async function normalizeOptions( const buildTargetSpecifier = options.buildTarget ?? `::development`; const buildTarget = targetFromTargetString(buildTargetSpecifier, projectName, 'build'); - const { codeCoverage, codeCoverageExclude, tsConfig, runner, reporters, browsers } = options; + const { tsConfig, runner, reporters, browsers } = options; return { // Project/workspace information @@ -46,8 +46,16 @@ export async function normalizeOptions( include: options.include ?? ['**/*.spec.ts'], exclude: options.exclude ?? [], runnerName: runner, - codeCoverage, - codeCoverageExclude, + codeCoverage: options.codeCoverage + ? { + exclude: options.codeCoverageExclude, + reporters: options.codeCoverageReporters?.map((entry) => + typeof entry === 'string' + ? ([entry, {}] as [string, Record]) + : (entry as [string, Record]), + ), + } + : undefined, tsConfig, reporters, browsers, diff --git a/packages/angular/build/src/builders/unit-test/schema.json b/packages/angular/build/src/builders/unit-test/schema.json index 764a751a0e95..310600332fa2 100644 --- a/packages/angular/build/src/builders/unit-test/schema.json +++ b/packages/angular/build/src/builders/unit-test/schema.json @@ -64,6 +64,23 @@ }, "default": [] }, + "codeCoverageReporters": { + "type": "array", + "description": "Reporters to use for code coverage results.", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/coverage-reporters" + }, + { + "type": "array", + "minItems": 1, + "maxItems": 2, + "items": [{ "$ref": "#/definitions/coverage-reporters" }, { "type": "object" }] + } + ] + } + }, "reporters": { "type": "array", "description": "Test runner reporters to use. Directly passed to the test runner.", @@ -78,5 +95,10 @@ } }, "additionalProperties": false, - "required": ["buildTarget", "tsConfig", "runner"] + "required": ["buildTarget", "tsConfig", "runner"], + "definitions": { + "coverage-reporters": { + "enum": ["html", "lcov", "lcovonly", "text", "text-summary", "cobertura"] + } + } }