diff --git a/Sources/Testing/Issues/Issue.swift b/Sources/Testing/Issues/Issue.swift index b70f5b4ea..9f9029459 100644 --- a/Sources/Testing/Issues/Issue.swift +++ b/Sources/Testing/Issues/Issue.swift @@ -175,11 +175,9 @@ extension Issue: CustomStringConvertible, CustomDebugStringConvertible { /// In the future, when our minimum deployment target supports casting a value /// to a constrained existential type ([SE-0353](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0353-constrained-existential-types.md#effect-on-abi-stability)), /// we can remove this protocol and cast to `RangeExpression` instead. -private protocol _RangeExpressionOverIntValues: RangeExpression where Bound == Int {} +private protocol _RangeExpressionOverIntValues: RangeExpression & Sequence where Bound == Int, Element == Int {} extension ClosedRange: _RangeExpressionOverIntValues {} extension PartialRangeFrom: _RangeExpressionOverIntValues {} -extension PartialRangeThrough: _RangeExpressionOverIntValues {} -extension PartialRangeUpTo: _RangeExpressionOverIntValues {} extension Range: _RangeExpressionOverIntValues {} extension Issue.Kind: CustomStringConvertible { @@ -200,9 +198,15 @@ extension Issue.Kind: CustomStringConvertible { } case let .confirmationMiscounted(actual: actual, expected: expected): if let expected = expected as? any _RangeExpressionOverIntValues { - let expected = expected.relative(to: []) - if expected.upperBound > expected.lowerBound && expected.lowerBound == expected.upperBound - 1 { - return "Confirmation was confirmed \(actual.counting("time")), but expected to be confirmed \(expected.lowerBound.counting("time"))" + let lowerBound = expected.first { _ in true } + if let lowerBound { + // Not actually an upper bound, just "any value greater than the lower + // bound." That's sufficient for us to determine if the range contains + // a single value. + let upperBound = expected.first { $0 > lowerBound } + if let upperBound, upperBound > lowerBound && lowerBound == upperBound - 1 { + return "Confirmation was confirmed \(actual.counting("time")), but expected to be confirmed \(lowerBound.counting("time"))" + } } } return "Confirmation was confirmed \(actual.counting("time")), but expected to be confirmed \(String(describingForTest: expected)) time(s)" diff --git a/Tests/TestingTests/ConfirmationTests.swift b/Tests/TestingTests/ConfirmationTests.swift index 7fe824d71..8e4a9b8a7 100644 --- a/Tests/TestingTests/ConfirmationTests.swift +++ b/Tests/TestingTests/ConfirmationTests.swift @@ -47,6 +47,19 @@ struct ConfirmationTests { } } + @Test func confirmationFailureCanBeDescribed() async { + var configuration = Configuration() + configuration.eventHandler = { event, _ in + if case let .issueRecorded(issue) = event.kind { + #expect(String(describing: issue) != "") + } + } + + await Test { + await confirmation(expectedCount: 1...) { _ in } + }.run(configuration: configuration) + } + #if !SWT_NO_EXIT_TESTS @Test("Confirmation requires positive count") func positiveCount() async {