Repository: cpisciotta/xcbeautify
Pull request #233 (2024-01-07 22:42:28)

Refactor Formatting Methods Requiring Raw Input
Each of the formatting methods should have sufficient information from the respective `CaptureGroup` to format without the raw input. This unblocks the effort to introduce a `formatted` method directly on each of the `CaptureGroup`s.

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/cpisciotta/xcbeautify/pull/233?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Charles+Pisciotta) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Comparison is base [(`1a2e8b3`)](https://app.codecov.io/gh/cpisciotta/xcbeautify/commit/1a2e8b3b7d78f4dd039dca8d9b016c73de2ac28d?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Charles+Pisciotta) 83.11% compared to head [(`e57c4f7`)](https://app.codecov.io/gh/cpisciotta/xcbeautify/pull/233?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Charles+Pisciotta) 77.17%.


<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #233      +/-   ##
==========================================
- Coverage   83.11%   77.17%   -5.95%     
==========================================
  Files          14       14              
  Lines        1860     1862       +2     
==========================================
- Hits         1546     1437     -109     
- Misses        314      425     +111     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/cpisciotta/xcbeautify/pull/233?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Charles+Pisciotta).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Charles+Pisciotta).


Patch:
diff --git a/Sources/XcbeautifyLib/CaptureGroups.swift b/Sources/XcbeautifyLib/CaptureGroups.swift
index bd34d4c..3841c51 100644
--- a/Sources/XcbeautifyLib/CaptureGroups.swift
+++ b/Sources/XcbeautifyLib/CaptureGroups.swift
@@ -513,18 +513,21 @@ struct RestartingTestCaptureGroup: CaptureGroup {
     static let outputType: OutputType = .test
 
     /// Regular expression captured groups:
-    /// $1 = test suite + test case
-    /// $2 = test suite
-    /// $3 = test case
-    static let regex = Regex(pattern: #"^Restarting after unexpected exit, crash, or test timeout in (-\[(\w+)\s(\w+)\]|(\w+)\.(\w+)\(\));"#)
+    /// $1 = whole message
+    /// $2 = test suite + test case
+    /// $3 = test suite
+    /// $4 = test case
+    static let regex = Regex(pattern: #"^(Restarting after unexpected exit, crash, or test timeout in (-\[(\w+)\s(\w+)\]|(\w+)\.(\w+)\(\));.*)"#)
 
+    let wholeMessage: String
     let testSuiteAndTestCase: String
     let testSuite: String
     let testCase: String
 
     init?(groups: [String]) {
-        assert(groups.count >= 3)
-        guard let testSuiteAndTestCase = groups[safe: 0], let testSuite = groups[safe: 1], let testCase = groups[safe: 2] else { return nil }
+        assert(groups.count >= 4)
+        guard let wholeMessage = groups[safe: 0], let testSuiteAndTestCase = groups[safe: 1], let testSuite = groups[safe: 2], let testCase = groups[safe: 3] else { return nil }
+        self.wholeMessage = wholeMessage
         self.testSuiteAndTestCase = testSuiteAndTestCase
         self.testSuite = testSuite
         self.testCase = testCase
@@ -805,14 +808,17 @@ struct ParallelTestingStartedCaptureGroup: CaptureGroup {
     static let outputType: OutputType = .test
 
     /// Regular expression captured groups:
-    /// $1 = device
-    static let regex = Regex(pattern: #"^Testing\s+started\s+on\s+'(.*)'"#)
+    /// $1 = whole message
+    /// $2 = device
+    static let regex = Regex(pattern: #"^(Testing\s+started\s+on\s+'(.*)'.*)$"#)
 
+    let wholeMessage: String
     let device: String
 
     init?(groups: [String]) {
-        assert(groups.count >= 1)
-        guard let device = groups[safe: 0] else { return nil }
+        assert(groups.count >= 2)
+        guard let wholeMessage = groups[safe: 0], let device = groups[safe: 1] else { return nil }
+        self.wholeMessage = wholeMessage
         self.device = device
     }
 }
@@ -821,14 +827,17 @@ struct ParallelTestingPassedCaptureGroup: CaptureGroup {
     static let outputType: OutputType = .test
 
     /// Regular expression captured groups:
-    /// $1 = device
-    static let regex = Regex(pattern: #"^Testing\s+passed\s+on\s+'(.*)'"#)
+    /// $1 = whole message
+    /// $2 = device
+    static let regex = Regex(pattern: #"^(Testing\s+passed\s+on\s+'(.*)'.*)$"#)
 
+    let wholeMessage: String
     let device: String
 
     init?(groups: [String]) {
-        assert(groups.count >= 1)
-        guard let device = groups[safe: 0] else { return nil }
+        assert(groups.count >= 2)
+        guard let wholeMessage = groups[safe: 0], let device = groups[safe: 1] else { return nil }
+        self.wholeMessage = wholeMessage
         self.device = device
     }
 }
@@ -837,14 +846,17 @@ struct ParallelTestingFailedCaptureGroup: CaptureGroup {
     static let outputType: OutputType = .nonContextualError
 
     /// Regular expression captured groups:
-    /// $1 = device
-    static let regex = Regex(pattern: #"^Testing\s+failed\s+on\s+'(.*)'"#)
+    /// $1 = whole error
+    /// $2 = device
+    static let regex = Regex(pattern: #"^(Testing\s+failed\s+on\s+'(.*)'.*)$"#)
 
+    let wholeError: String
     let device: String
 
     init?(groups: [String]) {
-        assert(groups.count >= 1)
-        guard let device = groups[safe: 0] else { return nil }
+        assert(groups.count >= 2)
+        guard let wholeError = groups[safe: 0], let device = groups[safe: 1] else { return nil }
+        self.wholeError = wholeError
         self.device = device
     }
 }
@@ -939,15 +951,24 @@ struct PreprocessCaptureGroup: CaptureGroup {
     static let outputType: OutputType = .task
 
     /// Regular expression captured groups:
-    /// $1 = file
-    static let regex = Regex(pattern: #"^Preprocess\s(?:(?:\ |[^ ])*)\s((?:\ |[^ ])*)$"#)
+    /// $1 = file path
+    /// $2 = file
+    /// $3 = target
+    /// $4 = project
+    static let regex = Regex(pattern: #"^Preprocess\s(.*\/(.*\.(?:m|mm|cc|cpp|c|cxx)))\s.*\(in target '(.*)' from project '(.*)'\)"#)
 
+    let filePath: String
     let file: String
+    let target: String
+    let project: String
 
     init?(groups: [String]) {
-        assert(groups.count >= 1)
-        guard let file = groups[safe: 0] else { return nil }
+        assert(groups.count >= 4)
+        guard let filePath = groups[safe: 0], let file = groups[safe: 1], let target = groups[safe: 2], let project = groups[safe: 3] else { return nil }
+        self.filePath = filePath
         self.file = file
+        self.target = target
+        self.project = project
     }
 }
 
@@ -1485,14 +1506,17 @@ struct SymbolReferencedFromCaptureGroup: CaptureGroup {
     static let outputType: OutputType = .error
 
     /// Regular expression captured groups:
-    /// $1 = reference
-    static let regex = Regex(pattern: #"\s+\"(.*)\", referenced from:$"#)
+    /// $1 = wholeError
+    /// $2 = reference
+    static let regex = Regex(pattern: #"(\s+\"(.*)\", referenced from:)$"#)
 
+    let wholeError: String
     let reference: String
 
     init?(groups: [String]) {
-        assert(groups.count >= 1)
-        guard let reference = groups[safe: 0] else { return nil }
+        assert(groups.count >= 2)
+        guard let wholeError = groups[safe: 0], let reference = groups[safe: 1] else { return nil }
+        self.wholeError = wholeError
         self.reference = reference
     }
 }
@@ -1516,16 +1540,19 @@ struct ModuleIncludesErrorCaptureGroup: ErrorCaptureGroup {
 struct UndefinedSymbolLocationCaptureGroup: CaptureGroup {
     static let outputType: OutputType = .warning
     /// Regular expression captured groups:
-    /// $1 = target
-    /// $2 = filename
-    static let regex = Regex(pattern: #".+ in (.+)\((.+)\.o\)$"#)
+    /// $1 = whole warning
+    /// $2 = target
+    /// $3 = filename
+    static let regex = Regex(pattern: #"(.+ in (.+)\((.+)\.o\))$"#)
 
+    let wholeWarning: String
     let target: String
     let filename: String
 
     init?(groups: [String]) {
-        assert(groups.count >= 2)
-        guard let target = groups[safe: 0], let filename = groups[safe: 1] else { return nil }
+        assert(groups.count >= 3)
+        guard let wholeWarning = groups[safe: 0], let target = groups[safe: 1], let filename = groups[safe: 2] else { return nil }
+        self.wholeWarning = wholeWarning
         self.target = target
         self.filename = filename
     }
diff --git a/Sources/XcbeautifyLib/Renderers/GitHubActionsRenderer.swift b/Sources/XcbeautifyLib/Renderers/GitHubActionsRenderer.swift
index aecd976..ec02ad5 100644
--- a/Sources/XcbeautifyLib/Renderers/GitHubActionsRenderer.swift
+++ b/Sources/XcbeautifyLib/Renderers/GitHubActionsRenderer.swift
@@ -63,17 +63,17 @@ struct GitHubActionsRenderer: OutputRendering {
         )
     }
 
-    func formatCompleteError(line: String) -> String {
+    func formatSymbolReferencedFrom(group: SymbolReferencedFromCaptureGroup) -> String {
         outputGitHubActionsLog(
             annotationType: .error,
-            message: line
+            message: group.wholeError
         )
     }
 
-    func formatCompleteWarning(line: String) -> String {
+    func formatUndefinedSymbolLocation(group: UndefinedSymbolLocationCaptureGroup) -> String {
         outputGitHubActionsLog(
             annotationType: .warning,
-            message: line
+            message: group.wholeWarning
         )
     }
 
@@ -160,15 +160,15 @@ struct GitHubActionsRenderer: OutputRendering {
         return Format.indent + testCase + " on '\(device)' (\(time) seconds)"
     }
 
-    func formatParallelTestingFailed(line: String, group: ParallelTestingFailedCaptureGroup) -> String {
+    func formatParallelTestingFailed(group: ParallelTestingFailedCaptureGroup) -> String {
         outputGitHubActionsLog(
             annotationType: .error,
-            message: line
+            message: group.wholeError
         )
     }
 
-    func formatRestartingTest(line: String, group: RestartingTestCaptureGroup) -> String {
-        let message = Format.indent + line
+    func formatRestartingTest(group: RestartingTestCaptureGroup) -> String {
+        let message = Format.indent + group.wholeMessage
         return outputGitHubActionsLog(
             annotationType: .error,
             message: message
diff --git a/Sources/XcbeautifyLib/Renderers/OutputRendering.swift b/Sources/XcbeautifyLib/Renderers/OutputRendering.swift
index fc020ec..5e0c3c7 100644
--- a/Sources/XcbeautifyLib/Renderers/OutputRendering.swift
+++ b/Sources/XcbeautifyLib/Renderers/OutputRendering.swift
@@ -7,8 +7,8 @@ protocol OutputRendering {
 
     func format(testSummary: TestSummary) -> String
 
-    func format(line: String, command: String, pattern: String, arguments: String) -> String?
     func formatAnalyze(group: AnalyzeCaptureGroup) -> String
+    func formatCheckDependencies() -> String
     func formatCleanRemove(group: CleanRemoveCaptureGroup) -> String
     func formatCodeSign(group: CodesignCaptureGroup) -> String
     func formatCodeSignFramework(group: CodesignFrameworkCaptureGroup) -> String
@@ -16,8 +16,6 @@ protocol OutputRendering {
     func formatCompileCommand(group: CompileCommandCaptureGroup) -> String?
     func formatCompileError(group: CompileErrorCaptureGroup, additionalLines: @escaping () -> (String?)) -> String
     func formatCompileWarning(group: CompileWarningCaptureGroup, additionalLines: @escaping () -> (String?)) -> String
-    func formatCompleteError(line: String) -> String
-    func formatCompleteWarning(line: String) -> String
     func formatCopy(group: CopyCaptureGroup) -> String
     func formatCoverageReport(group: GeneratedCoverageReportCaptureGroup) -> String
     func formatCursor(group: CursorCaptureGroup) -> String?
@@ -45,17 +43,19 @@ protocol OutputRendering {
     func formatParallelTestCaseAppKitPassed(group: ParallelTestCaseAppKitPassedCaptureGroup) -> String
     func formatParallelTestCaseFailed(group: ParallelTestCaseFailedCaptureGroup) -> String
     func formatParallelTestCasePassed(group: ParallelTestCasePassedCaptureGroup) -> String
-    func formatParallelTestingFailed(line: String, group: ParallelTestingFailedCaptureGroup) -> String
-    func formatParallelTestingPassed(line: String, group: ParallelTestingPassedCaptureGroup) -> String
-    func formatParallelTestingStarted(line: String, group: ParallelTestingStartedCaptureGroup) -> String
+    func formatParallelTestingFailed(group: ParallelTestingFailedCaptureGroup) -> String
+    func formatParallelTestingPassed(group: ParallelTestingPassedCaptureGroup) -> String
+    func formatParallelTestingStarted(group: ParallelTestingStartedCaptureGroup) -> String
     func formatParallelTestSuiteStarted(group: ParallelTestSuiteStartedCaptureGroup) -> String
     func formatPhaseScriptExecution(group: PhaseScriptExecutionCaptureGroup) -> String
     func formatPhaseSuccess(group: PhaseSuccessCaptureGroup) -> String
+    func formatPreprocess(group: PreprocessCaptureGroup) -> String
     func formatProcessInfoPlist(group: ProcessInfoPlistCaptureGroup) -> String
     func formatProcessPch(group: ProcessPchCaptureGroup) -> String
     func formatProcessPchCommand(group: ProcessPchCommandCaptureGroup) -> String
-    func formatRestartingTest(line: String, group: RestartingTestCaptureGroup) -> String
+    func formatRestartingTest(group: RestartingTestCaptureGroup) -> String
     func formatShellCommand(group: ShellCommandCaptureGroup) -> String?
+    func formatSymbolReferencedFrom(group: SymbolReferencedFromCaptureGroup) -> String
     func formatTargetCommand(command: String, group: TargetCaptureGroup) -> String
     func formatTestCaseMeasured(group: TestCaseMeasuredCaptureGroup) -> String
     func formatTestCasePassed(group: TestCasePassedCaptureGroup) -> String
@@ -69,6 +69,7 @@ protocol OutputRendering {
     func formatTIFFUtil(group: TIFFutilCaptureGroup) -> String?
     func formatTouch(group: TouchCaptureGroup) -> String
     func formatUIFailingTest(group: UIFailingTestCaptureGroup) -> String
+    func formatUndefinedSymbolLocation(group: UndefinedSymbolLocationCaptureGroup) -> String
     func formatWarning(group: GenericWarningCaptureGroup) -> String
     func formatWillNotBeCodesignWarning(group: WillNotBeCodeSignedCaptureGroup) -> String
     func formatWriteAuxiliaryFiles(group: WriteAuxiliaryFilesCaptureGroup) -> String?
@@ -98,7 +99,7 @@ extension OutputRendering {
         case let group as BuildTargetCaptureGroup:
             return formatTargetCommand(command: "Build", group: group)
         case is CheckDependenciesCaptureGroup:
-            return format(line: line, command: "Check Dependencies", pattern: CheckDependenciesCaptureGroup.pattern, arguments: "")
+            return formatCheckDependencies()
         case let group as CheckDependenciesErrorsCaptureGroup:
             return formatError(group: group)
         case let group as ClangErrorCaptureGroup:
@@ -192,11 +193,11 @@ extension OutputRendering {
         case let group as ParallelTestCasePassedCaptureGroup:
             return formatParallelTestCasePassed(group: group)
         case let group as ParallelTestingFailedCaptureGroup:
-            return formatParallelTestingFailed(line: line, group: group)
+            return formatParallelTestingFailed(group: group)
         case let group as ParallelTestingPassedCaptureGroup:
-            return formatParallelTestingPassed(line: line, group: group)
+            return formatParallelTestingPassed(group: group)
         case let group as ParallelTestingStartedCaptureGroup:
-            return formatParallelTestingStarted(line: line, group: group)
+            return formatParallelTestingStarted(group: group)
         case let group as ParallelTestSuiteStartedCaptureGroup:
             return formatParallelTestSuiteStarted(group: group)
         case let group as PbxcpCaptureGroup:
@@ -207,8 +208,8 @@ extension OutputRendering {
             return formatPhaseSuccess(group: group)
         case let group as PodsErrorCaptureGroup:
             return formatError(group: group)
-        case is PreprocessCaptureGroup:
-            return format(line: line, command: "Preprocessing", pattern: pattern, arguments: "$1")
+        case let group as PreprocessCaptureGroup:
+            return formatPreprocess(group: group)
         case let group as ProcessInfoPlistCaptureGroup:
             return formatProcessInfoPlist(group: group)
         case let group as ProcessPchCaptureGroup:
@@ -218,11 +219,11 @@ extension OutputRendering {
         case let group as ProvisioningProfileRequiredCaptureGroup:
             return formatError(group: group)
         case let group as RestartingTestCaptureGroup:
-            return formatRestartingTest(line: line, group: group)
+            return formatRestartingTest(group: group)
         case let group as ShellCommandCaptureGroup:
             return formatShellCommand(group: group)
-        case is SymbolReferencedFromCaptureGroup:
-            return formatCompleteError(line: line)
+        case let group as SymbolReferencedFromCaptureGroup:
+            return formatSymbolReferencedFrom(group: group)
         case let group as TestCaseMeasuredCaptureGroup:
             return formatTestCaseMeasured(group: group)
         case let group as TestCasePassedCaptureGroup:
@@ -247,8 +248,8 @@ extension OutputRendering {
             return formatTouch(group: group)
         case let group as UIFailingTestCaptureGroup:
             return formatUIFailingTest(group: group)
-        case is UndefinedSymbolLocationCaptureGroup:
-            return formatCompleteWarning(line: line)
+        case let group as UndefinedSymbolLocationCaptureGroup:
+            return formatUndefinedSymbolLocation(group: group)
         case let group as WillNotBeCodeSignedCaptureGroup:
             return formatWillNotBeCodesignWarning(group: group)
         case let group as WriteAuxiliaryFilesCaptureGroup:
@@ -265,28 +266,16 @@ extension OutputRendering {
 }
 
 extension OutputRendering {
-    func format(line: String, command: String, pattern: String, arguments: String) -> String? {
-        let template = command.style.Bold + " " + arguments
-
-        guard let formatted = try? NSRegularExpression(pattern: pattern)
-            .stringByReplacingMatches(
-                in: line,
-                range: NSRange(location: 0, length: line.count),
-                withTemplate: template
-            )
-        else {
-            return nil
-        }
-
-        return formatted
-    }
-
     func formatAnalyze(group: AnalyzeCaptureGroup) -> String {
         let filename = group.filename
         let target = group.target
         return colored ? "[\(target.f.Cyan)] \("Analyzing".s.Bold) \(filename)" : "[\(target)] Analyzing \(filename)"
     }
 
+    func formatCheckDependencies() -> String {
+        colored ? "Check Dependencies".style.Bold : "Check Dependencies"
+    }
+
     func formatCleanRemove(group: CleanRemoveCaptureGroup) -> String {
         let directory = group.directory
         return colored ? "\("Cleaning".s.Bold) \(directory)" : "Cleaning \(directory)"
@@ -401,8 +390,8 @@ extension OutputRendering {
         return "Updating " + source
     }
 
-    func formatParallelTestingPassed(line: String, group: ParallelTestingPassedCaptureGroup) -> String {
-        colored ? line.s.Bold.f.Green : line
+    func formatParallelTestingPassed(group: ParallelTestingPassedCaptureGroup) -> String {
+        colored ? group.wholeMessage.s.Bold.f.Green : group.wholeMessage
     }
 
     func formatParallelTestSuiteStarted(group: ParallelTestSuiteStartedCaptureGroup) -> String {
@@ -412,8 +401,8 @@ extension OutputRendering {
         return colored ? heading.s.Bold.f.Cyan : heading
     }
 
-    func formatParallelTestingStarted(line: String, group: ParallelTestingStartedCaptureGroup) -> String {
-        colored ? line.s.Bold.f.Cyan : line
+    func formatParallelTestingStarted(group: ParallelTestingStartedCaptureGroup) -> String {
+        colored ? group.wholeMessage.s.Bold.f.Cyan : group.wholeMessage
     }
 
     func formatPhaseScriptExecution(group: PhaseScriptExecutionCaptureGroup) -> String {
@@ -429,6 +418,12 @@ extension OutputRendering {
         return colored ? "\(phase) Succeeded".s.Bold.f.Green : "\(phase) Succeeded"
     }
 
+    func formatPreprocess(group: PreprocessCaptureGroup) -> String {
+        let target = group.target
+        let file = group.file
+        return colored ? "[\(target.f.Cyan)] \("Preprocess".s.Bold) \(file)" : "[\(target)] Preprocess \(file)"
+    }
+
     func formatProcessInfoPlist(group: ProcessInfoPlistCaptureGroup) -> String {
         let plist = group.filename
 
diff --git a/Sources/XcbeautifyLib/Renderers/TerminalRenderer.swift b/Sources/XcbeautifyLib/Renderers/TerminalRenderer.swift
index 58fa081..11c45df 100644
--- a/Sources/XcbeautifyLib/Renderers/TerminalRenderer.swift
+++ b/Sources/XcbeautifyLib/Renderers/TerminalRenderer.swift
@@ -16,8 +16,8 @@ struct TerminalRenderer: OutputRendering {
         return colored ? Format.indent + TestStatus.fail.foreground.Red + " " + file + ", " + failingReason : Format.indent + TestStatus.fail + " " + file + ", " + failingReason
     }
 
-    func formatRestartingTest(line: String, group: RestartingTestCaptureGroup) -> String {
-        colored ? Format.indent + TestStatus.fail.foreground.Red + " " + line : Format.indent + TestStatus.fail + " " + line
+    func formatRestartingTest(group: RestartingTestCaptureGroup) -> String {
+        colored ? Format.indent + TestStatus.fail.foreground.Red + " " + group.wholeMessage : Format.indent + TestStatus.fail + " " + group.wholeMessage
     }
 
     func formatTestCasePending(group: TestCasePendingCaptureGroup) -> String {
@@ -68,8 +68,8 @@ struct TerminalRenderer: OutputRendering {
         return colored ? Symbol.error + " " + errorMessage.f.Red : Symbol.asciiError + " " + errorMessage
     }
 
-    func formatCompleteError(line: String) -> String {
-        colored ? Symbol.error + " " + line.f.Red : Symbol.asciiError + " " + line
+    func formatSymbolReferencedFrom(group: SymbolReferencedFromCaptureGroup) -> String {
+        colored ? Symbol.error + " " + group.wholeError.f.Red : Symbol.asciiError + " " + group.wholeError
     }
 
     func formatCompileError(group: CompileErrorCaptureGroup, additionalLines: @escaping () -> (String?)) -> String {
@@ -104,8 +104,8 @@ struct TerminalRenderer: OutputRendering {
         return colored ? Symbol.warning + " " + warningMessage.f.Yellow : Symbol.asciiWarning + " " + warningMessage
     }
 
-    func formatCompleteWarning(line: String) -> String {
-        colored ? Symbol.warning + " " + line.f.Yellow : Symbol.asciiWarning + " " + line
+    func formatUndefinedSymbolLocation(group: UndefinedSymbolLocationCaptureGroup) -> String {
+        colored ? Symbol.warning + " " + group.wholeWarning.f.Yellow : Symbol.asciiWarning + " " + group.wholeWarning
     }
 
     func formatCompileWarning(group: CompileWarningCaptureGroup, additionalLines: @escaping () -> (String?)) -> String {
@@ -191,8 +191,8 @@ struct TerminalRenderer: OutputRendering {
         return colored ? Symbol.warning + " " + message.f.Yellow : Symbol.asciiWarning + " " + message
     }
 
-    func formatParallelTestingFailed(line: String, group: ParallelTestingFailedCaptureGroup) -> String {
-        colored ? line.s.Bold.f.Red : line
+    func formatParallelTestingFailed(group: ParallelTestingFailedCaptureGroup) -> String {
+        colored ? group.wholeError.s.Bold.f.Red : group.wholeError
     }
 
     func format(testSummary: TestSummary) -> String {


Test patch:
diff --git a/Tests/XcbeautifyLibTests/RendererTests/GitHubActionsRendererTests.swift b/Tests/XcbeautifyLibTests/RendererTests/GitHubActionsRendererTests.swift
index 093efd6..68476b3 100644
--- a/Tests/XcbeautifyLibTests/RendererTests/GitHubActionsRendererTests.swift
+++ b/Tests/XcbeautifyLibTests/RendererTests/GitHubActionsRendererTests.swift
@@ -39,7 +39,11 @@ final class GitHubActionsRendererTests: XCTestCase {
 
     func testCheckDependenciesErrors() { }
 
-    func testCheckDependencies() { }
+    func testCheckDependencies() {
+        let command = "Check Dependencies"
+        let formatted = logFormatted(command)
+        XCTAssertEqual(formatted, command)
+    }
 
     func testClangError() {
         let formatted = logFormatted("clang: error: linker command failed with exit code 1 (use -v to see invocation)")
@@ -405,7 +409,11 @@ final class GitHubActionsRendererTests: XCTestCase {
         XCTAssertEqual(logFormatted(input), output)
     }
 
-    func testPreprocess() { }
+    func testPreprocess() {
+        let input = "Preprocess /Example/Example/Something.m normal arm64 (in target 'SomeTarget' from project 'SomeProject')"
+        let output = "[SomeTarget] Preprocess Something.m"
+        XCTAssertEqual(logFormatted(input), output)
+    }
 
     func testProcessInfoPlist() {
         let formatted = logFormatted("ProcessInfoPlistFile /Users/admin/Library/Developer/Xcode/DerivedData/xcbeautify-abcd/Build/Products/Debug/Guaka.framework/Versions/A/Resources/Info.plist /Users/admin/xcbeautify/xcbeautify.xcodeproj/Guaka_Info.plist")
diff --git a/Tests/XcbeautifyLibTests/RendererTests/TerminalRendererTests.swift b/Tests/XcbeautifyLibTests/RendererTests/TerminalRendererTests.swift
index 3f8eed5..143abd0 100644
--- a/Tests/XcbeautifyLibTests/RendererTests/TerminalRendererTests.swift
+++ b/Tests/XcbeautifyLibTests/RendererTests/TerminalRendererTests.swift
@@ -35,7 +35,11 @@ final class TerminalRendererTests: XCTestCase {
 
     func testCheckDependenciesErrors() { }
 
-    func testCheckDependencies() { }
+    func testCheckDependencies() {
+        let command = "Check Dependencies"
+        let formatted = noColoredFormatted(command)
+        XCTAssertEqual(formatted, command)
+    }
 
     func testClangError() {
         let formatted = noColoredFormatted("clang: error: linker command failed with exit code 1 (use -v to see invocation)")
@@ -385,7 +389,11 @@ final class TerminalRendererTests: XCTestCase {
         XCTAssertEqual(noColoredFormatted(input), output)
     }
 
-    func testPreprocess() { }
+    func testPreprocess() {
+        let input = "Preprocess /Example/Example/Something.m normal arm64 (in target 'SomeTarget' from project 'SomeProject')"
+        let output = "[SomeTarget] Preprocess Something.m"
+        XCTAssertEqual(noColoredFormatted(input), output)
+    }
 
     func testProcessInfoPlist() {
         let formatted = noColoredFormatted("ProcessInfoPlistFile /Users/admin/Library/Developer/Xcode/DerivedData/xcbeautify-abcd/Build/Products/Debug/Guaka.framework/Versions/A/Resources/Info.plist /Users/admin/xcbeautify/xcbeautify.xcodeproj/Guaka_Info.plist")