mirror of
https://github.com/dorny/test-reporter.git
synced 2026-02-01 02:45:22 -08:00
119 lines
3.3 KiB
TypeScript
119 lines
3.3 KiB
TypeScript
import {ParseOptions, TestParser} from '../../test-parser'
|
|
import {
|
|
TestCaseError,
|
|
TestCaseResult,
|
|
TestExecutionResult,
|
|
TestGroupResult,
|
|
TestRunResult,
|
|
TestSuiteResult
|
|
} from '../../test-results'
|
|
import {getExceptionSource} from '../../utils/node-utils'
|
|
import {getBasePath, normalizeFilePath} from '../../utils/path-utils'
|
|
import {MochaJson, MochaJsonTest} from './mocha-json-types'
|
|
|
|
export class MochaJsonParser implements TestParser {
|
|
assumedWorkDir: string | undefined
|
|
|
|
constructor(readonly options: ParseOptions) {}
|
|
|
|
async parse(path: string, content: string): Promise<TestRunResult> {
|
|
const mocha = this.getMochaJson(path, content)
|
|
const result = this.getTestRunResult(path, mocha)
|
|
result.sort(true)
|
|
return Promise.resolve(result)
|
|
}
|
|
|
|
private getMochaJson(path: string, content: string): MochaJson {
|
|
try {
|
|
return JSON.parse(content)
|
|
} catch (e) {
|
|
throw new Error(`Invalid JSON at ${path}\n\n${e}`)
|
|
}
|
|
}
|
|
|
|
private getTestRunResult(resultsPath: string, mocha: MochaJson): TestRunResult {
|
|
const suitesMap: {[path: string]: TestSuiteResult} = {}
|
|
|
|
const getSuite = (test: MochaJsonTest): TestSuiteResult => {
|
|
const path = this.getRelativePath(test.file)
|
|
return suitesMap[path] ?? (suitesMap[path] = new TestSuiteResult(path, []))
|
|
}
|
|
|
|
for (const test of mocha.passes) {
|
|
const suite = getSuite(test)
|
|
this.processTest(suite, test, 'success')
|
|
}
|
|
|
|
for (const test of mocha.failures) {
|
|
const suite = getSuite(test)
|
|
this.processTest(suite, test, 'failed')
|
|
}
|
|
|
|
for (const test of mocha.pending) {
|
|
const suite = getSuite(test)
|
|
this.processTest(suite, test, 'skipped')
|
|
}
|
|
|
|
const suites = Object.values(suitesMap)
|
|
return new TestRunResult(resultsPath, suites, mocha.stats.duration)
|
|
}
|
|
|
|
private processTest(suite: TestSuiteResult, test: MochaJsonTest, result: TestExecutionResult): void {
|
|
const groupName =
|
|
test.fullTitle !== test.title
|
|
? test.fullTitle.substring(0, test.fullTitle.length - test.title.length).trimEnd()
|
|
: null
|
|
|
|
let group = suite.groups.find(grp => grp.name === groupName)
|
|
if (group === undefined) {
|
|
group = new TestGroupResult(groupName, [])
|
|
suite.groups.push(group)
|
|
}
|
|
|
|
const error = this.getTestCaseError(test)
|
|
const testCase = new TestCaseResult(test.title, result, test.duration ?? 0, error)
|
|
group.tests.push(testCase)
|
|
}
|
|
|
|
private getTestCaseError(test: MochaJsonTest): TestCaseError | undefined {
|
|
const details = test.err.stack
|
|
const message = test.err.message
|
|
if (details === undefined) {
|
|
return undefined
|
|
}
|
|
|
|
let path
|
|
let line
|
|
|
|
const src = getExceptionSource(details, this.options.trackedFiles, file => this.getRelativePath(file))
|
|
if (src) {
|
|
path = src.path
|
|
line = src.line
|
|
}
|
|
|
|
return {
|
|
path,
|
|
line,
|
|
message,
|
|
details
|
|
}
|
|
}
|
|
|
|
private getRelativePath(path: string): string {
|
|
path = normalizeFilePath(path)
|
|
const workDir = this.getWorkDir(path)
|
|
if (workDir !== undefined && path.startsWith(workDir)) {
|
|
path = path.substring(workDir.length)
|
|
}
|
|
return path
|
|
}
|
|
|
|
private getWorkDir(path: string): string | undefined {
|
|
return (
|
|
this.options.workDir ??
|
|
this.assumedWorkDir ??
|
|
(this.assumedWorkDir = getBasePath(path, this.options.trackedFiles))
|
|
)
|
|
}
|
|
}
|