Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: debug Vite PR 18983 #7096

Draft
wants to merge 20 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions examples/repro/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```sh
VITE_NODE_DEBUG_DUMP=1 pnpm -C examples/repro test -- --coverage
```
16 changes: 16 additions & 0 deletions examples/repro/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "@vitest/example-repro",
"type": "module",
"private": true,
"license": "MIT",
"scripts": {
"test": "vitest"
},
"devDependencies": {
"magic-string": "^0.30.17",
"vitest": "latest"
},
"stackblitz": {
"startCommand": "npm run test:ui"
}
}
6 changes: 6 additions & 0 deletions examples/repro/src/basic.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { expect, test } from 'vitest'
import { squared } from './basic'

test('repro', () => {
expect(squared(2)).toBe(4)
})
2 changes: 2 additions & 0 deletions examples/repro/src/basic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const squared = (n: number) => n * n
export const cube = (n: number) => n * n * n
26 changes: 26 additions & 0 deletions examples/repro/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import MagicString from 'magic-string'
import { defineConfig } from 'vitest/config'

export default defineConfig({
test: {
coverage: {
reporter: ['text', 'text-summary', 'html', 'clover', 'json'],
},
},
plugins: [
{
name: 'repro',
transform(code, id, _options) {
if (id.endsWith('/basic.ts')) {
const output = new MagicString(code)
output.prepend(`function prepended(){};`)
output.append(`;function appended(){};`)
return {
code: output.toString(),
map: output.generateMap({ hires: 'boundary' }),
}
}
},
},
],
})
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"tinyglobby": "^0.2.10",
"tsx": "^4.19.2",
"typescript": "^5.7.2",
"vite": "^5.4.0",
"vite": "https://pkg.pr.new/vite@059d132",
"vitest": "workspace:*",
"zx": "^8.2.4"
},
Expand Down
33 changes: 32 additions & 1 deletion packages/coverage-v8/src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import v8ToIstanbul from 'v8-to-istanbul'
import { cleanUrl } from 'vite-node/utils'

import { BaseCoverageProvider } from 'vitest/coverage'
import { offsetToPosition, originalPositionFor, TraceMap } from 'vitest/utils'
import { version } from '../package.json' with { type: 'json' }

type TransformResults = Map<string, FetchResult>
Expand Down Expand Up @@ -277,6 +278,7 @@ export class V8CoverageProvider extends BaseCoverageProvider<ResolvedCoverageOpt
originalSource: sourcesContent[0],
source: code || sourcesContent[0],
sourceMap: {
// sourcemap: map,
sourcemap: excludeGeneratedCode(code, {
...map,
version: 3,
Expand Down Expand Up @@ -348,6 +350,32 @@ export class V8CoverageProvider extends BaseCoverageProvider<ResolvedCoverageOpt

// If file was executed by vite-node we'll need to add its wrapper
const wrapperLength = sources.isExecuted ? WRAPPER_LENGTH : 0
// console.log({ sources, wrapperLength, url })
// console.log(...functions)

// filter out functions without mappings,
// for example, "export getter" injected by Vite ssr transform.
// https://github.com/vitest-dev/vitest/issues/7130
if (sources.isExecuted && sources.sourceMap) {
const traceMap = new TraceMap(sources.sourceMap.sourcemap)
functions = functions.filter((f) => {
if (f.ranges.length === 1) {
const start = f.ranges[0].startOffset - wrapperLength
const end = f.ranges[0].endOffset - wrapperLength
if (start < 0) {
return true
}
const startPos = offsetToPosition(sources.source, start)
const endPos = offsetToPosition(sources.source, end)
const startSourcePos = originalPositionFor(traceMap, startPos)
const endSourcePos = originalPositionFor(traceMap, endPos)
if (startSourcePos.line === null && endSourcePos.line === null) {
return false
}
}
return true
})
}

const converter = v8ToIstanbul(
url,
Expand All @@ -365,6 +393,9 @@ export class V8CoverageProvider extends BaseCoverageProvider<ResolvedCoverageOpt
this.ctx.logger.error(`Failed to convert coverage for ${url}.\n`, error)
}

// const converted = converter.toIstanbul()
// console.log(Object.values(converted)[0])
// coverageMap.merge(converted)
coverageMap.merge(converter.toIstanbul())
}),
)
Expand Down Expand Up @@ -400,7 +431,7 @@ function excludeGeneratedCode(
}

const trimmed = new MagicString(source)
trimmed.replaceAll(VITE_EXPORTS_LINE_PATTERN, '\n')
// trimmed.replaceAll(VITE_EXPORTS_LINE_PATTERN, '\n')
trimmed.replaceAll(DECORATOR_METADATA_PATTERN, match =>
'\n'.repeat(match.split('\n').length - 1))

Expand Down
1 change: 1 addition & 0 deletions packages/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export { nanoid } from './nanoid'
export {
lineSplitRE,
offsetToLineNumber,
offsetToPosition,
positionToOffset,
} from './offset'
export { shuffle } from './random'
Expand Down
22 changes: 22 additions & 0 deletions packages/utils/src/offset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,25 @@ export function offsetToLineNumber(source: string, offset: number): number {
}
return line + 1
}

export function offsetToPosition(
source: string,
offset: number,
): { line: number; column: number } {
const lineLengths = source
.split(/(?<=\n)|(?<=\r\n)/)
.map(line => line.length)
let acc = 0
for (let i = 0; i < lineLengths.length; i++) {
if (offset <= acc + lineLengths[i]) {
return {
line: i + 1,
column: offset - acc,
}
}
acc += lineLengths[i]
}
throw new Error(
`offset is longer than source length! offset ${offset} > length ${source.length}`,
)
}
2 changes: 1 addition & 1 deletion packages/vite-node/src/source-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function withInlineSourcemap(
// If the first line is not present on source maps, add simple 1:1 mapping ([0,0,0,0], [1,0,0,0])
// so that debuggers can be set to break on first line
if (map.mappings.startsWith(';')) {
map.mappings = `AAAA,CAAA${map.mappings}`
// map.mappings = `AAAA,CAAA${map.mappings}`
}

const sourceMap = Buffer.from(JSON.stringify(map), 'utf-8').toString(
Expand Down
1 change: 1 addition & 0 deletions packages/vitest/src/utils/source-map.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export {
lineSplitRE,
offsetToLineNumber,
offsetToPosition,
positionToOffset,
} from '@vitest/utils'
export {
Expand Down
Loading
Loading