Skip to content

Commit 1603000

Browse files
authored
Add experimental AdvancedConsoleOutputRecorder skeleton framework (#1253)
Add experimental AdvancedConsoleOutputRecorder skeleton framework ### Motivation: The current console output for `swift test` is a static log, which presents challenges for developers in understanding test progress and diagnosing failures, especially in large, parallel test suites. This PR introduces the foundational "skeleton" for a new, advanced console reporter to address these issues. The recorder is marked as experimental and must be explicitly enabled via the `SWT_ENABLE_EXPERIMENTAL_CONSOLE_OUTPUT` environment variable, ensuring it doesn't affect existing functionality. ### Modifications: - **Added `Event.AdvancedConsoleOutputRecorder.swift`**: New experimental console output recorder skeleton with: - Basic structure and minimal configuration options - Currently delegates to `Event.ConsoleOutputRecorder` for actual output - Foundation framework ready for future development of advanced features The implementation provides the foundation structure following established patterns in the codebase, ready for future development of advanced console features. ### Checklist: - [x] Code and documentation should follow the style of the [Style Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md). - [x] If public symbols are renamed or modified, DocC references should be updated.
1 parent 2b45ed1 commit 1603000

File tree

3 files changed

+87
-6
lines changed

3 files changed

+87
-6
lines changed

Sources/Testing/ABI/EntryPoints/EntryPoint.swift

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,29 @@ func entryPoint(passing args: __CommandLineArguments_v0?, eventHandler: Event.Ha
5454
#if !SWT_NO_FILE_IO
5555
// Configure the event recorder to write events to stderr.
5656
if configuration.verbosity > .min {
57-
let eventRecorder = Event.ConsoleOutputRecorder(options: .for(.stderr)) { string in
58-
try? FileHandle.stderr.write(string)
59-
}
60-
configuration.eventHandler = { [oldEventHandler = configuration.eventHandler] event, context in
61-
eventRecorder.record(event, in: context)
62-
oldEventHandler(event, context)
57+
// Check for experimental console output flag
58+
if Environment.flag(named: "SWT_ENABLE_EXPERIMENTAL_CONSOLE_OUTPUT") == true {
59+
// Use experimental AdvancedConsoleOutputRecorder
60+
var advancedOptions = Event.AdvancedConsoleOutputRecorder.Options()
61+
advancedOptions.base = .for(.stderr)
62+
63+
let eventRecorder = Event.AdvancedConsoleOutputRecorder(options: advancedOptions) { string in
64+
try? FileHandle.stderr.write(string)
65+
}
66+
67+
configuration.eventHandler = { [oldEventHandler = configuration.eventHandler] event, context in
68+
eventRecorder.record(event, in: context)
69+
oldEventHandler(event, context)
70+
}
71+
} else {
72+
// Use the standard console output recorder (default behavior)
73+
let eventRecorder = Event.ConsoleOutputRecorder(options: .for(.stderr)) { string in
74+
try? FileHandle.stderr.write(string)
75+
}
76+
configuration.eventHandler = { [oldEventHandler = configuration.eventHandler] event, context in
77+
eventRecorder.record(event, in: context)
78+
oldEventHandler(event, context)
79+
}
6380
}
6481
}
6582
#endif

Sources/Testing/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ add_library(Testing
2626
Attachments/Attachment.swift
2727
Events/Clock.swift
2828
Events/Event.swift
29+
Events/Recorder/Event.AdvancedConsoleOutputRecorder.swift
2930
Events/Recorder/Event.ConsoleOutputRecorder.swift
3031
Events/Recorder/Event.HumanReadableOutputRecorder.swift
3132
Events/Recorder/Event.JUnitXMLRecorder.swift
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//
2+
// This source file is part of the Swift.org open source project
3+
//
4+
// Copyright (c) 2025 Apple Inc. and the Swift project authors
5+
// Licensed under Apache License v2.0 with Runtime Library Exception
6+
//
7+
// See https://swift.org/LICENSE.txt for license information
8+
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
//
10+
11+
extension Event {
12+
/// An experimental console output recorder that provides enhanced test result
13+
/// display capabilities.
14+
///
15+
/// This recorder is currently experimental and must be enabled via the
16+
/// `SWT_ENABLE_EXPERIMENTAL_CONSOLE_OUTPUT` environment variable.
17+
struct AdvancedConsoleOutputRecorder: Sendable {
18+
/// Configuration options for the advanced console output recorder.
19+
struct Options: Sendable {
20+
/// Base console output recorder options to inherit from.
21+
var base: Event.ConsoleOutputRecorder.Options
22+
23+
init() {
24+
self.base = Event.ConsoleOutputRecorder.Options()
25+
}
26+
}
27+
28+
/// The options for this recorder.
29+
let options: Options
30+
31+
/// The write function for this recorder.
32+
let write: @Sendable (String) -> Void
33+
34+
/// The fallback console recorder for standard output.
35+
private let _fallbackRecorder: Event.ConsoleOutputRecorder
36+
37+
/// Initialize the advanced console output recorder.
38+
///
39+
/// - Parameters:
40+
/// - options: Configuration options for the recorder.
41+
/// - write: A closure that writes output to its destination.
42+
init(options: Options = Options(), writingUsing write: @escaping @Sendable (String) -> Void) {
43+
self.options = options
44+
self.write = write
45+
self._fallbackRecorder = Event.ConsoleOutputRecorder(options: options.base, writingUsing: write)
46+
}
47+
}
48+
}
49+
50+
extension Event.AdvancedConsoleOutputRecorder {
51+
/// Record an event by processing it and generating appropriate output.
52+
///
53+
/// Currently this is a skeleton implementation that delegates to
54+
/// ``Event/ConsoleOutputRecorder``.
55+
///
56+
/// - Parameters:
57+
/// - event: The event to record.
58+
/// - eventContext: The context associated with the event.
59+
func record(_ event: borrowing Event, in eventContext: borrowing Event.Context) {
60+
// Skeleton implementation: delegate to ConsoleOutputRecorder
61+
_fallbackRecorder.record(event, in: eventContext)
62+
}
63+
}

0 commit comments

Comments
 (0)