Skip to content
19 changes: 15 additions & 4 deletions Sources/Testing/Traits/ConditionTrait.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,27 @@ public struct ConditionTrait: TestTrait, SuiteTrait {

/// The source location where this trait is specified.
public var sourceLocation: SourceLocation

public func prepare(for test: Test) async throws {
let result = switch kind {

/// Evaluate this instance's underlying condition.
///
/// - Returns: The result of evaluating this instance's underlying condition.
///
/// The evaluation is performed each time this function is called, and is not
/// cached.
@_spi(Experimental)
public func evaluate() async throws -> Bool {
switch kind {
case let .conditional(condition):
try await condition()
case let .unconditional(unconditionalValue):
unconditionalValue
}
}

public func prepare(for test: Test) async throws {
let isEnabled = try await evaluate()

if !result {
if !isEnabled {
// We don't need to consider including a backtrace here because it will
// primarily contain frames in the testing library, not user code. If an
// error was thrown by a condition evaluated above, the caller _should_
Expand Down
20 changes: 19 additions & 1 deletion Tests/TestingTests/Traits/ConditionTraitTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
//

@testable import Testing
@testable @_spi(Experimental) import Testing

@Suite("Condition Trait Tests", .tags(.traitRelated))
struct ConditionTraitTests {
Expand Down Expand Up @@ -41,4 +41,22 @@ struct ConditionTraitTests {
.disabled(if: false)
)
func disabledTraitIf() throws {}

@Test
func evaluateCondition() async throws {
let trueUnconditional = ConditionTrait(kind: .unconditional(true), comments: [], sourceLocation: #_sourceLocation)
let falseUnconditional = ConditionTrait.disabled()
let enabledTrue = ConditionTrait.enabled(if: true)
let enabledFalse = ConditionTrait.enabled(if: false)
var result: Bool

result = try await trueUnconditional.evaluate()
#expect(result)
result = try await falseUnconditional.evaluate()
#expect(!result)
result = try await enabledTrue.evaluate()
#expect(result)
result = try await enabledFalse.evaluate()
#expect(!result)
}
}