Skip to content

Commit 862937a

Browse files
authored
Avoid hanging trying to diff Data and similar collections. (#1644)
This PR suppresses our diffing logic for collections with element types `Int8` or `UInt8`. The output is not currently useful for these types. Resolves rdar://173002947. ### Checklist: - [x] Code and documentation should follow the style of the [Style Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md). - [x] If public symbols are renamed or modified, DocC references should be updated.
1 parent 983efcd commit 862937a

2 files changed

Lines changed: 48 additions & 0 deletions

File tree

Sources/Testing/Expectations/ExpectationChecking+Macro.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,34 @@ public func __checkBinaryOperation(
664664
)
665665
}
666666

667+
/// Check that an expectation has passed after a condition has been evaluated
668+
/// and throw an error if it failed.
669+
///
670+
/// This overload is necessary because collections whose elements are of type
671+
/// `UInt8` or `Int8` tend to be raw data and diffing them can be very slow
672+
/// while also not producing useful, readable output.
673+
///
674+
/// - Warning: This function is used to implement the `#expect()` and
675+
/// `#require()` macros. Do not call it directly.
676+
public func __checkBinaryOperation<T, U>(
677+
_ lhs: T, _ op: (T, () -> U) -> Bool, _ rhs: @autoclosure () -> U,
678+
expression: __Expression,
679+
comments: @autoclosure () -> [Comment],
680+
isRequired: Bool,
681+
sourceLocation: SourceLocation
682+
) -> Result<Void, any Error> where T: Collection, U: Collection, T.Element == U.Element, T.Element: BinaryInteger, T.Element.Magnitude == UInt8 {
683+
let (condition, rhs) = _callBinaryOperator(lhs, op, rhs)
684+
return __checkValue(
685+
condition,
686+
expression: expression,
687+
expressionWithCapturedRuntimeValues: expression.capturingRuntimeValues(condition, lhs, rhs),
688+
difference: nil,
689+
comments: comments(),
690+
isRequired: isRequired,
691+
sourceLocation: sourceLocation
692+
)
693+
}
694+
667695
/// Check that an expectation has passed after a condition has been evaluated
668696
/// and throw an error if it failed.
669697
///

Tests/TestingTests/IssueTests.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,6 +1284,26 @@ final class IssueTests: XCTestCase {
12841284
}.run(configuration: configuration)
12851285
}
12861286

1287+
func testCollectionDifferenceSkippedForByteCollections() async {
1288+
var configuration = Configuration()
1289+
configuration.eventHandler = { event, _ in
1290+
guard case let .issueRecorded(issue) = event.kind else {
1291+
return
1292+
}
1293+
guard case let .expectationFailed(expectation) = issue.kind else {
1294+
XCTFail("Unexpected issue kind \(issue.kind)")
1295+
return
1296+
}
1297+
XCTAssertNil(expectation.differenceDescription)
1298+
}
1299+
1300+
await Test {
1301+
let lhs = [1, 2, 3] as [UInt8]
1302+
let rhs = [4, 5, 6] as [UInt8]
1303+
#expect(lhs == rhs)
1304+
}.run(configuration: configuration)
1305+
}
1306+
12871307
func testCollectionDifferenceSkippedForRanges() async {
12881308
var configuration = Configuration()
12891309
configuration.eventHandler = { event, _ in

0 commit comments

Comments
 (0)