@@ -193,6 +193,18 @@ export class V8CoverageProvider extends BaseCoverageProvider implements Coverage
193
193
coverageMap . merge ( await transformCoverage ( converted ) )
194
194
}
195
195
196
+ await this . generateReports ( coverageMap , allTestsRun )
197
+
198
+ // In watch mode we need to preserve the previous results if cleanOnRerun is disabled
199
+ const keepResults = ! this . options . cleanOnRerun && this . ctx . config . watch
200
+
201
+ if ( ! keepResults ) {
202
+ this . coverageFiles = new Map ( )
203
+ await fs . rm ( this . coverageFilesDirectory , { recursive : true } )
204
+ }
205
+ }
206
+
207
+ async generateReports ( coverageMap : CoverageMap , allTestsRun : boolean | undefined ) {
196
208
const context = libReport . createContext ( {
197
209
dir : this . options . reportsDirectory ,
198
210
coverageMap,
@@ -203,6 +215,11 @@ export class V8CoverageProvider extends BaseCoverageProvider implements Coverage
203
215
this . ctx . logger . log ( c . blue ( ' % ' ) + c . dim ( 'Coverage report from ' ) + c . yellow ( this . name ) )
204
216
205
217
for ( const reporter of this . options . reporter ) {
218
+ if ( reporter [ 0 ] === 'blob' ) {
219
+ await this . createBlobReport ( coverageMap , reporter [ 1 ] )
220
+ continue
221
+ }
222
+
206
223
// Type assertion required for custom reporters
207
224
reports . create ( reporter [ 0 ] as Parameters < typeof reports . create > [ 0 ] , {
208
225
skipFull : this . options . skipFull ,
@@ -239,14 +256,36 @@ export class V8CoverageProvider extends BaseCoverageProvider implements Coverage
239
256
} )
240
257
}
241
258
}
259
+ }
260
+
261
+ async mergeReports ( path : string ) {
262
+ const directory = resolve ( path , 'coverage' )
263
+ const files = await fs . readdir ( directory )
264
+ const coverageMap = libCoverage . createCoverageMap ( { } )
265
+
266
+ for ( const file of files ) {
267
+ const report = await fs . readFile ( resolve ( directory , file ) , 'utf8' )
268
+ coverageMap . merge ( JSON . parse ( report ) )
269
+ }
242
270
243
- // In watch mode we need to preserve the previous results if cleanOnRerun is disabled
244
- const keepResults = ! this . options . cleanOnRerun && this . ctx . config . watch
271
+ await this . generateReports ( coverageMap , true )
272
+ }
245
273
246
- if ( ! keepResults ) {
247
- this . coverageFiles = new Map ( )
248
- await fs . rm ( this . coverageFilesDirectory , { recursive : true } )
274
+ async createBlobReport ( coverageMap : CoverageMap , options : Options [ 'reporter' ] [ number ] [ 1 ] ) {
275
+ const dir = this . ctx . config . coverage . reportsDirectory || '.vitest-reports/coverage/'
276
+ let file = 'file' in options && options . file as string
277
+
278
+ if ( ! file ) {
279
+ const shard = this . ctx . config . shard
280
+ file = shard
281
+ ? `.coverage-blob-${ shard . index } -${ shard . count } .json`
282
+ : '.coverage-blob.json'
249
283
}
284
+
285
+ const context = libReport . createContext ( { dir, coverageMap } )
286
+ reports . create ( 'json' , { file } ) . execute ( context )
287
+
288
+ this . ctx . logger . log ( `coverage blob report written to ${ resolve ( dir , file ) } ` )
250
289
}
251
290
252
291
private async getUntestedFiles ( testedFiles : string [ ] ) : Promise < RawCoverage > {
0 commit comments