Skip to content

Commit a1f3d98

Browse files
committed
Add testRecordsIssue(matching:) condition
1 parent 99ddc0f commit a1f3d98

File tree

2 files changed

+59
-8
lines changed

2 files changed

+59
-8
lines changed

Sources/Testing/Traits/AttachmentSavingTrait.swift

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,39 @@ public struct AttachmentSavingTrait: TestTrait, SuiteTrait {
4848
Self { $0.hasFailed }
4949
}
5050

51+
/// The testing library saves attachments if the test records a matching
52+
/// issue.
53+
///
54+
/// - Parameters:
55+
/// - issueMatcher: A function to invoke when an issue occurs that is used
56+
/// to determine if the testing library should save attachments for the
57+
/// current test.
58+
///
59+
/// - Returns: An instance of ``AttachmentSavingTrait/Condition`` that
60+
/// evaluates `issueMatcher`.
61+
public static func testRecordsIssue(
62+
matching issueMatcher: @escaping @Sendable (_ issue: Issue) async throws -> Bool
63+
) -> Self {
64+
Self(inspectsIssues: true) { context in
65+
for issue in context.issues {
66+
if try await issueMatcher(issue) {
67+
return true
68+
}
69+
}
70+
return false
71+
}
72+
}
73+
74+
/// Whether or not this condition needs to inspect individual issues (which
75+
/// implies a slower path.)
76+
fileprivate var inspectsIssues = false
77+
5178
/// The condition function.
5279
///
5380
/// - Parameters:
5481
/// - condition: The function to call. The result of this function
5582
/// determines if the condition is satisfied or not.
56-
fileprivate var condition: @Sendable (borrowing Context) async throws -> Bool
83+
fileprivate var body: @Sendable (borrowing Context) async throws -> Bool
5784
}
5885

5986
/// This instance's condition.
@@ -70,7 +97,7 @@ public struct AttachmentSavingTrait: TestTrait, SuiteTrait {
7097
// MARK: - TestScoping
7198

7299
extension AttachmentSavingTrait: TestScoping {
73-
/// A type representing the per-test context for this trait.
100+
/// A type representing the per-test-case context for this trait.
74101
///
75102
/// An instance of this type is created for each scope this trait provides.
76103
/// When the scope ends, the context is then passed to the trait's condition
@@ -79,8 +106,11 @@ extension AttachmentSavingTrait: TestScoping {
79106
/// The set of events that were deferred for later conditional handling.
80107
var deferredEvents = [Event]()
81108

82-
/// Whether or not the current test has recorded a failing issue.
109+
/// Whether or not the current test case has recorded a failing issue.
83110
var hasFailed = false
111+
112+
/// All issues recorded within the scope of the current test case.
113+
var issues = [Issue]()
84114
}
85115

86116
public func scopeProvider(for test: Test, testCase: Test.Case?) -> Self? {
@@ -124,7 +154,14 @@ extension AttachmentSavingTrait: TestScoping {
124154
}
125155

126156
case let .issueRecorded(issue):
127-
if issue.isFailure {
157+
if condition.inspectsIssues {
158+
context.withLock { context in
159+
if issue.isFailure {
160+
context.hasFailed = true
161+
}
162+
context.issues.append(issue)
163+
}
164+
} else if issue.isFailure {
128165
context.withLock { context in
129166
context.hasFailed = true
130167
}
@@ -161,7 +198,7 @@ extension AttachmentSavingTrait: TestScoping {
161198

162199
await Issue.withErrorRecording(at: sourceLocation, configuration: configuration) {
163200
// Evaluate the condition.
164-
guard try await condition.condition(context) else {
201+
guard try await condition.body(context) else {
165202
return
166203
}
167204

Tests/TestingTests/Traits/AttachmentSavingTraitTests.swift

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ struct `AttachmentSavingTrait tests` {
5757
)
5858
}
5959

60+
@Test func `Saving attachments with warning issue`() async throws {
61+
try await runAttachmentSavingTests(
62+
with: .savingAttachments(if: .testRecordsIssue { $0.severity == .warning }),
63+
expectedCount: Self.warningTestCaseCount,
64+
expectedPreferredName: "PASSING TEST"
65+
)
66+
}
67+
6068
@Test func `Saving attachments only on test failure`() async throws {
6169
try await runAttachmentSavingTests(
6270
with: .savingAttachments(if: .testFails),
@@ -108,10 +116,11 @@ struct `AttachmentSavingTrait tests` {
108116
// MARK: - Fixtures
109117

110118
extension `AttachmentSavingTrait tests` {
111-
static let totalTestCaseCount = 1 + 1 + 5 + 7
112-
static let passingTestCaseCount = 1 + 5
119+
static let totalTestCaseCount = passingTestCaseCount + failingTestCaseCount
120+
static let passingTestCaseCount = 1 + 5 + warningTestCaseCount
121+
static let warningTestCaseCount = 1
113122
static let failingTestCaseCount = 1 + 7
114-
static let issueCountFromTestBodies = failingTestCaseCount
123+
static let issueCountFromTestBodies = warningTestCaseCount + failingTestCaseCount
115124

116125
@TaskLocal
117126
static var currentAttachmentSavingTrait: any SuiteTrait = Comment(rawValue: "<no .savingAttachments trait set>")
@@ -122,6 +131,11 @@ extension `AttachmentSavingTrait tests` {
122131
Attachment.record("", named: "PASSING TEST")
123132
}
124133

134+
@Test(.hidden) func `Records an attachment (warning)`() {
135+
Attachment.record("", named: "PASSING TEST")
136+
Issue.record("", severity: .warning)
137+
}
138+
125139
@Test(.hidden) func `Records an attachment (failing)`() {
126140
Attachment.record("", named: "FAILING TEST")
127141
Issue.record("")

0 commit comments

Comments
 (0)