Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor JUnitReporter #367

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 36 additions & 46 deletions Sources/XcbeautifyLib/JunitReporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,80 +19,70 @@ package final class JunitReporter {

package init() { }

package func add(line: String) {
// Remove any preceding or excessive spaces
let line = line.trimmingCharacters(in: .whitespacesAndNewlines)

if let groups = FailingTestCaptureGroup.regex.captureGroups(for: line) {
guard let testCase = generateFailingTest(groups: groups) else { return }
// TODO: Delete `line` parameter
package func add(captureGroup: any CaptureGroup, line: String) {
switch captureGroup {
case let group as FailingTestCaptureGroup:
guard let testCase = generateFailingTest(group: group) else { return }
components.append(.failingTest(testCase))
} else if let groups = RestartingTestCaptureGroup.regex.captureGroups(for: line) {
guard let testCase = generateRestartingTest(groups: groups, line: line) else { return }
case let group as RestartingTestCaptureGroup:
guard let testCase = generateRestartingTest(group: group, line: line) else { return }
components.append(.failingTest(testCase))
} else if let groups = TestCasePassedCaptureGroup.regex.captureGroups(for: line) {
guard let testCase = generatePassingTest(groups: groups) else { return }
case let group as TestCasePassedCaptureGroup:
guard let testCase = generatePassingTest(group: group) else { return }
components.append(.testCasePassed(testCase))
} else if let groups = TestCaseSkippedCaptureGroup.regex.captureGroups(for: line) {
guard let testCase = generateSkippedTest(groups: groups) else { return }
case let group as TestCaseSkippedCaptureGroup:
guard let testCase = generateSkippedTest(group: group) else { return }
components.append(.skippedTest(testCase))
} else if let groups = TestSuiteStartCaptureGroup.regex.captureGroups(for: line) {
guard let testStart = generateSuiteStart(groups: groups) else { return }
case let group as TestSuiteStartCaptureGroup:
guard let testStart = generateSuiteStart(group: group) else { return }
components.append(.testSuiteStart(testStart))
} else if let groups = ParallelTestCaseFailedCaptureGroup.regex.captureGroups(for: line) {
guard let testCase = generateParallelFailingTest(groups: groups) else { return }
case let group as ParallelTestCaseFailedCaptureGroup:
guard let testCase = generateParallelFailingTest(group: group) else { return }
parallelComponents.append(.failingTest(testCase))
} else if let groups = ParallelTestCasePassedCaptureGroup.regex.captureGroups(for: line) {
guard let testCase = generatePassingParallelTest(groups: groups) else { return }
case let group as ParallelTestCasePassedCaptureGroup:
guard let testCase = generatePassingParallelTest(group: group) else { return }
parallelComponents.append(.testCasePassed(testCase))
} else if let groups = ParallelTestCaseSkippedCaptureGroup.regex.captureGroups(for: line) {
guard let testCase = generateSkippedParallelTest(groups: groups) else { return }
case let group as ParallelTestCaseSkippedCaptureGroup:
guard let testCase = generateSkippedParallelTest(group: group) else { return }
parallelComponents.append(.testCasePassed(testCase))
} else {
// Not needed for generating a junit report
default:
return
}
}

private func generateFailingTest(groups: [String]) -> TestCase? {
guard let group = FailingTestCaptureGroup(groups: groups) else { return nil }
return TestCase(classname: group.testSuite, name: group.testCase, time: nil, failure: .init(message: "\(group.file) - \(group.reason)"))
private func generateFailingTest(group: FailingTestCaptureGroup) -> TestCase? {
TestCase(classname: group.testSuite, name: group.testCase, time: nil, failure: .init(message: "\(group.file) - \(group.reason)"))
}

// TODO: Delete `line` parameter
private func generateRestartingTest(groups: [String], line: String) -> TestCase? {
guard let group = RestartingTestCaptureGroup(groups: groups) else { return nil }
return TestCase(classname: group.testSuite, name: group.testCase, time: nil, failure: .init(message: line))
private func generateRestartingTest(group: RestartingTestCaptureGroup, line: String) -> TestCase? {
TestCase(classname: group.testSuite, name: group.testCase, time: nil, failure: .init(message: line))
}

private func generateParallelFailingTest(groups: [String]) -> TestCase? {
private func generateParallelFailingTest(group: ParallelTestCaseFailedCaptureGroup) -> TestCase? {
// Parallel tests do not provide meaningful failure messages
guard let group = ParallelTestCaseFailedCaptureGroup(groups: groups) else { return nil }
return TestCase(classname: group.suite, name: group.testCase, time: nil, failure: .init(message: "Parallel test failed"))
TestCase(classname: group.suite, name: group.testCase, time: nil, failure: .init(message: "Parallel test failed"))
}

private func generatePassingTest(groups: [String]) -> TestCase? {
guard let group = TestCasePassedCaptureGroup(groups: groups) else { return nil }
return TestCase(classname: group.suite, name: group.testCase, time: group.time)
private func generatePassingTest(group: TestCasePassedCaptureGroup) -> TestCase? {
TestCase(classname: group.suite, name: group.testCase, time: group.time)
}

private func generateSkippedTest(groups: [String]) -> TestCase? {
guard let group = TestCaseSkippedCaptureGroup(groups: groups) else { return nil }
return TestCase(classname: group.suite, name: group.testCase, time: group.time, skipped: .init(message: nil))
private func generateSkippedTest(group: TestCaseSkippedCaptureGroup) -> TestCase? {
TestCase(classname: group.suite, name: group.testCase, time: group.time, skipped: .init(message: nil))
}

private func generatePassingParallelTest(groups: [String]) -> TestCase? {
guard let group = ParallelTestCasePassedCaptureGroup(groups: groups) else { return nil }
return TestCase(classname: group.suite, name: group.testCase, time: group.time)
private func generatePassingParallelTest(group: ParallelTestCasePassedCaptureGroup) -> TestCase? {
TestCase(classname: group.suite, name: group.testCase, time: group.time)
}

private func generateSkippedParallelTest(groups: [String]) -> TestCase? {
guard let group = ParallelTestCaseSkippedCaptureGroup(groups: groups) else { return nil }
return TestCase(classname: group.suite, name: group.testCase, time: group.time, skipped: .init(message: nil))
private func generateSkippedParallelTest(group: ParallelTestCaseSkippedCaptureGroup) -> TestCase? {
TestCase(classname: group.suite, name: group.testCase, time: group.time, skipped: .init(message: nil))
}

private func generateSuiteStart(groups: [String]) -> String? {
guard let group = TestSuiteStartCaptureGroup(groups: groups) else { return nil }
return group.testSuiteName
private func generateSuiteStart(group: TestSuiteStartCaptureGroup) -> String? {
group.testSuiteName
}

package func generateReport() throws -> Data {
Expand Down
15 changes: 5 additions & 10 deletions Sources/xcbeautify/Xcbeautify.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,6 @@ struct Xcbeautify: ParsableCommand {
let output = OutputHandler(quiet: quiet, quieter: quieter, isCI: isCI) { print($0) }
let junitReporter = JunitReporter()

func readLine() -> String? {
let line = Swift.readLine()
if let line {
if report.contains(.junit) {
junitReporter.add(line: line)
}
}
return line
}

let parser = Parser()

let formatter = XcbeautifyLib.Formatter(
Expand All @@ -114,6 +104,11 @@ struct Xcbeautify: ParsableCommand {

continue
}

if report.contains(.junit) {
junitReporter.add(captureGroup: captureGroup, line: line)
}

guard let formatted = formatter.format(captureGroup: captureGroup) else { continue }
output.write(captureGroup.outputType, formatted)
}
Expand Down
10 changes: 8 additions & 2 deletions Tests/XcbeautifyLibTests/JunitReporterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -398,9 +398,12 @@ class JunitReporterTests: XCTestCase {
"""

func testJunitReport() throws {
let parser = Parser()
let reporter = JunitReporter()
for component in testLog.components(separatedBy: .newlines) {
reporter.add(line: component)
if let group = parser.parse(line: component) {
reporter.add(captureGroup: group, line: component)
}
}
let data = try reporter.generateReport()
let xml = String(data: data, encoding: .utf8)!
Expand Down Expand Up @@ -485,9 +488,12 @@ class JunitReporterTests: XCTestCase {
"""

func testParallelJunitReport() throws {
let parser = Parser()
let reporter = JunitReporter()
for component in parallelTests.components(separatedBy: .newlines) {
reporter.add(line: component)
if let captureGroup = parser.parse(line: component.trimmingCharacters(in: .whitespacesAndNewlines)) {
reporter.add(captureGroup: captureGroup, line: component.trimmingCharacters(in: .whitespacesAndNewlines))
}
}
let data = try reporter.generateReport()
let xml = String(data: data, encoding: .utf8)!
Expand Down
Loading