1
1
import { existsSync , promises as fs } from 'fs'
2
2
import _url from 'url'
3
3
import type { Profiler } from 'inspector'
4
- import { takeCoverage } from 'v8'
5
4
import { extname , resolve } from 'pathe'
6
5
import c from 'picocolors'
7
6
import { provider } from 'std-env'
8
7
import type { RawSourceMap } from 'vite-node'
9
8
import { coverageConfigDefaults } from 'vitest/config'
10
9
// 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'
12
11
import type { Vitest } from 'vitest/node'
13
12
import type { Report } from 'c8'
14
13
// @ts -expect-error missing types
15
14
import createReport from 'c8/lib/report.js'
16
15
// @ts -expect-error missing types
17
16
import { checkCoverages } from 'c8/lib/commands/check-coverage.js'
18
17
19
- type Options =
20
- & ResolvedCoverageOptions < 'c8' >
21
- & { tempDirectory : string }
18
+ type Options = ResolvedCoverageOptions < 'c8' >
22
19
23
20
export class C8CoverageProvider implements CoverageProvider {
24
21
name = 'c8'
25
22
26
23
ctx ! : Vitest
27
24
options ! : Options
25
+ coverages : Profiler . TakePreciseCoverageReturnType [ ] = [ ]
28
26
29
27
initialize ( ctx : Vitest ) {
30
28
this . ctx = ctx
@@ -35,25 +33,18 @@ export class C8CoverageProvider implements CoverageProvider {
35
33
return this . options
36
34
}
37
35
38
- onBeforeFilesRun ( ) {
39
- process . env . NODE_V8_COVERAGE ||= this . options . tempDirectory
40
- }
41
-
42
36
async clean ( clean = true ) {
43
37
if ( clean && existsSync ( this . options . reportsDirectory ) )
44
38
await fs . rm ( this . options . reportsDirectory , { recursive : true , force : true , maxRetries : 10 } )
45
39
46
- if ( ! existsSync ( this . options . tempDirectory ) )
47
- await fs . mkdir ( this . options . tempDirectory , { recursive : true } )
40
+ this . coverages = [ ]
48
41
}
49
42
50
- onAfterSuiteRun ( ) {
51
- takeCoverage ( )
43
+ onAfterSuiteRun ( { coverage } : AfterSuiteRunMeta ) {
44
+ this . coverages . push ( coverage as Profiler . TakePreciseCoverageReturnType )
52
45
}
53
46
54
47
async reportCoverage ( { allTestsRun } : ReportContext = { } ) {
55
- takeCoverage ( )
56
-
57
48
if ( provider === 'stackblitz' )
58
49
this . ctx . logger . log ( c . blue ( ' % ' ) + c . yellow ( '@vitest/coverage-c8 does not work on Stackblitz. Report will be empty.' ) )
59
50
@@ -64,6 +55,9 @@ export class C8CoverageProvider implements CoverageProvider {
64
55
65
56
const report = createReport ( options )
66
57
58
+ // Overwrite C8's loader as results are in memory instead of file system
59
+ report . _loadReports = ( ) => this . coverages
60
+
67
61
interface MapAndSource { map : RawSourceMap ; source : string | undefined }
68
62
type SourceMapMeta = { url : string ; filepath : string } & MapAndSource
69
63
@@ -73,7 +67,7 @@ export class C8CoverageProvider implements CoverageProvider {
73
67
74
68
const entries = Array
75
69
. from ( this . ctx . vitenode . fetchCache . entries ( ) )
76
- . filter ( i => ! i [ 0 ] . includes ( '/node_modules/' ) )
70
+ . filter ( entry => report . _shouldInstrument ( entry [ 0 ] ) )
77
71
. map ( ( [ file , { result } ] ) => {
78
72
if ( ! result . map )
79
73
return null
@@ -153,12 +147,6 @@ export class C8CoverageProvider implements CoverageProvider {
153
147
154
148
await report . run ( )
155
149
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 } )
162
150
}
163
151
}
164
152
@@ -178,7 +166,6 @@ function resolveC8Options(options: CoverageC8Options, root: string): Options {
178
166
179
167
// Resolved fields
180
168
provider : 'c8' ,
181
- tempDirectory : process . env . NODE_V8_COVERAGE || resolve ( reportsDirectory , 'tmp' ) ,
182
169
reporter : Array . isArray ( reporter ) ? reporter : [ reporter ] ,
183
170
reportsDirectory,
184
171
}
0 commit comments