mirror of
https://github.com/hanzoai/vitest.git
synced 2026-09-24 17:04:25 +00:00
326 lines
8.1 KiB
TypeScript
326 lines
8.1 KiB
TypeScript
import type { defineConfig } from 'vitest/config'
|
|
import type { CoverageInstrumenter, CoverageProviderModule, InstrumenterOptions, ResolvedCoverageOptions, Vitest } from 'vitest/node'
|
|
import { assertType, test } from 'vitest'
|
|
|
|
type NarrowToTestConfig<T> = T extends { test?: any } ? NonNullable<T['test']> : never
|
|
type Configuration = NarrowToTestConfig<(Parameters<typeof defineConfig>[0])>
|
|
type Coverage = NonNullable<Configuration['coverage']>
|
|
|
|
test('providers, built-in', () => {
|
|
assertType<Coverage>({ provider: 'v8' })
|
|
assertType<Coverage>({ provider: 'istanbul' })
|
|
|
|
// @ts-expect-error -- String options must be known ones only
|
|
assertType<Coverage>({ provider: 'unknown-provider' })
|
|
})
|
|
|
|
test('providers, custom', () => {
|
|
assertType<Coverage>({
|
|
provider: 'custom',
|
|
customProviderModule: 'custom-provider-module.ts',
|
|
})
|
|
})
|
|
|
|
test('provider options, generic', () => {
|
|
assertType<Coverage>({
|
|
provider: 'v8',
|
|
enabled: true,
|
|
include: ['string'],
|
|
watermarks: {
|
|
functions: [80, 95],
|
|
lines: [80, 95],
|
|
},
|
|
thresholds: {
|
|
'100': true,
|
|
'lines': 1,
|
|
'autoUpdate': true,
|
|
'perFile': true,
|
|
'statements': 100,
|
|
|
|
'**/some-file.ts': {
|
|
100: true,
|
|
lines: 12,
|
|
branches: 12,
|
|
functions: 12,
|
|
statements: 12,
|
|
perFile: true,
|
|
},
|
|
},
|
|
})
|
|
|
|
assertType<Coverage>({
|
|
provider: 'istanbul',
|
|
enabled: true,
|
|
include: ['string'],
|
|
watermarks: {
|
|
statements: [80, 95],
|
|
},
|
|
thresholds: {
|
|
'100': false,
|
|
'lines': 1,
|
|
'autoUpdate': true,
|
|
'perFile': true,
|
|
'statements': 100,
|
|
|
|
'**/some-file.ts': {
|
|
100: false,
|
|
lines: 12,
|
|
branches: 12,
|
|
functions: 12,
|
|
statements: 12,
|
|
},
|
|
},
|
|
})
|
|
|
|
assertType<Coverage>({
|
|
provider: 'v8',
|
|
thresholds: {
|
|
lines: 80,
|
|
functions: 80,
|
|
branches: 80,
|
|
statements: 80,
|
|
perFile: {
|
|
lines: 50,
|
|
functions: 50,
|
|
branches: 50,
|
|
statements: 50,
|
|
},
|
|
},
|
|
})
|
|
|
|
// Glob patterns accept their own `perFile` (boolean or object).
|
|
assertType<Coverage>({
|
|
provider: 'v8',
|
|
thresholds: {
|
|
'**/some-file.ts': {
|
|
perFile: true,
|
|
},
|
|
'**/other-file.ts': {
|
|
perFile: {
|
|
lines: 50,
|
|
},
|
|
},
|
|
'**/strict.ts': {
|
|
perFile: {
|
|
100: true,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
assertType<Coverage>({
|
|
provider: 'v8',
|
|
thresholds: {
|
|
'**/some-file.ts': {
|
|
perFile: {
|
|
// @ts-expect-error -- per-file threshold values must be numbers
|
|
lines: '50',
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
assertType<Coverage>({
|
|
provider: 'istanbul',
|
|
thresholds: {
|
|
lines: 80,
|
|
perFile: {
|
|
100: true,
|
|
},
|
|
},
|
|
})
|
|
|
|
assertType<Coverage>({
|
|
provider: 'v8',
|
|
thresholds: {
|
|
perFile: {
|
|
// @ts-expect-error -- per-file threshold values must be numbers
|
|
lines: '50',
|
|
},
|
|
},
|
|
})
|
|
|
|
assertType<Coverage>({
|
|
provider: 'v8',
|
|
thresholds: {
|
|
perFile: {
|
|
// @ts-expect-error -- `autoUpdate` is not a per-file option
|
|
autoUpdate: true,
|
|
},
|
|
},
|
|
})
|
|
})
|
|
|
|
test('provider module', () => {
|
|
assertType<CoverageProviderModule>({
|
|
getProvider() {
|
|
return {
|
|
name: 'custom-provider',
|
|
initialize(_: Vitest) {},
|
|
generateCoverage() {},
|
|
resolveOptions(): ResolvedCoverageOptions {
|
|
return {
|
|
provider: 'v8',
|
|
clean: true,
|
|
cleanOnRerun: true,
|
|
enabled: true,
|
|
exclude: ['string'],
|
|
reporter: [['html', {}], ['json', { file: 'string' }]],
|
|
reportsDirectory: 'string',
|
|
reportOnFailure: true,
|
|
allowExternal: true,
|
|
processingConcurrency: 1,
|
|
excludeAfterRemap: false,
|
|
ignoreClassMethods: [],
|
|
skipFull: true,
|
|
watermarks: {
|
|
statements: [80, 95],
|
|
functions: [80, 95],
|
|
branches: [80, 95],
|
|
lines: [80, 95],
|
|
},
|
|
autoAttachSubprocess: false,
|
|
}
|
|
},
|
|
clean(_?: boolean) {},
|
|
onBeforeFilesRun() {},
|
|
onAfterSuiteRun({ coverage: _coverage }) {},
|
|
reportCoverage() {},
|
|
onFileTransform(_code: string, _id: string, ctx) {
|
|
ctx.getCombinedSourcemap()
|
|
},
|
|
}
|
|
},
|
|
takeCoverage() {},
|
|
startCoverage() {},
|
|
stopCoverage() {},
|
|
})
|
|
})
|
|
|
|
test('reporters, single', () => {
|
|
assertType<Coverage>({ reporter: 'clover' })
|
|
assertType<Coverage>({ reporter: 'cobertura' })
|
|
assertType<Coverage>({ reporter: 'html-spa' })
|
|
assertType<Coverage>({ reporter: 'html' })
|
|
assertType<Coverage>({ reporter: 'json-summary' })
|
|
assertType<Coverage>({ reporter: 'json' })
|
|
assertType<Coverage>({ reporter: 'lcov' })
|
|
assertType<Coverage>({ reporter: 'lcovonly' })
|
|
assertType<Coverage>({ reporter: 'none' })
|
|
assertType<Coverage>({ reporter: 'teamcity' })
|
|
assertType<Coverage>({ reporter: 'text-lcov' })
|
|
assertType<Coverage>({ reporter: 'text-summary' })
|
|
assertType<Coverage>({ reporter: 'text' })
|
|
assertType<Coverage>({ reporter: 'custom-reporter' })
|
|
})
|
|
|
|
test('reporters, multiple', () => {
|
|
assertType<Coverage>({
|
|
reporter: [
|
|
'clover',
|
|
'cobertura',
|
|
'html-spa',
|
|
'html',
|
|
'json-summary',
|
|
'json',
|
|
'lcov',
|
|
'lcovonly',
|
|
'none',
|
|
'teamcity',
|
|
'text-lcov',
|
|
'text-summary',
|
|
'text',
|
|
],
|
|
})
|
|
|
|
assertType<Coverage>({ reporter: ['custom-reporter'] })
|
|
assertType<Coverage>({ reporter: ['html', 'json', 'custom-reporter'] })
|
|
})
|
|
|
|
test('reporters, with options', () => {
|
|
assertType<Coverage>({
|
|
reporter: [
|
|
['clover', { projectRoot: 'string', file: 'string' }],
|
|
['cobertura', { projectRoot: 'string', file: 'string' }],
|
|
['html-spa', { metricsToShow: ['branches', 'functions'], verbose: true, subdir: 'string' }],
|
|
['html', { verbose: true, subdir: 'string' }],
|
|
['json-summary', { file: 'string' }],
|
|
['json', { file: 'string' }],
|
|
['lcov', { projectRoot: 'string', file: 'string' }],
|
|
['lcovonly', { projectRoot: 'string', file: 'string' }],
|
|
['none'],
|
|
['teamcity', { blockName: 'string' }],
|
|
['text-lcov', { projectRoot: 'string' }],
|
|
['text-summary', { file: 'string' }],
|
|
['text', { skipEmpty: true, skipFull: true, maxCols: 1 }],
|
|
['custom-reporter', { 'someOption': true, 'some-other-custom-option': { width: 123 } }],
|
|
],
|
|
})
|
|
|
|
assertType<Coverage>({
|
|
reporter: [
|
|
['html', { subdir: 'string' }],
|
|
['json'],
|
|
['lcov', { projectRoot: 'string' }],
|
|
],
|
|
})
|
|
|
|
assertType<Coverage>({
|
|
reporter: [
|
|
// @ts-expect-error -- second value should be object even though TS intellisense prompts types of reporters
|
|
['lcov', 'html-spa'],
|
|
],
|
|
})
|
|
})
|
|
|
|
test('reporters, mixed variations', () => {
|
|
assertType<Coverage>({
|
|
reporter: [
|
|
'clover',
|
|
'custom-reporter-1',
|
|
['cobertura'],
|
|
['custom-reporter-2'],
|
|
['html-spa', {}],
|
|
['custom-reporter-3', {}],
|
|
['html', { verbose: true, subdir: 'string' }],
|
|
['custom-reporter-4', { some: 'option', width: 123 }],
|
|
],
|
|
})
|
|
})
|
|
|
|
test('custom instrumenter', () => {
|
|
// Custom instrumenter factory function
|
|
assertType<Coverage>({
|
|
provider: 'istanbul',
|
|
instrumenter: _options => ({
|
|
instrumentSync: (code, _filename, _sourceMap?) => code,
|
|
lastSourceMap: () => ({}),
|
|
lastFileCoverage: () => ({}),
|
|
}),
|
|
})
|
|
|
|
// Without instrumenter (default behavior)
|
|
assertType<Coverage>({
|
|
provider: 'istanbul',
|
|
})
|
|
|
|
// Verify CoverageInstrumenter type can be used as return type
|
|
const factory: (opts: InstrumenterOptions) => CoverageInstrumenter = _opts => ({
|
|
instrumentSync: code => code,
|
|
lastSourceMap: () => null,
|
|
lastFileCoverage: () => ({}),
|
|
})
|
|
|
|
assertType<InstrumenterOptions>({
|
|
coverageVariable: '__VITEST_COVERAGE__',
|
|
coverageGlobalScope: 'globalThis',
|
|
coverageGlobalScopeFunc: false,
|
|
ignoreClassMethods: ['test-method'],
|
|
})
|
|
|
|
assertType<Coverage>({
|
|
provider: 'istanbul',
|
|
instrumenter: factory,
|
|
})
|
|
})
|