@@ -24,11 +24,13 @@ import { OutputHashing } from '../application/schema';
2424import { writeTestFiles } from '../karma/application_builder' ;
2525import { findTests , getTestEntrypoints } from '../karma/find-tests' ;
2626import { useKarmaBuilder } from './karma-bridge' ;
27- import { normalizeOptions } from './options' ;
27+ import { NormalizedUnitTestOptions , normalizeOptions } from './options' ;
2828import type { Schema as UnitTestOptions } from './schema' ;
2929
3030export type { UnitTestOptions } ;
3131
32+ type VitestCoverageOption = Exclude < import ( 'vitest/node' ) . InlineConfig [ 'coverage' ] , undefined > ;
33+
3234/**
3335 * @experimental Direct usage of this function is considered experimental.
3436 */
@@ -230,15 +232,11 @@ export async function* execute(
230232 include : [ ] ,
231233 reporters : normalizedOptions . reporters ?? [ 'default' ] ,
232234 watch : normalizedOptions . watch ,
233- coverage : {
234- enabled : ! ! normalizedOptions . codeCoverage ,
235- excludeAfterRemap : true ,
236- exclude : normalizedOptions . codeCoverage ?. exclude ?? [ ] ,
237- // Special handling for `reporter` due to an undefined value causing upstream failures
238- ...( normalizedOptions . codeCoverage ?. reporters
239- ? { reporter : normalizedOptions . codeCoverage . reporters }
240- : { } ) ,
241- } ,
235+ coverage : generateCoverageOption (
236+ normalizedOptions . codeCoverage ,
237+ workspaceRoot ,
238+ outputPath ,
239+ ) ,
242240 ...debugOptions ,
243241 } ,
244242 {
@@ -249,7 +247,7 @@ export async function* execute(
249247 // Create a subproject that can be configured with plugins for browser mode.
250248 // Plugins defined directly in the vite overrides will not be present in the
251249 // browser specific Vite instance.
252- await context . injectTestProjects ( {
250+ const [ project ] = await context . injectTestProjects ( {
253251 test : {
254252 name : projectName ,
255253 root : outputPath ,
@@ -282,6 +280,15 @@ export async function* execute(
282280 } ,
283281 ] ,
284282 } ) ;
283+
284+ // Adjust coverage excludes to not include the otherwise automatically inserted included unit tests.
285+ // Vite does this as a convenience but is problematic for the bundling strategy employed by the
286+ // builder's test setup. To workaround this, the excludes are adjusted here to only automaticallyAdd commentMore actions
287+ // exclude the TypeScript source test files.
288+ project . config . coverage . exclude = [
289+ ...( normalizedOptions . codeCoverage ?. exclude ?? [ ] ) ,
290+ '**/*.{test,spec}.?(c|m)ts' ,
291+ ] ;
285292 } ,
286293 } ,
287294 ] ,
@@ -377,3 +384,24 @@ function generateOutputPath(): string {
377384
378385 return path . join ( 'dist' , 'test-out' , `${ datePrefix } -${ uuidSuffix } ` ) ;
379386}
387+ function generateCoverageOption (
388+ codeCoverage : NormalizedUnitTestOptions [ 'codeCoverage' ] ,
389+ workspaceRoot : string ,
390+ outputPath : string ,
391+ ) : VitestCoverageOption {
392+ if ( ! codeCoverage ) {
393+ return {
394+ enabled : false ,
395+ } ;
396+ }
397+
398+ return {
399+ enabled : true ,
400+ excludeAfterRemap : true ,
401+ include : [ `${ path . relative ( workspaceRoot , outputPath ) } /**` ] ,
402+ // Special handling for `reporter` due to an undefined value causing upstream failures
403+ ...( codeCoverage . reporters
404+ ? ( { reporter : codeCoverage . reporters } satisfies VitestCoverageOption )
405+ : { } ) ,
406+ } ;
407+ }
0 commit comments