diff --git a/packages/coverage-v8/src/provider.ts b/packages/coverage-v8/src/provider.ts index 308b96b7f..bea15a123 100644 --- a/packages/coverage-v8/src/provider.ts +++ b/packages/coverage-v8/src/provider.ts @@ -257,6 +257,19 @@ export class V8CoverageProvider extends BaseCoverageProvider implements Coverage return true } + // SSR transformed import binding + if ( + type === 'statement' + && node.type === 'VariableDeclarator' + && node.init + && node.init.type === 'MemberExpression' + && node.init.object.type === 'MemberExpression' + && node.init.object.object.type === 'Identifier' + && node.init.object.object.name.startsWith('__vite_ssr_import_') + ) { + return true + } + // SSR transformed exports vite@>6.3.5 if ( type === 'statement' diff --git a/test/coverage-test/fixtures/src/node-built-ins.ts b/test/coverage-test/fixtures/src/node-built-ins.ts new file mode 100644 index 000000000..b7ad7246a --- /dev/null +++ b/test/coverage-test/fixtures/src/node-built-ins.ts @@ -0,0 +1,5 @@ +import { randomUUID } from "node:crypto"; + +export function makeId(): string { + return randomUUID(); +} diff --git a/test/coverage-test/fixtures/test/vite-ssr-imports.test.ts b/test/coverage-test/fixtures/test/vite-ssr-imports.test.ts new file mode 100644 index 000000000..bba5efc85 --- /dev/null +++ b/test/coverage-test/fixtures/test/vite-ssr-imports.test.ts @@ -0,0 +1,6 @@ +import { expect, test } from 'vitest' +import { makeId } from '../src/node-built-ins' + +test('makeId', () => { + expect(makeId()).toBeTypeOf('string') +}) diff --git a/test/coverage-test/test/results-snapshot.test.ts b/test/coverage-test/test/results-snapshot.test.ts index e34b548de..adb8d235a 100644 --- a/test/coverage-test/test/results-snapshot.test.ts +++ b/test/coverage-test/test/results-snapshot.test.ts @@ -1,5 +1,5 @@ import { expect } from 'vitest' -import { readCoverageMap, runVitest, test } from '../utils' +import { isBrowser, readCoverageMap, runVitest, test } from '../utils' test('coverage results matches snapshot', async () => { await runVitest({ @@ -68,3 +68,41 @@ test('coverage results matches snapshot', async () => { } `) }) + +test.for(['node', 'jsdom'] as const)('vite SSR generated code ignored in { environment: %s }', async (environment, { skip }) => { + skip(isBrowser(), 'SSR not relevant to browser environment') + + await runVitest({ + include: ['fixtures/test/vite-ssr-imports.test.ts'], + environment, + coverage: { reporter: 'json', + }, + }) + + const coverageMap = await readCoverageMap() + const fileCoverages = coverageMap.files().map(file => coverageMap.fileCoverageFor(file)) + + expect(fileCoverages).toMatchInlineSnapshot(` + { + "/fixtures/src/node-built-ins.ts": { + "branches": "0/0 (100%)", + "functions": "1/1 (100%)", + "lines": "1/1 (100%)", + "statements": "1/1 (100%)", + }, + } + `) + + const lineCoverages = coverageMap.files().reduce((all, file) => ({ + [file]: coverageMap.fileCoverageFor(file).getLineCoverage(), + ...all, + }), {}) + + expect(lineCoverages).toMatchInlineSnapshot(` + { + "/fixtures/src/node-built-ins.ts": { + "4": 1, + }, + } + `) +})