From fec9ca0b9c5356648d821dffd515dc9fb217c531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Perkki=C3=B6?= Date: Mon, 5 Feb 2024 17:56:36 +0200 Subject: [PATCH] feat(reporters): support custom options (#5111) --- docs/guide/reporters.md | 30 ++++++++- packages/ui/node/reporter.ts | 11 +++- packages/vitest/src/node/config.ts | 50 +++++++++++++-- packages/vitest/src/node/reporters/index.ts | 17 +++++- packages/vitest/src/node/reporters/json.ts | 11 +++- packages/vitest/src/node/reporters/junit.ts | 19 +++++- packages/vitest/src/node/reporters/utils.ts | 25 ++++---- packages/vitest/src/types/config.ts | 16 ++++- test/reporters/src/custom-reporter.ts | 8 +++ .../tests/configuration-options.test-d.ts | 61 +++++++++++++++++++ test/reporters/tests/custom-reporter.spec.ts | 6 ++ test/reporters/tests/junit.test.ts | 60 +++++++++++++----- test/reporters/tests/reporters.spec.ts | 26 ++++---- test/reporters/tests/utils.test.ts | 6 +- test/reporters/vitest.config.ts | 4 ++ 15 files changed, 292 insertions(+), 58 deletions(-) create mode 100644 test/reporters/tests/configuration-options.test-d.ts diff --git a/docs/guide/reporters.md b/docs/guide/reporters.md index 8c78c539b403..b773f066a844 100644 --- a/docs/guide/reporters.md +++ b/docs/guide/reporters.md @@ -26,6 +26,23 @@ export default defineConfig({ }) ``` +Some reporters can be customized by passing additional options to them. Reporter specific options are described in sections below. + +:::tip +Since Vitest v1.3.0 +::: + +```ts +export default defineConfig({ + test: { + reporters: [ + 'default', + ['junit', { suiteName: 'UI tests' }] + ], + }, +}) +``` + ## Reporter Output By default, Vitest's reporters will print their output to the terminal. When using the `json`, `html` or `junit` reporters, you can instead write your tests' output to a file by including an `outputFile` [configuration option](/config/#outputfile) either in your Vite configuration file or via CLI. @@ -234,7 +251,18 @@ AssertionError: expected 5 to be 4 // Object.is equality ``` -The outputted XML contains nested `testsuites` and `testcase` tags. You can use the environment variables `VITEST_JUNIT_SUITE_NAME` and `VITEST_JUNIT_CLASSNAME` to configure their `name` and `classname` attributes, respectively. + +The outputted XML contains nested `testsuites` and `testcase` tags. You can use the environment variables `VITEST_JUNIT_SUITE_NAME` and `VITEST_JUNIT_CLASSNAME` to configure their `name` and `classname` attributes, respectively. These can also be customized via reporter options: + +```ts +export default defineConfig({ + test: { + reporters: [ + ['junit', { suiteName: 'custom suite name', classname: 'custom-classname' }] + ] + }, +}) +``` ### JSON Reporter diff --git a/packages/ui/node/reporter.ts b/packages/ui/node/reporter.ts index 3196f5b18e12..a11b18b6a30e 100644 --- a/packages/ui/node/reporter.ts +++ b/packages/ui/node/reporter.ts @@ -9,6 +9,10 @@ import { stringify } from 'flatted' import type { File, ModuleGraphData, Reporter, ResolvedConfig, Vitest } from 'vitest' import { getModuleGraph } from '../../vitest/src/utils/graph' +export interface HTMLOptions { + outputFile?: string +} + interface PotentialConfig { outputFile?: string | Partial> } @@ -37,6 +41,11 @@ export default class HTMLReporter implements Reporter { start = 0 ctx!: Vitest reportUIPath!: string + options: HTMLOptions + + constructor(options: HTMLOptions) { + this.options = options + } async onInit(ctx: Vitest) { this.ctx = ctx @@ -60,7 +69,7 @@ export default class HTMLReporter implements Reporter { } async writeReport(report: string) { - const htmlFile = getOutputFile(this.ctx.config) || 'html/index.html' + const htmlFile = this.options.outputFile || getOutputFile(this.ctx.config) || 'html/index.html' const htmlFileName = basename(htmlFile) const htmlDir = resolve(this.ctx.config.root, dirname(htmlFile)) diff --git a/packages/vitest/src/node/config.ts b/packages/vitest/src/node/config.ts index 618c150cceb4..a032dbe10546 100644 --- a/packages/vitest/src/node/config.ts +++ b/packages/vitest/src/node/config.ts @@ -358,21 +358,63 @@ export function resolveConfig( if (options.related) resolved.related = toArray(options.related).map(file => resolve(resolved.root, file)) + /* + * Reporters can be defined in many different ways: + * { reporter: 'json' } + * { reporter: { onFinish() { method() } } } + * { reporter: ['json', { onFinish() { method() } }] } + * { reporter: [[ 'json' ]] } + * { reporter: [[ 'json' ], 'html'] } + * { reporter: [[ 'json', { outputFile: 'test.json' } ], 'html'] } + */ + if (options.reporters) { + if (!Array.isArray(options.reporters)) { + // Reporter name, e.g. { reporters: 'json' } + if (typeof options.reporters === 'string') + resolved.reporters = [[options.reporters, {}]] + // Inline reporter e.g. { reporters: { onFinish() { method() } } } + else + resolved.reporters = [options.reporters] + } + // It's an array of reporters + else { + resolved.reporters = [] + + for (const reporter of options.reporters) { + if (Array.isArray(reporter)) { + // Reporter with options, e.g. { reporters: [ [ 'json', { outputFile: 'test.json' } ] ] } + resolved.reporters.push([reporter[0], reporter[1] || {}]) + } + else if (typeof reporter === 'string') { + // Reporter name in array, e.g. { reporters: ["html", "json"]} + resolved.reporters.push([reporter, {}]) + } + else { + // Inline reporter, e.g. { reporter: [{ onFinish() { method() } }] } + resolved.reporters.push(reporter) + } + } + } + } + if (mode !== 'benchmark') { // @ts-expect-error "reporter" is from CLI, should be absolute to the running directory // it is passed down as "vitest --reporter ../reporter.js" - const cliReporters = toArray(resolved.reporter || []).map((reporter: string) => { + const reportersFromCLI = resolved.reporter + + const cliReporters = toArray(reportersFromCLI || []).map((reporter: string) => { // ./reporter.js || ../reporter.js, but not .reporters/reporter.js if (/^\.\.?\//.test(reporter)) return resolve(process.cwd(), reporter) return reporter }) - const reporters = cliReporters.length ? cliReporters : resolved.reporters - resolved.reporters = Array.from(new Set(toArray(reporters as 'json'[]))).filter(Boolean) + + if (cliReporters.length) + resolved.reporters = Array.from(new Set(toArray(cliReporters))).filter(Boolean).map(reporter => [reporter, {}]) } if (!resolved.reporters.length) - resolved.reporters.push('default') + resolved.reporters.push(['default', {}]) if (resolved.changed) resolved.passWithNoTests ??= true diff --git a/packages/vitest/src/node/reporters/index.ts b/packages/vitest/src/node/reporters/index.ts index 7fc76117b712..146cfe0a0403 100644 --- a/packages/vitest/src/node/reporters/index.ts +++ b/packages/vitest/src/node/reporters/index.ts @@ -2,10 +2,10 @@ import type { Reporter } from '../../types' import { BasicReporter } from './basic' import { DefaultReporter } from './default' import { DotReporter } from './dot' -import { JsonReporter } from './json' +import { type JsonOptions, JsonReporter } from './json' import { VerboseReporter } from './verbose' import { TapReporter } from './tap' -import { JUnitReporter } from './junit' +import { type JUnitOptions, JUnitReporter } from './junit' import { TapFlatReporter } from './tap-flat' import { HangingProcessReporter } from './hanging-process' import type { BaseReporter } from './base' @@ -39,4 +39,17 @@ export const ReportersMap = { export type BuiltinReporters = keyof typeof ReportersMap +export interface BuiltinReporterOptions { + default: never + basic: never + verbose: never + dot: never + json: JsonOptions + tap: never + 'tap-flat': never + junit: JUnitOptions + 'hanging-process': never + html: { outputFile?: string } // TODO: Any better place for defining this UI package's reporter options? +} + export * from './benchmark' diff --git a/packages/vitest/src/node/reporters/json.ts b/packages/vitest/src/node/reporters/json.ts index 019c9405b79b..9f6e4a9526c9 100644 --- a/packages/vitest/src/node/reporters/json.ts +++ b/packages/vitest/src/node/reporters/json.ts @@ -62,9 +62,18 @@ export interface JsonTestResults { // wasInterrupted: boolean } +export interface JsonOptions { + outputFile?: string +} + export class JsonReporter implements Reporter { start = 0 ctx!: Vitest + options: JsonOptions + + constructor(options: JsonOptions) { + this.options = options + } onInit(ctx: Vitest): void { this.ctx = ctx @@ -162,7 +171,7 @@ export class JsonReporter implements Reporter { * @param report */ async writeReport(report: string) { - const outputFile = getOutputFile(this.ctx.config, 'json') + const outputFile = this.options.outputFile ?? getOutputFile(this.ctx.config, 'json') if (outputFile) { const reportFile = resolve(this.ctx.config.root, outputFile) diff --git a/packages/vitest/src/node/reporters/junit.ts b/packages/vitest/src/node/reporters/junit.ts index a82ef7da117c..714c8e525e94 100644 --- a/packages/vitest/src/node/reporters/junit.ts +++ b/packages/vitest/src/node/reporters/junit.ts @@ -12,6 +12,12 @@ import { F_POINTER } from '../../utils/figures' import { getOutputFile } from '../../utils/config-helpers' import { IndentedLogger } from './renderers/indented-logger' +export interface JUnitOptions { + outputFile?: string + classname?: string + suiteName?: string +} + function flattenTasks(task: Task, baseName = ''): Task[] { const base = baseName ? `${baseName} > ` : '' @@ -80,11 +86,16 @@ export class JUnitReporter implements Reporter { private logger!: IndentedLogger> private _timeStart = new Date() private fileFd?: fs.FileHandle + private options: JUnitOptions + + constructor(options: JUnitOptions) { + this.options = options + } async onInit(ctx: Vitest): Promise { this.ctx = ctx - const outputFile = getOutputFile(this.ctx.config, 'junit') + const outputFile = this.options.outputFile ?? getOutputFile(this.ctx.config, 'junit') if (outputFile) { this.reportFile = resolve(this.ctx.config.root, outputFile) @@ -173,7 +184,8 @@ export class JUnitReporter implements Reporter { async writeTasks(tasks: Task[], filename: string): Promise { for (const task of tasks) { await this.writeElement('testcase', { - classname: process.env.VITEST_JUNIT_CLASSNAME ?? filename, + // TODO: v2.0.0 Remove env variable in favor of custom reporter options, e.g. "reporters: [['json', { classname: 'something' }]]" + classname: this.options.classname ?? process.env.VITEST_JUNIT_CLASSNAME ?? filename, name: task.name, time: getDuration(task), }, async () => { @@ -258,7 +270,8 @@ export class JUnitReporter implements Reporter { stats.failures += file.stats.failures return stats }, { - name: process.env.VITEST_JUNIT_SUITE_NAME || 'vitest tests', + // TODO: v2.0.0 Remove env variable in favor of custom reporter options, e.g. "reporters: [['json', { suiteName: 'something' }]]" + name: this.options.suiteName || process.env.VITEST_JUNIT_SUITE_NAME || 'vitest tests', tests: 0, failures: 0, errors: 0, // we cannot detect those diff --git a/packages/vitest/src/node/reporters/utils.ts b/packages/vitest/src/node/reporters/utils.ts index 5b6e4935b5f0..69d9dedeb71c 100644 --- a/packages/vitest/src/node/reporters/utils.ts +++ b/packages/vitest/src/node/reporters/utils.ts @@ -1,9 +1,9 @@ import type { ViteNodeRunner } from 'vite-node/client' -import type { Reporter, Vitest } from '../../types' +import type { Reporter, ResolvedConfig, Vitest } from '../../types' import { BenchmarkReportsMap, ReportersMap } from './index' import type { BenchmarkBuiltinReporters, BuiltinReporters } from './index' -async function loadCustomReporterModule(path: string, runner: ViteNodeRunner): Promise C> { +async function loadCustomReporterModule(path: string, runner: ViteNodeRunner): Promise C> { let customReporterModule: { default: new () => C } try { customReporterModule = await runner.executeId(path) @@ -18,24 +18,27 @@ async function loadCustomReporterModule(path: string, runner return customReporterModule.default } -function createReporters(reporterReferences: Array, ctx: Vitest) { +function createReporters(reporterReferences: ResolvedConfig['reporters'], ctx: Vitest) { const runner = ctx.runner const promisedReporters = reporterReferences.map(async (referenceOrInstance) => { - if (typeof referenceOrInstance === 'string') { - if (referenceOrInstance === 'html') { + if (Array.isArray(referenceOrInstance)) { + const [reporterName, reporterOptions] = referenceOrInstance + + if (reporterName === 'html') { await ctx.packageInstaller.ensureInstalled('@vitest/ui', runner.root) const CustomReporter = await loadCustomReporterModule('@vitest/ui/reporter', runner) - return new CustomReporter() + return new CustomReporter(reporterOptions) } - else if (referenceOrInstance in ReportersMap) { - const BuiltinReporter = ReportersMap[referenceOrInstance as BuiltinReporters] - return new BuiltinReporter() + else if (reporterName in ReportersMap) { + const BuiltinReporter = ReportersMap[reporterName as BuiltinReporters] + return new BuiltinReporter(reporterOptions) } else { - const CustomReporter = await loadCustomReporterModule(referenceOrInstance, runner) - return new CustomReporter() + const CustomReporter = await loadCustomReporterModule(reporterName, runner) + return new CustomReporter(reporterOptions) } } + return referenceOrInstance }) return Promise.all(promisedReporters) diff --git a/packages/vitest/src/types/config.ts b/packages/vitest/src/types/config.ts index b6f55da719fe..6e4be4951b9f 100644 --- a/packages/vitest/src/types/config.ts +++ b/packages/vitest/src/types/config.ts @@ -3,7 +3,7 @@ import type { PrettyFormatOptions } from 'pretty-format' import type { FakeTimerInstallOpts } from '@sinonjs/fake-timers' import type { SequenceHooks, SequenceSetupFiles } from '@vitest/runner' import type { ViteNodeServerOptions } from 'vite-node' -import type { BuiltinReporters } from '../node/reporters' +import type { BuiltinReporterOptions, BuiltinReporters } from '../node/reporters' import type { TestSequencerConstructor } from '../node/sequencers/types' import type { ChaiConfig } from '../integrations/chai/config' import type { CoverageOptions, ResolvedCoverageOptions } from './coverage' @@ -189,6 +189,15 @@ interface DepsOptions { moduleDirectories?: string[] } +type InlineReporter = Reporter +type ReporterName = BuiltinReporters | 'html' | (string & {}) +type ReporterWithOptions = + Name extends keyof BuiltinReporterOptions + ? BuiltinReporterOptions[Name] extends never + ? [Name, {}] + : [Name, Partial] + : [Name, Record] + export interface InlineConfig { /** * Name of the project. Will be used to display in the reporter. @@ -365,8 +374,9 @@ export interface InlineConfig { * Custom reporter for output. Can contain one or more built-in report names, reporter instances, * and/or paths to custom reporters. */ - reporters?: Arrayable> + reporters?: Arrayable | ((ReporterName | InlineReporter) | [ReporterName] | ReporterWithOptions)[] + // TODO: v2.0.0 Remove in favor of custom reporter options, e.g. "reporters: [['json', { outputFile: 'some-dir/file.html' }]]" /** * Write test results to a file when the --reporter=json` or `--reporter=junit` option is also specified. * Also definable individually per reporter by using an object instead. @@ -786,7 +796,7 @@ export interface ResolvedConfig extends Omit, 'config' | 'f pool: Pool poolOptions?: PoolOptions - reporters: (Reporter | BuiltinReporters)[] + reporters: (InlineReporter | ReporterWithOptions)[] defines: Record diff --git a/test/reporters/src/custom-reporter.ts b/test/reporters/src/custom-reporter.ts index 81f53f421db2..5fd7a67b79ee 100644 --- a/test/reporters/src/custom-reporter.ts +++ b/test/reporters/src/custom-reporter.ts @@ -2,6 +2,11 @@ import type { Reporter, Vitest } from 'vitest' export default class TestReporter implements Reporter { ctx!: Vitest + options?: unknown + + constructor(options?: unknown) { + this.options = options + } onInit(ctx: Vitest) { this.ctx = ctx @@ -9,5 +14,8 @@ export default class TestReporter implements Reporter { onFinished() { this.ctx.logger.log('hello from custom reporter') + + if (this.options) + this.ctx.logger.log(`custom reporter options ${JSON.stringify(this.options)}`) } } diff --git a/test/reporters/tests/configuration-options.test-d.ts b/test/reporters/tests/configuration-options.test-d.ts new file mode 100644 index 000000000000..c3af1761609d --- /dev/null +++ b/test/reporters/tests/configuration-options.test-d.ts @@ -0,0 +1,61 @@ +import { assertType, test } from 'vitest' +import type { defineConfig } from 'vitest/config' + +type NarrowToTestConfig = T extends { test?: any } ? NonNullable : never +type Configuration = NonNullable[0])>> + +test('reporters, single', () => { + assertType({ reporters: 'basic' }) + assertType({ reporters: 'default' }) + assertType({ reporters: 'dot' }) + assertType({ reporters: 'hanging-process' }) + assertType({ reporters: 'html' }) + assertType({ reporters: 'json' }) + assertType({ reporters: 'junit' }) + assertType({ reporters: 'tap' }) + assertType({ reporters: 'tap-flat' }) + assertType({ reporters: 'verbose' }) + + assertType({ reporters: 'custom-reporter' }) + assertType({ reporters: './reporter.mjs' }) + assertType({ reporters: { onFinished() {} } }) +}) + +test('reporters, multiple', () => { + assertType({ + reporters: [ + 'basic', + 'default', + 'dot', + 'hanging-process', + 'html', + 'json', + 'junit', + 'tap', + 'tap-flat', + 'verbose', + ], + }) + assertType({ reporters: ['custom-reporter'] }) + assertType({ reporters: ['html', 'json', 'custom-reporter'] }) +}) + +test('reporters, with options', () => { + assertType({ + reporters: [ + ['json', { outputFile: 'test.json' }], + ['junit', { classname: 'something', suiteName: 'Suite name', outputFile: 'test.json' }], + ['vitest-sonar-reporter', { outputFile: 'report.xml' }], + ], + }) +}) + +test('reporters, mixed variations', () => { + assertType({ + reporters: [ + 'default', + ['verbose'], + ['json', { outputFile: 'test.json' }], + ], + }) +}) diff --git a/test/reporters/tests/custom-reporter.spec.ts b/test/reporters/tests/custom-reporter.spec.ts index f4adfc55dd66..4713ad0f8d4e 100644 --- a/test/reporters/tests/custom-reporter.spec.ts +++ b/test/reporters/tests/custom-reporter.spec.ts @@ -75,4 +75,10 @@ describe('custom reporters', () => { expect(stdout).not.includes('hello from package reporter') expect(stdout).includes('hello from custom reporter') }, TIMEOUT) + + test('custom reporter with options', async () => { + const { stdout } = await runVitest({ root, reporters: [[customTsReporterPath, { some: { custom: 'option here' } }]], include: ['tests/reporters.spec.ts'] }) + expect(stdout).includes('hello from custom reporter') + expect(stdout).includes('custom reporter options {"some":{"custom":"option here"}}') + }, TIMEOUT) }) diff --git a/test/reporters/tests/junit.test.ts b/test/reporters/tests/junit.test.ts index 0c721a5fc8f0..72cdcbd4ab98 100644 --- a/test/reporters/tests/junit.test.ts +++ b/test/reporters/tests/junit.test.ts @@ -43,29 +43,57 @@ test('calc the duration used by junit', () => { test('emits if a test has a syntax error', async () => { const { stdout } = await runVitest({ reporters: 'junit', root }, ['with-syntax-error']) - let xml = stdout + const xml = stabilizeReport(stdout) - // clear timestamp and hostname - xml = xml.replace(/timestamp="[^"]+"/, 'timestamp="TIMESTAMP"') - xml = xml.replace(/hostname="[^"]+"/, 'hostname="HOSTNAME"') - - expect(xml).toContain('') + expect(xml).toContain('') expect(xml).toContain(' when beforeAll/afterAll failed', async () => { - let { stdout } = await runVitest({ reporters: 'junit', root: './fixtures/suite-hook-failure' }) - // reduct non-deterministic output - stdout = stdout.replaceAll(/(timestamp|hostname|time)=".*?"/g, '$1="..."') - expect(stdout).toMatchSnapshot() + const { stdout } = await runVitest({ reporters: 'junit', root: './fixtures/suite-hook-failure' }) + + const xml = stabilizeReport(stdout) + + expect(xml).toMatchSnapshot() }) test('write testsuite name relative to root config', async () => { - let { stdout } = await runVitest({ reporters: 'junit', root: './fixtures/better-testsuite-name' }) - stdout = stdout.replaceAll(/(timestamp|hostname|time)=".*?"/g, '$1="..."') + const { stdout } = await runVitest({ reporters: 'junit', root: './fixtures/better-testsuite-name' }) + + const xml = stabilizeReport(stdout) - const space1 = '' - const space2 = '' - expect(stdout).toContain(space1) - expect(stdout).toContain(space2) + expect(xml).toContain('') + expect(xml).toContain('') }) + +test('options.classname changes classname property', async () => { + const { stdout } = await runVitest({ + reporters: [['junit', { classname: 'some-custom-classname' }]], + root: './fixtures/default', + include: ['a.test.ts'], + }) + + const xml = stabilizeReport(stdout) + + // All classname attributes should have the custom value + expect(xml.match(/ { + const { stdout } = await runVitest({ + reporters: [['junit', { suiteName: 'some-custom-suiteName' }]], + root: './fixtures/default', + include: ['a.test.ts'], + }) + + const xml = stabilizeReport(stdout) + + expect(xml).not.toContain(' { test('JUnit reporter', async () => { // Arrange - const reporter = new JUnitReporter() + const reporter = new JUnitReporter({}) const context = getContext() vi.mock('os', () => ({ @@ -60,7 +60,7 @@ test('JUnit reporter', async () => { test('JUnit reporter (no outputFile entry)', async () => { // Arrange - const reporter = new JUnitReporter() + const reporter = new JUnitReporter({}) const context = getContext() context.vitest.config.outputFile = {} @@ -80,7 +80,7 @@ test('JUnit reporter (no outputFile entry)', async () => { test('JUnit reporter with outputFile', async () => { // Arrange - const reporter = new JUnitReporter() + const reporter = new JUnitReporter({}) const outputFile = resolve('report.xml') const context = getContext() context.vitest.config.outputFile = outputFile @@ -106,7 +106,7 @@ test('JUnit reporter with outputFile', async () => { test('JUnit reporter with outputFile with XML in error message', async () => { // Arrange - const reporter = new JUnitReporter() + const reporter = new JUnitReporter({}) const outputFile = resolve('report_escape_msg_xml.xml') const context = getContext() context.vitest.config.outputFile = outputFile @@ -135,7 +135,7 @@ test('JUnit reporter with outputFile with XML in error message', async () => { test('JUnit reporter with outputFile object', async () => { // Arrange - const reporter = new JUnitReporter() + const reporter = new JUnitReporter({}) const outputFile = resolve('report_object.xml') const context = getContext() context.vitest.config.outputFile = { @@ -163,7 +163,7 @@ test('JUnit reporter with outputFile object', async () => { test('JUnit reporter with outputFile in non-existing directory', async () => { // Arrange - const reporter = new JUnitReporter() + const reporter = new JUnitReporter({}) const rootDirectory = resolve('junitReportDirectory') const outputFile = `${rootDirectory}/deeply/nested/report.xml` const context = getContext() @@ -190,7 +190,7 @@ test('JUnit reporter with outputFile in non-existing directory', async () => { test('JUnit reporter with outputFile object in non-existing directory', async () => { // Arrange - const reporter = new JUnitReporter() + const reporter = new JUnitReporter({}) const rootDirectory = resolve('junitReportDirectory_object') const outputFile = `${rootDirectory}/deeply/nested/report.xml` const context = getContext() @@ -219,7 +219,7 @@ test('JUnit reporter with outputFile object in non-existing directory', async () test('json reporter', async () => { // Arrange - const reporter = new JsonReporter() + const reporter = new JsonReporter({}) const context = getContext() vi.setSystemTime(1642587001759) @@ -234,7 +234,7 @@ test('json reporter', async () => { test('json reporter (no outputFile entry)', async () => { // Arrange - const reporter = new JsonReporter() + const reporter = new JsonReporter({}) const context = getContext() context.vitest.config.outputFile = {} @@ -250,7 +250,7 @@ test('json reporter (no outputFile entry)', async () => { test('json reporter with outputFile', async () => { // Arrange - const reporter = new JsonReporter() + const reporter = new JsonReporter({}) const outputFile = resolve('report.json') const context = getContext() context.vitest.config.outputFile = outputFile @@ -272,7 +272,7 @@ test('json reporter with outputFile', async () => { test('json reporter with outputFile object', async () => { // Arrange - const reporter = new JsonReporter() + const reporter = new JsonReporter({}) const outputFile = resolve('report_object.json') const context = getContext() context.vitest.config.outputFile = { @@ -296,7 +296,7 @@ test('json reporter with outputFile object', async () => { test('json reporter with outputFile in non-existing directory', async () => { // Arrange - const reporter = new JsonReporter() + const reporter = new JsonReporter({}) const rootDirectory = resolve('jsonReportDirectory') const outputFile = `${rootDirectory}/deeply/nested/report.json` const context = getContext() @@ -319,7 +319,7 @@ test('json reporter with outputFile in non-existing directory', async () => { test('json reporter with outputFile object in non-existing directory', async () => { // Arrange - const reporter = new JsonReporter() + const reporter = new JsonReporter({}) const rootDirectory = resolve('jsonReportDirectory_object') const outputFile = `${rootDirectory}/deeply/nested/report.json` const context = getContext() diff --git a/test/reporters/tests/utils.test.ts b/test/reporters/tests/utils.test.ts index 35951cc7bdea..c502e5feb1d0 100644 --- a/test/reporters/tests/utils.test.ts +++ b/test/reporters/tests/utils.test.ts @@ -24,21 +24,21 @@ describe('Reporter Utils', () => { }) test('passing the name of a single built-in reporter returns a new instance', async () => { - const promisedReporters = await createReporters(['default'], ctx) + const promisedReporters = await createReporters([['default', {}]], ctx) expect(promisedReporters).toHaveLength(1) const reporter = promisedReporters[0] expect(reporter).toBeInstanceOf(DefaultReporter) }) test('passing in the path to a custom reporter returns a new instance', async () => { - const promisedReporters = await createReporters(([customReporterPath]), ctx) + const promisedReporters = await createReporters(([[customReporterPath, {}]]), ctx) expect(promisedReporters).toHaveLength(1) const customReporter = promisedReporters[0] expect(customReporter).toBeInstanceOf(TestReporter) }) test('passing in a mix of built-in and custom reporters works', async () => { - const promisedReporters = await createReporters(['default', customReporterPath], ctx) + const promisedReporters = await createReporters([['default', {}], [customReporterPath, {}]], ctx) expect(promisedReporters).toHaveLength(2) const defaultReporter = promisedReporters[0] expect(defaultReporter).toBeInstanceOf(DefaultReporter) diff --git a/test/reporters/vitest.config.ts b/test/reporters/vitest.config.ts index 60be5378bbe7..ba37dda9faf5 100644 --- a/test/reporters/vitest.config.ts +++ b/test/reporters/vitest.config.ts @@ -7,5 +7,9 @@ export default defineConfig({ chaiConfig: { truncateThreshold: 0, }, + typecheck: { + enabled: true, + include: ['./tests/configuration-options.test-d.ts'], + }, }, })