@@ -25,11 +25,12 @@ import { cleanUrl } from 'vite-node/utils'
2525import { BaseCoverageProvider } from 'vitest/coverage'
2626import { version } from '../package.json' with { type : 'json' }
2727
28- type TransformResults = Map < string , FetchResult >
29- type RawCoverage = Profiler . TakePreciseCoverageReturnType
28+ export interface ScriptCoverageWithOffset extends Profiler . ScriptCoverage {
29+ startOffset : number
30+ }
3031
31- // TODO: vite-node should export this
32- const WRAPPER_LENGTH = 185
32+ type TransformResults = Map < string , FetchResult >
33+ interface RawCoverage { result : ScriptCoverageWithOffset [ ] }
3334
3435// Note that this needs to match the line ending as well
3536const VITE_EXPORTS_LINE_PATTERN
@@ -69,6 +70,14 @@ export class V8CoverageProvider extends BaseCoverageProvider<ResolvedCoverageOpt
6970 await this . readCoverageFiles < RawCoverage > ( {
7071 onFileRead ( coverage ) {
7172 merged = mergeProcessCovs ( [ merged , coverage ] )
73+
74+ // mergeProcessCovs sometimes loses startOffset, e.g. in vue
75+ merged . result . forEach ( ( result ) => {
76+ if ( ! result . startOffset ) {
77+ const original = coverage . result . find ( r => r . url === result . url )
78+ result . startOffset = original ?. startOffset || 0
79+ }
80+ } )
7281 } ,
7382 onFinished : async ( project , transformMode ) => {
7483 const converted = await this . convertCoverage (
@@ -230,15 +239,12 @@ export class V8CoverageProvider extends BaseCoverageProvider<ResolvedCoverageOpt
230239 source : string
231240 originalSource : string
232241 sourceMap ?: { sourcemap : EncodedSourceMap }
233- isExecuted : boolean
234242 } > {
235243 const filePath = normalize ( fileURLToPath ( url ) )
236244
237- let isExecuted = true
238245 let transformResult : FetchResult | TransformResult | undefined = transformResults . get ( filePath )
239246
240247 if ( ! transformResult ) {
241- isExecuted = false
242248 transformResult = await onTransform ( removeStartsWith ( url , FILE_PROTOCOL ) ) . catch ( ( ) => undefined )
243249 }
244250
@@ -258,7 +264,6 @@ export class V8CoverageProvider extends BaseCoverageProvider<ResolvedCoverageOpt
258264 // These can be uncovered files included by "all: true" or files that are loaded outside vite-node
259265 if ( ! map ) {
260266 return {
261- isExecuted,
262267 source : code || sourcesContent [ 0 ] ,
263268 originalSource : sourcesContent [ 0 ] ,
264269 }
@@ -273,7 +278,6 @@ export class V8CoverageProvider extends BaseCoverageProvider<ResolvedCoverageOpt
273278 }
274279
275280 return {
276- isExecuted,
277281 originalSource : sourcesContent [ 0 ] ,
278282 source : code || sourcesContent [ 0 ] ,
279283 sourceMap : {
@@ -338,20 +342,17 @@ export class V8CoverageProvider extends BaseCoverageProvider<ResolvedCoverageOpt
338342 }
339343
340344 await Promise . all (
341- chunk . map ( async ( { url, functions } ) => {
345+ chunk . map ( async ( { url, functions, startOffset } ) => {
342346 const sources = await this . getSources (
343347 url ,
344348 transformResults ,
345349 onTransform ,
346350 functions ,
347351 )
348352
349- // If file was executed by vite-node we'll need to add its wrapper
350- const wrapperLength = sources . isExecuted ? WRAPPER_LENGTH : 0
351-
352353 const converter = v8ToIstanbul (
353354 url ,
354- wrapperLength ,
355+ startOffset ,
355356 sources ,
356357 undefined ,
357358 this . options . ignoreEmptyLines ,
0 commit comments