fix(reporter): use default error formatter for JUnit (#5629)

This commit is contained in:
Hiroshi Ogawa 2024-04-29 20:22:56 +09:00 committed by GitHub
parent eeaebff1fe
commit 200609ccfd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 188 additions and 390 deletions

View File

@ -1,5 +1,6 @@
/* eslint-disable prefer-template */
import { existsSync, readFileSync } from 'node:fs'
import { Writable } from 'node:stream'
import { normalize, relative } from 'pathe'
import c from 'picocolors'
import cliTruncate from 'cli-truncate'
@ -13,7 +14,7 @@ import { TypeCheckError } from '../typecheck/typechecker'
import { isPrimitive } from '../utils'
import type { Vitest } from './core'
import { divider } from './reporters/renderers/utils'
import type { Logger } from './logger'
import { Logger } from './logger'
import type { WorkspaceProject } from './workspace'
interface PrintErrorOptions {
@ -27,6 +28,26 @@ interface PrintErrorResult {
nearest?: ParsedStack
}
// use Logger with custom Console to capture entire error printing
export async function captuerPrintError(
error: unknown,
ctx: Vitest,
project: WorkspaceProject,
) {
let output = ''
const writable = new Writable({
write(chunk, _encoding, callback) {
output += String(chunk)
callback()
},
})
const result = await printError(error, project, {
showCodeFrame: false,
logger: new Logger(ctx, writable, writable),
})
return { nearest: result?.nearest, output }
}
export async function printError(error: unknown, project: WorkspaceProject | undefined, options: PrintErrorOptions): Promise<PrintErrorResult | undefined> {
const { showCodeFrame = true, fullStack = false, type } = options
const logger = options.logger

View File

@ -1,10 +1,8 @@
import { Writable } from 'node:stream'
import { getTasks } from '@vitest/runner/utils'
import stripAnsi from 'strip-ansi'
import type { File, Reporter, Vitest } from '../../types'
import { getFullName } from '../../utils'
import { printError } from '../error'
import { Logger } from '../logger'
import { captuerPrintError } from '../error'
import type { WorkspaceProject } from '../workspace'
export class GithubActionsReporter implements Reporter {
@ -44,7 +42,7 @@ export class GithubActionsReporter implements Reporter {
// format errors via `printError`
for (const { project, title, error } of projectErrors) {
const result = await printErrorWrapper(error, this.ctx, project)
const result = await captuerPrintError(error, this.ctx, project)
const stack = result?.nearest
if (!stack)
continue
@ -63,23 +61,6 @@ export class GithubActionsReporter implements Reporter {
}
}
// use Logger with custom Console to extract messgage from `processError` util
// TODO: maybe refactor `processError` to require single function `(message: string) => void` instead of full Logger?
async function printErrorWrapper(error: unknown, ctx: Vitest, project: WorkspaceProject) {
let output = ''
const writable = new Writable({
write(chunk, _encoding, callback) {
output += String(chunk)
callback()
},
})
const result = await printError(error, project, {
showCodeFrame: false,
logger: new Logger(ctx, writable, writable),
})
return { nearest: result?.nearest, output }
}
// workflow command formatting based on
// https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message
// https://github.com/actions/toolkit/blob/f1d9b4b985e6f0f728b4b766db73498403fd5ca3/packages/core/src/command.ts#L80-L85

View File

@ -3,13 +3,12 @@ import { hostname } from 'node:os'
import { dirname, relative, resolve } from 'pathe'
import type { Task } from '@vitest/runner'
import type { ErrorWithDiff } from '@vitest/utils'
import { getSuites } from '@vitest/runner/utils'
import stripAnsi from 'strip-ansi'
import type { Vitest } from '../../node'
import type { Reporter } from '../../types/reporter'
import { parseErrorStacktrace } from '../../utils/source-map'
import { F_POINTER } from '../../utils/figures'
import { getOutputFile } from '../../utils/config-helpers'
import { captuerPrintError } from '../error'
import { IndentedLogger } from './renderers/indented-logger'
export interface JUnitOptions {
@ -140,31 +139,6 @@ export class JUnitReporter implements Reporter {
await this.logger.log(`</${name}>`)
}
async writeErrorDetails(task: Task, error: ErrorWithDiff): Promise<void> {
const errorName = error.name ?? error.nameStr ?? 'Unknown Error'
const errorDetails = `${errorName}: ${error.message}`
// Be sure to escape any XML in the error Details
await this.baseLog(escapeXML(errorDetails))
const project = this.ctx.getProjectByTaskId(task.id)
const stack = parseErrorStacktrace(error, {
getSourceMap: file => project.getBrowserSourceMapModuleById(file),
frameFilter: this.ctx.config.onStackTrace,
})
// TODO: This is same as printStack but without colors. Find a way to reuse code.
for (const frame of stack) {
const path = relative(this.ctx.config.root, frame.file)
await this.baseLog(escapeXML(` ${F_POINTER} ${[frame.method, `${path}:${frame.line}:${frame.column}`].filter(Boolean).join(' ')}`))
// reached at test file, skip the follow stack
if (frame.file in this.ctx.state.filesMap)
break
}
}
async writeLogs(task: Task, type: 'err' | 'out'): Promise<void> {
if (task.logs == null || task.logs.length === 0)
return
@ -205,7 +179,12 @@ export class JUnitReporter implements Reporter {
if (!error)
return
await this.writeErrorDetails(task, error)
const result = await captuerPrintError(
error,
this.ctx,
this.ctx.getProjectByTaskId(task.id),
)
await this.baseLog(escapeXML(stripAnsi(result.output.trim())))
})
}
}

View File

@ -0,0 +1,49 @@
import { afterAll, it, expect } from "vitest";
afterAll(() => {
throwSuite()
})
it('stack', () => {
throwDeep()
})
it('diff', () => {
expect({ hello: 'x' }).toEqual({ hello: 'y' })
})
it('unhandled', () => {
(async () => throwSimple())()
})
it('no name object', () => {
throw { noName: 'hi' };
});
it('string', () => {
throw "hi";
});
it('number', () => {
throw 1234;
});
it('number name object', () => {
throw { name: 1234 };
});
it('xml', () => {
throw new Error('error message that has XML in it <div><input/></div>');
})
function throwDeep() {
throwSimple()
}
function throwSimple() {
throw new Error('throwSimple')
}
function throwSuite() {
throw new Error('throwSuite')
}

View File

@ -1,63 +0,0 @@
import { AssertionError } from 'node:assert'
import type { File, Suite, Task } from 'vitest'
function createSuiteHavingFailedTestWithXmlInError(): File[] {
const file: File = {
id: '1223128da3',
name: 'test/core/test/basic.test.ts',
type: 'suite',
meta: {},
mode: 'run',
filepath: '/vitest/test/core/test/basic.test.ts',
result: { state: 'fail', duration: 145.99284195899963 },
tasks: [],
projectName: '',
}
const suite: Suite = {
id: '',
type: 'suite',
name: 'suite',
mode: 'run',
meta: {},
file,
result: { state: 'pass', duration: 1.90183687210083 },
tasks: [],
projectName: '',
}
const errorWithXml = new AssertionError({
message: 'error message that has XML in it <tag>',
})
errorWithXml.stack = 'Error: error message that has XML in it <tag>\n'
+ ' at /vitest/test/core/test/basic.test.ts:8:32\n'
+ ' at /vitest/test/core/test/<bracket-name>.ts:3:11\n'
+ ' at etc....'
const tasks: Task[] = [
{
id: '123_0',
type: 'test',
name: 'test with xml in error',
mode: 'run',
meta: {},
suite,
fails: undefined,
file,
result: {
state: 'fail',
errors: [errorWithXml],
duration: 2.123123123,
},
context: null as any,
},
]
file.tasks = [suite]
suite.tasks = tasks
return [file]
}
export { createSuiteHavingFailedTestWithXmlInError }

View File

@ -34,3 +34,83 @@ Error: afterAll error
</testsuites>
"
`;
exports[`format error 1`] = `
"<?xml version="1.0" encoding="UTF-8" ?>
<testsuites name="vitest tests" tests="9" failures="8" errors="0" time="...">
<testsuite name="error.test.ts" timestamp="..." hostname="..." tests="9" failures="8" errors="0" skipped="0" time="...">
<testcase classname="error.test.ts" name="stack" time="...">
<failure message="throwSimple" type="Error">
Error: throwSimple
throwSimple error.test.ts:44:9
throwDeep error.test.ts:40:3
error.test.ts:8:3
</failure>
</testcase>
<testcase classname="error.test.ts" name="diff" time="...">
<failure message="expected { hello: &apos;x&apos; } to deeply equal { hello: &apos;y&apos; }" type="AssertionError">
AssertionError: expected { hello: &apos;x&apos; } to deeply equal { hello: &apos;y&apos; }
- Expected
+ Received
Object {
- &quot;hello&quot;: &quot;y&quot;,
+ &quot;hello&quot;: &quot;x&quot;,
}
error.test.ts:12:26
</failure>
</testcase>
<testcase classname="error.test.ts" name="unhandled" time="...">
</testcase>
<testcase classname="error.test.ts" name="no name object" time="...">
<failure>
{
noName: &apos;hi&apos;,
expected: &apos;undefined&apos;,
actual: &apos;undefined&apos;,
stacks: []
}
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { noName: &apos;hi&apos; }
</failure>
</testcase>
<testcase classname="error.test.ts" name="string" time="...">
<failure message="hi">
Unknown Error: hi
</failure>
</testcase>
<testcase classname="error.test.ts" name="number" time="...">
<failure message="1234">
Unknown Error: 1234
</failure>
</testcase>
<testcase classname="error.test.ts" name="number name object" time="...">
<failure type="1234">
{
name: 1234,
nameStr: &apos;1234&apos;,
expected: &apos;undefined&apos;,
actual: &apos;undefined&apos;,
stacks: []
}
</failure>
</testcase>
<testcase classname="error.test.ts" name="xml" time="...">
<failure message="error message that has XML in it &lt;div&gt;&lt;input/&gt;&lt;/div&gt;" type="Error">
Error: error message that has XML in it &lt;div&gt;&lt;input/&gt;&lt;/div&gt;
error.test.ts:36:9
</failure>
</testcase>
<testcase classname="error.test.ts" name="error.test.ts" time="...">
<failure message="throwSuite" type="Error">
Error: throwSuite
throwSuite error.test.ts:48:9
error.test.ts:4:3
</failure>
</testcase>
</testsuite>
</testsuites>
"
`;

View File

@ -2,72 +2,14 @@
exports[`JUnit reporter (no outputFile entry) 1`] = `
"<?xml version="1.0" encoding="UTF-8" ?>
<testsuites name="vitest tests" tests="9" failures="1" errors="0" time="0">
<testsuite name="test/core/test/basic.test.ts" timestamp="2022-01-19T10:10:01.759Z" hostname="hostname" tests="9" failures="1" errors="0" skipped="2" time="0.145992842">
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; inner suite &gt; Math.sqrt()" time="0.001442286">
<failure message="expected 2.23606797749979 to equal 2" type="AssertionError">
AssertionError: expected 2.23606797749979 to equal 2
test/core/test/basic.test.ts:8:32
</failure>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; JSON" time="0.001023711">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; async with timeout" time="0">
<skipped/>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; timeout" time="0.1005059841">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback setup success " time="0.020184875">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback test success " time="0.0003324542">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback setup success done(false)" time="0.019738606">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback test success done(false)" time="0.0001923509">
<system-err>
[33merror[39m
</system-err>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; todo test" time="0">
<skipped/>
</testcase>
</testsuite>
<testsuites name="vitest tests" tests="0" failures="0" errors="0" time="0">
</testsuites>
"
`;
exports[`JUnit reporter 1`] = `
"<?xml version="1.0" encoding="UTF-8" ?>
<testsuites name="vitest tests" tests="9" failures="1" errors="0" time="0">
<testsuite name="test/core/test/basic.test.ts" timestamp="2022-01-19T10:10:01.759Z" hostname="hostname" tests="9" failures="1" errors="0" skipped="2" time="0.145992842">
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; inner suite &gt; Math.sqrt()" time="0.001442286">
<failure message="expected 2.23606797749979 to equal 2" type="AssertionError">
AssertionError: expected 2.23606797749979 to equal 2
test/core/test/basic.test.ts:8:32
</failure>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; JSON" time="0.001023711">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; async with timeout" time="0">
<skipped/>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; timeout" time="0.1005059841">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback setup success " time="0.020184875">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback test success " time="0.0003324542">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback setup success done(false)" time="0.019738606">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback test success done(false)" time="0.0001923509">
<system-err>
[33merror[39m
</system-err>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; todo test" time="0">
<skipped/>
</testcase>
</testsuite>
<testsuites name="vitest tests" tests="0" failures="0" errors="0" time="0">
</testsuites>
"
`;
@ -79,36 +21,7 @@ exports[`JUnit reporter with outputFile 1`] = `
exports[`JUnit reporter with outputFile 2`] = `
"<?xml version="1.0" encoding="UTF-8" ?>
<testsuites name="vitest tests" tests="9" failures="1" errors="0" time="0">
<testsuite name="test/core/test/basic.test.ts" timestamp="2022-01-19T10:10:01.759Z" hostname="hostname" tests="9" failures="1" errors="0" skipped="2" time="0.145992842">
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; inner suite &gt; Math.sqrt()" time="0.001442286">
<failure message="expected 2.23606797749979 to equal 2" type="AssertionError">
AssertionError: expected 2.23606797749979 to equal 2
test/core/test/basic.test.ts:8:32
</failure>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; JSON" time="0.001023711">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; async with timeout" time="0">
<skipped/>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; timeout" time="0.1005059841">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback setup success " time="0.020184875">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback test success " time="0.0003324542">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback setup success done(false)" time="0.019738606">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback test success done(false)" time="0.0001923509">
<system-err>
[33merror[39m
</system-err>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; todo test" time="0">
<skipped/>
</testcase>
</testsuite>
<testsuites name="vitest tests" tests="0" failures="0" errors="0" time="0">
</testsuites>
"
`;
@ -120,36 +33,7 @@ exports[`JUnit reporter with outputFile in non-existing directory 1`] = `
exports[`JUnit reporter with outputFile in non-existing directory 2`] = `
"<?xml version="1.0" encoding="UTF-8" ?>
<testsuites name="vitest tests" tests="9" failures="1" errors="0" time="0">
<testsuite name="test/core/test/basic.test.ts" timestamp="2022-01-19T10:10:01.759Z" hostname="hostname" tests="9" failures="1" errors="0" skipped="2" time="0.145992842">
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; inner suite &gt; Math.sqrt()" time="0.001442286">
<failure message="expected 2.23606797749979 to equal 2" type="AssertionError">
AssertionError: expected 2.23606797749979 to equal 2
test/core/test/basic.test.ts:8:32
</failure>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; JSON" time="0.001023711">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; async with timeout" time="0">
<skipped/>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; timeout" time="0.1005059841">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback setup success " time="0.020184875">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback test success " time="0.0003324542">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback setup success done(false)" time="0.019738606">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback test success done(false)" time="0.0001923509">
<system-err>
[33merror[39m
</system-err>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; todo test" time="0">
<skipped/>
</testcase>
</testsuite>
<testsuites name="vitest tests" tests="0" failures="0" errors="0" time="0">
</testsuites>
"
`;
@ -161,36 +45,7 @@ exports[`JUnit reporter with outputFile object 1`] = `
exports[`JUnit reporter with outputFile object 2`] = `
"<?xml version="1.0" encoding="UTF-8" ?>
<testsuites name="vitest tests" tests="9" failures="1" errors="0" time="0">
<testsuite name="test/core/test/basic.test.ts" timestamp="2022-01-19T10:10:01.759Z" hostname="hostname" tests="9" failures="1" errors="0" skipped="2" time="0.145992842">
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; inner suite &gt; Math.sqrt()" time="0.001442286">
<failure message="expected 2.23606797749979 to equal 2" type="AssertionError">
AssertionError: expected 2.23606797749979 to equal 2
test/core/test/basic.test.ts:8:32
</failure>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; JSON" time="0.001023711">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; async with timeout" time="0">
<skipped/>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; timeout" time="0.1005059841">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback setup success " time="0.020184875">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback test success " time="0.0003324542">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback setup success done(false)" time="0.019738606">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback test success done(false)" time="0.0001923509">
<system-err>
[33merror[39m
</system-err>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; todo test" time="0">
<skipped/>
</testcase>
</testsuite>
<testsuites name="vitest tests" tests="0" failures="0" errors="0" time="0">
</testsuites>
"
`;
@ -202,57 +57,7 @@ exports[`JUnit reporter with outputFile object in non-existing directory 1`] = `
exports[`JUnit reporter with outputFile object in non-existing directory 2`] = `
"<?xml version="1.0" encoding="UTF-8" ?>
<testsuites name="vitest tests" tests="9" failures="1" errors="0" time="0">
<testsuite name="test/core/test/basic.test.ts" timestamp="2022-01-19T10:10:01.759Z" hostname="hostname" tests="9" failures="1" errors="0" skipped="2" time="0.145992842">
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; inner suite &gt; Math.sqrt()" time="0.001442286">
<failure message="expected 2.23606797749979 to equal 2" type="AssertionError">
AssertionError: expected 2.23606797749979 to equal 2
test/core/test/basic.test.ts:8:32
</failure>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; JSON" time="0.001023711">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; async with timeout" time="0">
<skipped/>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; timeout" time="0.1005059841">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback setup success " time="0.020184875">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback test success " time="0.0003324542">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback setup success done(false)" time="0.019738606">
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; callback test success done(false)" time="0.0001923509">
<system-err>
[33merror[39m
</system-err>
</testcase>
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; todo test" time="0">
<skipped/>
</testcase>
</testsuite>
</testsuites>
"
`;
exports[`JUnit reporter with outputFile with XML in error message 1`] = `
"JUNIT report written to <process-cwd>/report_escape_msg_xml.xml
"
`;
exports[`JUnit reporter with outputFile with XML in error message 2`] = `
"<?xml version="1.0" encoding="UTF-8" ?>
<testsuites name="vitest tests" tests="1" failures="1" errors="0" time="0">
<testsuite name="test/core/test/basic.test.ts" timestamp="2022-01-19T10:10:01.759Z" hostname="hostname" tests="1" failures="1" errors="0" skipped="0" time="0.145992842">
<testcase classname="test/core/test/basic.test.ts" name="suite &gt; test with xml in error" time="0.0021231231">
<failure message="error message that has XML in it &lt;tag&gt;" type="AssertionError">
AssertionError: error message that has XML in it &lt;tag&gt;
test/core/test/basic.test.ts:8:32
test/core/test/&lt;bracket-name&gt;.ts:3:11
</failure>
</testcase>
</testsuite>
<testsuites name="vitest tests" tests="0" failures="0" errors="0" time="0">
</testsuites>
"
`;

View File

@ -57,6 +57,11 @@ test('emits <failure> when beforeAll/afterAll failed', async () => {
expect(xml).toMatchSnapshot()
})
test('format error', async () => {
const { stdout } = await runVitest({ reporters: 'junit', root }, ['error.test.ts'])
expect(stabilizeReport(stdout)).toMatchSnapshot()
})
test('write testsuite name relative to root config', async () => {
const { stdout } = await runVitest({ reporters: 'junit', root: './fixtures/better-testsuite-name' })

View File

@ -1,5 +1,5 @@
import { existsSync, readFileSync, rmSync } from 'node:fs'
import { afterEach, expect, test, vi } from 'vitest'
import { beforeEach, expect, test, vi } from 'vitest'
import { normalize, resolve } from 'pathe'
import { JsonReporter } from '../../../packages/vitest/src/node/reporters/json'
import { JUnitReporter } from '../../../packages/vitest/src/node/reporters/junit'
@ -7,10 +7,16 @@ import { TapReporter } from '../../../packages/vitest/src/node/reporters/tap'
import { TapFlatReporter } from '../../../packages/vitest/src/node/reporters/tap-flat'
import { getContext } from '../src/context'
import { files } from '../src/data'
import { createSuiteHavingFailedTestWithXmlInError } from '../src/data-for-junit'
afterEach(() => {
vi.useRealTimers()
vi.mock('os', () => ({
hostname: () => 'hostname',
}))
beforeEach(() => {
vi.setSystemTime(1642587001759)
return () => {
vi.useRealTimers()
}
})
test('tap reporter', async () => {
@ -44,15 +50,9 @@ test('JUnit reporter', async () => {
const reporter = new JUnitReporter({})
const context = getContext()
vi.mock('os', () => ({
hostname: () => 'hostname',
}))
vi.setSystemTime(1642587001759)
// Act
await reporter.onInit(context.vitest)
await reporter.onFinished(files)
await reporter.onFinished([])
// Assert
expect(context.output).toMatchSnapshot()
@ -64,15 +64,9 @@ test('JUnit reporter (no outputFile entry)', async () => {
const context = getContext()
context.vitest.config.outputFile = {}
vi.mock('os', () => ({
hostname: () => 'hostname',
}))
vi.setSystemTime(1642587001759)
// Act
await reporter.onInit(context.vitest)
await reporter.onFinished(files)
await reporter.onFinished([])
// Assert
expect(context.output).toMatchSnapshot()
@ -85,44 +79,9 @@ test('JUnit reporter with outputFile', async () => {
const context = getContext()
context.vitest.config.outputFile = outputFile
vi.mock('os', () => ({
hostname: () => 'hostname',
}))
vi.setSystemTime(1642587001759)
// Act
await reporter.onInit(context.vitest)
await reporter.onFinished(files)
// Assert
expect(normalizeCwd(context.output)).toMatchSnapshot()
expect(existsSync(outputFile)).toBe(true)
expect(readFileSync(outputFile, 'utf8')).toMatchSnapshot()
// Cleanup
rmSync(outputFile)
})
test('JUnit reporter with outputFile with XML in error message', async () => {
// Arrange
const reporter = new JUnitReporter({})
const outputFile = resolve('report_escape_msg_xml.xml')
const context = getContext()
context.vitest.config.outputFile = outputFile
vi.mock('os', () => ({
hostname: () => 'hostname',
}))
vi.setSystemTime(1642587001759)
// setup suite with failed test with xml
const filesWithTestHavingXmlInError = createSuiteHavingFailedTestWithXmlInError()
// Act
await reporter.onInit(context.vitest)
await reporter.onFinished(filesWithTestHavingXmlInError)
await reporter.onFinished([])
// Assert
expect(normalizeCwd(context.output)).toMatchSnapshot()
@ -142,15 +101,9 @@ test('JUnit reporter with outputFile object', async () => {
junit: outputFile,
}
vi.mock('os', () => ({
hostname: () => 'hostname',
}))
vi.setSystemTime(1642587001759)
// Act
await reporter.onInit(context.vitest)
await reporter.onFinished(files)
await reporter.onFinished([])
// Assert
expect(normalizeCwd(context.output)).toMatchSnapshot()
@ -169,15 +122,9 @@ test('JUnit reporter with outputFile in non-existing directory', async () => {
const context = getContext()
context.vitest.config.outputFile = outputFile
vi.mock('os', () => ({
hostname: () => 'hostname',
}))
vi.setSystemTime(1642587001759)
// Act
await reporter.onInit(context.vitest)
await reporter.onFinished(files)
await reporter.onFinished([])
// Assert
expect(normalizeCwd(context.output)).toMatchSnapshot()
@ -198,15 +145,9 @@ test('JUnit reporter with outputFile object in non-existing directory', async ()
junit: outputFile,
}
vi.mock('os', () => ({
hostname: () => 'hostname',
}))
vi.setSystemTime(1642587001759)
// Act
await reporter.onInit(context.vitest)
await reporter.onFinished(files)
await reporter.onFinished([])
// Assert
expect(normalizeCwd(context.output)).toMatchSnapshot()