mirror of
https://github.com/hanzoai/vitest.git
synced 2026-09-24 17:04:25 +00:00
168 lines
5.1 KiB
TypeScript
168 lines
5.1 KiB
TypeScript
import type { CoverageSummary, FileCoverageData } from 'istanbul-lib-coverage'
|
|
import type { UserConfig as ViteUserConfig } from 'vite'
|
|
import type { SuiteAPI, TestAPI } from 'vitest'
|
|
import type { TestUserConfig } from 'vitest/node'
|
|
import { existsSync, readFileSync } from 'node:fs'
|
|
import { unlink } from 'node:fs/promises'
|
|
import { relative, resolve } from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
import { stripVTControlCharacters } from 'node:util'
|
|
import { playwright } from '@vitest/browser-playwright'
|
|
import { toArray } from '@vitest/utils/helpers'
|
|
import libCoverage from 'istanbul-lib-coverage'
|
|
import { normalize } from 'pathe'
|
|
import { onTestFailed, onTestFinished, TestRunner, vi, describe as vitestDescribe, test as vitestTest } from 'vitest'
|
|
import * as testUtils from '../test-utils/index'
|
|
|
|
export const test: TestAPI = process.env.COVERAGE_TEST !== 'true'
|
|
? vitestTest
|
|
: (() => {}) as any as TestAPI
|
|
|
|
export const describe: SuiteAPI = process.env.COVERAGE_TEST !== 'true'
|
|
? vitestDescribe
|
|
: (() => {}) as any as SuiteAPI
|
|
|
|
export const coverageTest: TestAPI = process.env.COVERAGE_TEST !== 'true'
|
|
? (() => {}) as any as TestAPI
|
|
: vitestTest
|
|
|
|
export const runVitest = vi.defineHelper(async (config: TestUserConfig, options = { throwOnError: true }, viteOverrides: ViteUserConfig = {}) => {
|
|
const provider = process.env.COVERAGE_PROVIDER as any
|
|
|
|
const result = await testUtils.runVitest({
|
|
config: 'fixtures/configs/vitest.config.ts',
|
|
pool: 'threads',
|
|
...config,
|
|
env: {
|
|
COVERAGE_TEST: 'true',
|
|
...config.env,
|
|
},
|
|
coverage: {
|
|
enabled: true,
|
|
reporter: [],
|
|
...config.coverage,
|
|
provider,
|
|
customProviderModule: provider === 'custom' ? 'fixtures/custom-provider' : undefined,
|
|
},
|
|
browser: {
|
|
enabled: process.env.COVERAGE_BROWSER === 'true',
|
|
headless: true,
|
|
instances: [{ browser: 'chromium' }],
|
|
provider: playwright(),
|
|
...config.browser,
|
|
},
|
|
experimental: {
|
|
...config.experimental,
|
|
viteModuleRunner: process.env.VITE_MODULE_RUNNER === 'false' ? false : config.experimental?.viteModuleRunner,
|
|
},
|
|
setupFiles: [
|
|
resolve(import.meta.dirname, 'setup.native.ts'),
|
|
...config.setupFiles ?? [],
|
|
],
|
|
|
|
projects: config.projects?.map((project) => {
|
|
if (typeof project !== 'string' && 'test' in project) {
|
|
project.test ||= {}
|
|
project.test.setupFiles = toArray(project.test.setupFiles)
|
|
project.test.setupFiles.push(resolve(import.meta.dirname, 'setup.native.ts'))
|
|
}
|
|
|
|
return project
|
|
}),
|
|
|
|
$viteConfig: viteOverrides,
|
|
})
|
|
|
|
if (TestRunner.getCurrentTest()) {
|
|
onTestFailed(() => {
|
|
console.error('stderr:', result.stderr)
|
|
console.error('stdout:', result.stdout)
|
|
})
|
|
|
|
onTestFinished(() => {
|
|
if (process.env.NODE_V8_COVERAGE) {
|
|
delete process.env.NODE_V8_COVERAGE
|
|
}
|
|
})
|
|
}
|
|
|
|
if (options.throwOnError) {
|
|
if (result.stderr !== '') {
|
|
throw new Error(`stderr:\n${result.stderr}\n\nstdout:\n${result.stdout}`)
|
|
}
|
|
}
|
|
|
|
return result
|
|
})
|
|
|
|
export async function cleanupCoverageJson(name = './coverage/coverage-final.json') {
|
|
if (existsSync(name)) {
|
|
await unlink(name)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Read JSON coverage report from file system.
|
|
* Normalizes paths to keep contents consistent between OS's
|
|
*/
|
|
export async function readCoverageJson(name = './coverage/coverage-final.json') {
|
|
const jsonReport = JSON.parse(readFileSync(name, 'utf8')) as Record<string, FileCoverageData>
|
|
|
|
const normalizedReport: typeof jsonReport = {}
|
|
|
|
for (const [filename, coverage] of Object.entries(jsonReport)) {
|
|
coverage.path = normalizeFilename(coverage.path)
|
|
normalizedReport[normalizeFilename(filename)] = coverage
|
|
}
|
|
|
|
return normalizedReport
|
|
}
|
|
|
|
/**
|
|
* Read coverage report from file system as Istanbul's `CoverageMap`
|
|
*/
|
|
export async function readCoverageMap(name = './coverage/coverage-final.json') {
|
|
const coverageJson = await readCoverageJson(name)
|
|
return libCoverage.createCoverageMap(coverageJson)
|
|
}
|
|
|
|
export function formatSummary(summary: CoverageSummary) {
|
|
return (['branches', 'functions', 'lines', 'statements'] as const).reduce((all, current) => ({
|
|
...all,
|
|
[current]: `${summary[current].covered}/${summary[current].total} (${summary[current].pct}%)`,
|
|
}), {})
|
|
}
|
|
|
|
export function normalizeFilename(filename: string) {
|
|
return normalize(filename)
|
|
.replace(normalize(process.cwd()), '<process-cwd>')
|
|
.replace(normalize(resolve(process.cwd(), '../../')), '<project-root>')
|
|
}
|
|
|
|
export function isV8Provider() {
|
|
return process.env.COVERAGE_PROVIDER === 'v8'
|
|
}
|
|
|
|
export function isBrowser() {
|
|
return process.env.COVERAGE_BROWSER === 'true'
|
|
}
|
|
|
|
export function isNativeRunner() {
|
|
return process.env.VITE_MODULE_RUNNER === 'false'
|
|
}
|
|
|
|
export function normalizeURL(importMetaURL: string) {
|
|
return normalize(relative(process.cwd(), fileURLToPath(importMetaURL)))
|
|
}
|
|
|
|
export function captureStdout() {
|
|
const spy = vi.fn()
|
|
const original = process.stdout.write
|
|
process.stdout.write = spy
|
|
|
|
return function collect() {
|
|
process.stdout.write = original
|
|
return stripVTControlCharacters(spy.mock.calls.map(call => call[0]).join(''))
|
|
}
|
|
}
|