Skip to content

Commit 1e133ab

Browse files
committed
test: Add comprehensive unit tests for AdvancedConsoleOutputRecorder
1 parent a92f12a commit 1e133ab

File tree

1 file changed

+238
-0
lines changed

1 file changed

+238
-0
lines changed
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
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+
@testable @_spi(Experimental) @_spi(ForToolsIntegrationOnly) import Testing
12+
13+
@Suite("Advanced Console Output Recorder Tests")
14+
struct AdvancedConsoleOutputRecorderTests {
15+
final class Stream: TextOutputStream, Sendable {
16+
let buffer = Locked<String>(rawValue: "")
17+
18+
@Sendable func write(_ string: String) {
19+
buffer.withLock {
20+
$0.append(string)
21+
}
22+
}
23+
}
24+
25+
@Test("Recorder initialization with default options")
26+
func recorderInitialization() {
27+
let stream = Stream()
28+
let recorder = Event.AdvancedConsoleOutputRecorder<ABI.HighestVersion>(writingUsing: stream.write)
29+
30+
// Verify the recorder was created successfully and has expected defaults
31+
#expect(recorder.options.base.useANSIEscapeCodes == false) // Default for non-TTY
32+
}
33+
34+
@Test("Recorder initialization with custom options")
35+
func recorderInitializationWithCustomOptions() {
36+
let stream = Stream()
37+
var options = Event.AdvancedConsoleOutputRecorder<ABI.HighestVersion>.Options()
38+
options.base.useANSIEscapeCodes = true
39+
40+
let recorder = Event.AdvancedConsoleOutputRecorder<ABI.HighestVersion>(
41+
options: options,
42+
writingUsing: stream.write
43+
)
44+
45+
// Verify the custom options were applied
46+
#expect(recorder.options.base.useANSIEscapeCodes == true)
47+
}
48+
49+
@Test("Basic event recording produces output")
50+
func basicEventRecording() async {
51+
let stream = Stream()
52+
53+
var configuration = Configuration()
54+
let eventRecorder = Event.AdvancedConsoleOutputRecorder<ABI.HighestVersion>(writingUsing: stream.write)
55+
configuration.eventHandler = { event, context in
56+
eventRecorder.record(event, in: context)
57+
}
58+
59+
// Run a simple test to generate events
60+
await Test(name: "Sample Test") {
61+
#expect(Bool(true))
62+
}.run(configuration: configuration)
63+
64+
let buffer = stream.buffer.rawValue
65+
// Verify that the hierarchical output was generated
66+
#expect(buffer.contains("HIERARCHICAL TEST RESULTS"))
67+
#expect(buffer.contains("Test run started"))
68+
}
69+
70+
@Test("Hierarchical output structure is generated")
71+
func hierarchicalOutputStructure() async {
72+
let stream = Stream()
73+
74+
var configuration = Configuration()
75+
let eventRecorder = Event.AdvancedConsoleOutputRecorder<ABI.HighestVersion>(writingUsing: stream.write)
76+
configuration.eventHandler = { event, context in
77+
eventRecorder.record(event, in: context)
78+
}
79+
80+
// Run tests that will create a hierarchy
81+
await runTest(for: HierarchicalTestSuite.self, configuration: configuration)
82+
83+
let buffer = stream.buffer.rawValue
84+
85+
// Verify hierarchical output headers are generated
86+
#expect(buffer.contains("HIERARCHICAL TEST RESULTS"))
87+
#expect(buffer.contains("completed"))
88+
89+
// Should contain tree structure characters
90+
#expect(buffer.contains("├─") || buffer.contains("╰─") || buffer.contains("┌─"))
91+
}
92+
93+
@Test("Failed test details are properly formatted")
94+
func failedTestDetails() async {
95+
let stream = Stream()
96+
97+
var configuration = Configuration()
98+
let eventRecorder = Event.AdvancedConsoleOutputRecorder<ABI.HighestVersion>(writingUsing: stream.write)
99+
configuration.eventHandler = { event, context in
100+
eventRecorder.record(event, in: context)
101+
}
102+
103+
// Run tests with failures
104+
await runTest(for: FailingTestSuite.self, configuration: configuration)
105+
106+
let buffer = stream.buffer.rawValue
107+
108+
// Verify failure details section is generated
109+
#expect(buffer.contains("FAILED TEST DETAILS"))
110+
111+
// Should show test hierarchy in failure details
112+
#expect(buffer.contains("FailingTestSuite"))
113+
}
114+
115+
@Test("Test statistics are correctly calculated")
116+
func testStatisticsCalculation() async {
117+
let stream = Stream()
118+
119+
var configuration = Configuration()
120+
let eventRecorder = Event.AdvancedConsoleOutputRecorder<ABI.HighestVersion>(writingUsing: stream.write)
121+
configuration.eventHandler = { event, context in
122+
eventRecorder.record(event, in: context)
123+
}
124+
125+
// Run mixed passing and failing tests
126+
await runTest(for: MixedTestSuite.self, configuration: configuration)
127+
128+
let buffer = stream.buffer.rawValue
129+
130+
// Verify that statistics are correctly calculated and displayed
131+
#expect(buffer.contains("completed"))
132+
#expect(buffer.contains("pass:") || buffer.contains("fail:"))
133+
}
134+
135+
@Test("Duration formatting is consistent")
136+
func durationFormatting() async {
137+
let stream = Stream()
138+
139+
var configuration = Configuration()
140+
let eventRecorder = Event.AdvancedConsoleOutputRecorder<ABI.HighestVersion>(writingUsing: stream.write)
141+
configuration.eventHandler = { event, context in
142+
eventRecorder.record(event, in: context)
143+
}
144+
145+
// Run a simple test to generate timing
146+
await Test(name: "Timed Test") {
147+
#expect(Bool(true))
148+
}.run(configuration: configuration)
149+
150+
let buffer = stream.buffer.rawValue
151+
152+
// Should not crash and should generate some output with timing
153+
#expect(!buffer.isEmpty)
154+
#expect(buffer.contains("s")) // Duration formatting should include 's' suffix
155+
}
156+
157+
@Test("Event consolidation works correctly")
158+
func eventConsolidation() async {
159+
let stream = Stream()
160+
161+
var configuration = Configuration()
162+
let eventRecorder = Event.AdvancedConsoleOutputRecorder<ABI.HighestVersion>(writingUsing: stream.write)
163+
configuration.eventHandler = { event, context in
164+
eventRecorder.record(event, in: context)
165+
}
166+
167+
// Run tests to verify the consolidated data structure works
168+
await runTest(for: SimpleTestSuite.self, configuration: configuration)
169+
170+
let buffer = stream.buffer.rawValue
171+
172+
// Basic verification that the recorder processes events without crashing
173+
#expect(!buffer.isEmpty)
174+
#expect(buffer.contains("HIERARCHICAL TEST RESULTS"))
175+
}
176+
}
177+
178+
// MARK: - Test Suites for Testing
179+
180+
@Suite(.hidden)
181+
struct HierarchicalTestSuite {
182+
@Test(.hidden)
183+
func passingTest() {
184+
#expect(Bool(true))
185+
}
186+
187+
@Test(.hidden)
188+
func anotherPassingTest() {
189+
#expect(1 + 1 == 2)
190+
}
191+
192+
@Suite(.hidden)
193+
struct NestedSuite {
194+
@Test(.hidden)
195+
func nestedTest() {
196+
#expect("hello".count == 5)
197+
}
198+
}
199+
}
200+
201+
@Suite(.hidden)
202+
struct FailingTestSuite {
203+
@Test(.hidden)
204+
func failingTest() {
205+
#expect(Bool(false), "This test is designed to fail")
206+
}
207+
208+
@Test(.hidden)
209+
func passingTest() {
210+
#expect(Bool(true))
211+
}
212+
}
213+
214+
@Suite(.hidden)
215+
struct MixedTestSuite {
216+
@Test(.hidden)
217+
func test1() {
218+
#expect(Bool(true))
219+
}
220+
221+
@Test(.hidden)
222+
func test2() {
223+
#expect(Bool(false), "Intentional failure")
224+
}
225+
226+
@Test(.hidden)
227+
func test3() {
228+
#expect(1 == 1)
229+
}
230+
}
231+
232+
@Suite(.hidden)
233+
struct SimpleTestSuite {
234+
@Test(.hidden)
235+
func simpleTest() {
236+
#expect(Bool(true))
237+
}
238+
}

0 commit comments

Comments
 (0)