diff --git a/Sources/Testing/Traits/ConditionTrait.swift b/Sources/Testing/Traits/ConditionTrait.swift index 7efef95a7..a3b98c99d 100644 --- a/Sources/Testing/Traits/ConditionTrait.swift +++ b/Sources/Testing/Traits/ConditionTrait.swift @@ -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_ diff --git a/Tests/TestingTests/Traits/ConditionTraitTests.swift b/Tests/TestingTests/Traits/ConditionTraitTests.swift index 5d70c8e87..6b5311202 100644 --- a/Tests/TestingTests/Traits/ConditionTraitTests.swift +++ b/Tests/TestingTests/Traits/ConditionTraitTests.swift @@ -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 { @@ -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) + } }