Skip to content

Add ConditionTrait.evaluate() #909

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Mar 28, 2025
20 changes: 15 additions & 5 deletions Sources/Testing/Traits/ConditionTrait.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ public struct ConditionTrait: TestTrait, SuiteTrait {
///
/// - Parameters:
/// - body: The function to call. The result of this function determines
/// if the condition is satisfied or not.
case conditional(_ body: @Sendable () async throws -> Bool)

/// The trait is unconditional and always has the same result.
Expand Down Expand Up @@ -62,16 +61,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
17 changes: 17 additions & 0 deletions Tests/TestingTests/RunnerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,23 @@ final class RunnerTests: XCTestCase {
let test2 = Test(.disabled(if: Bool.random())) { }
XCTAssertTrue(test2.traits.compactMap { $0 as? ConditionTrait }.allSatisfy { !$0.isConstant })
}

func testEvaluateConditionTrait() 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()
XCTAssertTrue(result)
result = try await falseUnconditional.evaluate()
XCTAssertFalse(result)
result = try await enabledTrue.evaluate()
XCTAssertTrue(result)
result = try await enabledFalse.evaluate()
XCTAssertFalse(result)
}

func testGeneratedPlan() async throws {
let tests: [(Any.Type, String)] = [
Expand Down