Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
Something went wrong. Try again.
4.2 kB · 146 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147import type { Profiler } from 'node:inspector'import type { CoverageProviderModule } from 'vitest/node'import type { ScriptCoverageWithOffset, V8CoverageProvider } from './provider'import assert from 'node:assert'import { randomUUID } from 'node:crypto'import { existsSync } from 'node:fs'import { readdir, readFile, rm } from 'node:fs/promises'import inspector from 'node:inspector/promises'import { resolve } from 'node:path'import { fileURLToPath } from 'node:url'import { normalize } from 'pathe'import { provider } from 'std-env'import { writeCoverageFile } from './commands'import { loadProvider } from './load-provider'
let enabled = false
const mod: CoverageProviderModule & { extendedContextCoverageDir?: string // Use unknown to avoid bundling node:inspector session?: unknown | null} = { extendedContextCoverageDir: undefined, session: null,
async startCoverage({ isolate, autoAttachSubprocess, reportsDirectory }) { if (isolate === false && enabled) { return }
enabled = true
if (autoAttachSubprocess) { this.extendedContextCoverageDir = resolve(reportsDirectory, 'tmp', randomUUID()) process.env.NODE_V8_COVERAGE = this.extendedContextCoverageDir }
this.session ||= new inspector.Session() const session = this.session as inspector.Session
session.connect() await session.post('Profiler.enable') await session.post('Profiler.startPreciseCoverage', { callCount: true, detailed: true }) },
async takeCoverage(options): Promise<string | undefined> { if (provider === 'stackblitz') { return }
const session = this.session as inspector.Session
if (!session) { throw new Error('V8 provider missing inspector session.') }
const coverage = await session.post('Profiler.takePreciseCoverage') const result: ScriptCoverageWithOffset[] = []
// Reduce amount of data sent over rpc by doing some early result filtering for (const entry of coverage.result as ScriptCoverageWithOffset[]) { if (filterResult(entry)) { entry.startOffset = options?.moduleExecutionInfo?.get(normalize(fileURLToPath(entry.url)))?.startOffset || 0
result.push(entry) } }
if (this.extendedContextCoverageDir && existsSync(this.extendedContextCoverageDir)) { const filenames = await readdir(this.extendedContextCoverageDir) const contents = await Promise.all( filenames .filter((filename) => filename.endsWith('.json')) .map(async (filename) => { const path = `${this.extendedContextCoverageDir}/${filename}`
const content = await readFile(path, 'utf8') await rm(path)
return content }), )
for (const content of contents) { const json: { result: ScriptCoverageWithOffset[] } = JSON.parse(content)
for (const entry of json.result) { if (filterResult(entry)) { entry.startOffset = 0 entry.isExtendedContext = true
result.push(entry) } } } }
const coverageFilesDirectory = options?.coverageFilesDirectory assert(coverageFilesDirectory, 'coverageFilesDirectory is required')
return await writeCoverageFile(coverageFilesDirectory, { result }) },
async stopCoverage({ isolate }) { if (isolate === false) { return }
const session = this.session as inspector.Session
if (!session) { throw new Error('V8 provider missing inspector session.') }
await session.post('Profiler.stopPreciseCoverage') await session.post('Profiler.disable') session.disconnect() this.session = null },
async getProvider(): Promise<V8CoverageProvider> { return loadProvider() },}export default mod
function filterResult(coverage: Profiler.ScriptCoverage): boolean { if (!coverage.url.startsWith('file://')) { return false }
if (coverage.url.includes('/node_modules/')) { return false }
if (coverage.url.includes('/@id/@vitest/')) { return false }
if (coverage.url.includes('/@vite/client')) { return false }
return true}