11import { existsSync , promises as fs } from 'fs'
22import _url from 'url'
33import type { Profiler } from 'inspector'
4- import { takeCoverage } from 'v8'
54import { extname , resolve } from 'pathe'
65import c from 'picocolors'
76import { provider } from 'std-env'
87import type { RawSourceMap } from 'vite-node'
98import { coverageConfigDefaults } from 'vitest/config'
109// eslint-disable-next-line no-restricted-imports
11- import type { CoverageC8Options , CoverageProvider , ReportContext , ResolvedCoverageOptions } from 'vitest'
10+ import type { AfterSuiteRunMeta , CoverageC8Options , CoverageProvider , ReportContext , ResolvedCoverageOptions } from 'vitest'
1211import type { Vitest } from 'vitest/node'
1312import type { Report } from 'c8'
1413// @ts -expect-error missing types
1514import createReport from 'c8/lib/report.js'
1615// @ts -expect-error missing types
1716import { checkCoverages } from 'c8/lib/commands/check-coverage.js'
1817
19- type Options =
20- & ResolvedCoverageOptions < 'c8' >
21- & { tempDirectory : string }
18+ type Options = ResolvedCoverageOptions < 'c8' >
2219
2320export class C8CoverageProvider implements CoverageProvider {
2421 name = 'c8'
2522
2623 ctx ! : Vitest
2724 options ! : Options
25+ coverages : Profiler . TakePreciseCoverageReturnType [ ] = [ ]
2826
2927 initialize ( ctx : Vitest ) {
3028 this . ctx = ctx
@@ -35,25 +33,18 @@ export class C8CoverageProvider implements CoverageProvider {
3533 return this . options
3634 }
3735
38- onBeforeFilesRun ( ) {
39- process . env . NODE_V8_COVERAGE ||= this . options . tempDirectory
40- }
41-
4236 async clean ( clean = true ) {
4337 if ( clean && existsSync ( this . options . reportsDirectory ) )
4438 await fs . rm ( this . options . reportsDirectory , { recursive : true , force : true , maxRetries : 10 } )
4539
46- if ( ! existsSync ( this . options . tempDirectory ) )
47- await fs . mkdir ( this . options . tempDirectory , { recursive : true } )
40+ this . coverages = [ ]
4841 }
4942
50- onAfterSuiteRun ( ) {
51- takeCoverage ( )
43+ onAfterSuiteRun ( { coverage } : AfterSuiteRunMeta ) {
44+ this . coverages . push ( coverage as Profiler . TakePreciseCoverageReturnType )
5245 }
5346
5447 async reportCoverage ( { allTestsRun } : ReportContext = { } ) {
55- takeCoverage ( )
56-
5748 if ( provider === 'stackblitz' )
5849 this . ctx . logger . log ( c . blue ( ' % ' ) + c . yellow ( '@vitest/coverage-c8 does not work on Stackblitz. Report will be empty.' ) )
5950
@@ -64,6 +55,9 @@ export class C8CoverageProvider implements CoverageProvider {
6455
6556 const report = createReport ( options )
6657
58+ // Overwrite C8's loader as results are in memory instead of file system
59+ report . _loadReports = ( ) => this . coverages
60+
6761 interface MapAndSource { map : RawSourceMap ; source : string | undefined }
6862 type SourceMapMeta = { url : string ; filepath : string } & MapAndSource
6963
@@ -73,7 +67,7 @@ export class C8CoverageProvider implements CoverageProvider {
7367
7468 const entries = Array
7569 . from ( this . ctx . vitenode . fetchCache . entries ( ) )
76- . filter ( i => ! i [ 0 ] . includes ( '/node_modules/' ) )
70+ . filter ( entry => report . _shouldInstrument ( entry [ 0 ] ) )
7771 . map ( ( [ file , { result } ] ) => {
7872 if ( ! result . map )
7973 return null
@@ -153,12 +147,6 @@ export class C8CoverageProvider implements CoverageProvider {
153147
154148 await report . run ( )
155149 await checkCoverages ( options , report )
156-
157- // Note that this will only clean up the V8 reports generated so far.
158- // There will still be a temp directory with some reports when vitest exists,
159- // but at least it will only contain reports of vitest's internal functions.
160- if ( existsSync ( this . options . tempDirectory ) )
161- await fs . rm ( this . options . tempDirectory , { recursive : true , force : true , maxRetries : 10 } )
162150 }
163151}
164152
@@ -178,7 +166,6 @@ function resolveC8Options(options: CoverageC8Options, root: string): Options {
178166
179167 // Resolved fields
180168 provider : 'c8' ,
181- tempDirectory : process . env . NODE_V8_COVERAGE || resolve ( reportsDirectory , 'tmp' ) ,
182169 reporter : Array . isArray ( reporter ) ? reporter : [ reporter ] ,
183170 reportsDirectory,
184171 }
0 commit comments