@@ -53,15 +53,31 @@ interface TestExclude {
5353
5454type Options = ResolvedCoverageOptions < 'v8' >
5555type TransformResults = Map < string , FetchResult >
56- type Filename = string
5756type RawCoverage = Profiler . TakePreciseCoverageReturnType
58- type CoverageFilesByTransformMode = Record <
59- AfterSuiteRunMeta [ 'transformMode' ] ,
60- Filename [ ]
57+
58+ /**
59+ * Holds info about raw coverage results that are stored on file system:
60+ *
61+ * ```json
62+ * "project-a": {
63+ * "web": {
64+ * "tests/math.test.ts": "coverage-1.json",
65+ * "tests/utils.test.ts": "coverage-2.json",
66+ * // ^^^^^^^^^^^^^^^ Raw coverage on file system
67+ * },
68+ * "ssr": { ... },
69+ * "browser": { ... },
70+ * },
71+ * "project-b": ...
72+ * ```
73+ */
74+ type CoverageFiles = Map <
75+ NonNullable < AfterSuiteRunMeta [ 'projectName' ] > | typeof DEFAULT_PROJECT ,
76+ Record <
77+ AfterSuiteRunMeta [ 'transformMode' ] ,
78+ { [ TestFilenames : string ] : string }
79+ >
6180>
62- type ProjectName =
63- | NonNullable < AfterSuiteRunMeta [ 'projectName' ] >
64- | typeof DEFAULT_PROJECT
6581
6682type Entries < T > = [ keyof T , T [ keyof T ] ] [ ]
6783
@@ -86,7 +102,7 @@ export class V8CoverageProvider extends BaseCoverageProvider implements Coverage
86102 options ! : Options
87103 testExclude ! : InstanceType < TestExclude >
88104
89- coverageFiles : Map < ProjectName , CoverageFilesByTransformMode > = new Map ( )
105+ coverageFiles : CoverageFiles = new Map ( )
90106 coverageFilesDirectory ! : string
91107 pendingPromises : Promise < void > [ ] = [ ]
92108
@@ -181,23 +197,26 @@ export class V8CoverageProvider extends BaseCoverageProvider implements Coverage
181197 * Note that adding new entries here and requiring on those without
182198 * backwards compatibility is a breaking change.
183199 */
184- onAfterSuiteRun ( { coverage, transformMode, projectName } : AfterSuiteRunMeta ) : void {
200+ onAfterSuiteRun ( { coverage, transformMode, projectName, testFiles } : AfterSuiteRunMeta ) : void {
185201 if ( transformMode !== 'web' && transformMode !== 'ssr' && transformMode !== 'browser' ) {
186202 throw new Error ( `Invalid transform mode: ${ transformMode } ` )
187203 }
188204
189205 let entry = this . coverageFiles . get ( projectName || DEFAULT_PROJECT )
190206
191207 if ( ! entry ) {
192- entry = { web : [ ] , ssr : [ ] , browser : [ ] }
208+ entry = { web : { } , ssr : { } , browser : { } }
193209 this . coverageFiles . set ( projectName || DEFAULT_PROJECT , entry )
194210 }
195211
212+ const testFilenames = testFiles . join ( )
196213 const filename = resolve (
197214 this . coverageFilesDirectory ,
198215 `coverage-${ uniqueId ++ } .json` ,
199216 )
200- entry [ transformMode ] . push ( filename )
217+
218+ // If there's a result from previous run, overwrite it
219+ entry [ transformMode ] [ testFilenames ] = filename
201220
202221 const promise = fs . writeFile ( filename , JSON . stringify ( coverage ) , 'utf-8' )
203222 this . pendingPromises . push ( promise )
@@ -212,9 +231,10 @@ export class V8CoverageProvider extends BaseCoverageProvider implements Coverage
212231 this . pendingPromises = [ ]
213232
214233 for ( const [ projectName , coveragePerProject ] of this . coverageFiles . entries ( ) ) {
215- for ( const [ transformMode , filenames ] of Object . entries ( coveragePerProject ) as Entries < CoverageFilesByTransformMode > ) {
234+ for ( const [ transformMode , coverageByTestfiles ] of Object . entries ( coveragePerProject ) as Entries < typeof coveragePerProject > ) {
216235 let merged : RawCoverage = { result : [ ] }
217236
237+ const filenames = Object . values ( coverageByTestfiles )
218238 const project = this . ctx . projects . find ( p => p . getName ( ) === projectName ) || this . ctx . getCoreWorkspaceProject ( )
219239
220240 for ( const chunk of this . toSlices ( filenames , this . options . processingConcurrency ) ) {
@@ -245,7 +265,9 @@ export class V8CoverageProvider extends BaseCoverageProvider implements Coverage
245265 }
246266 }
247267
248- if ( this . options . all && allTestsRun ) {
268+ // Include untested files when all tests were run (not a single file re-run)
269+ // or if previous results are preserved by "cleanOnRerun: false"
270+ if ( this . options . all && ( allTestsRun || ! this . options . cleanOnRerun ) ) {
249271 const coveredFiles = coverageMap . files ( )
250272 const untestedCoverage = await this . getUntestedFiles ( coveredFiles )
251273
@@ -519,7 +541,7 @@ export class V8CoverageProvider extends BaseCoverageProvider implements Coverage
519541 private async convertCoverage (
520542 coverage : RawCoverage ,
521543 project : WorkspaceProject = this . ctx . getCoreWorkspaceProject ( ) ,
522- transformMode ?: keyof CoverageFilesByTransformMode ,
544+ transformMode ?: AfterSuiteRunMeta [ 'transformMode' ] ,
523545 ) : Promise < CoverageMap > {
524546 let fetchCache = project . vitenode . fetchCache
525547
0 commit comments