From bb63a9f46fc5830e2666715a939e35ecaed40085 Mon Sep 17 00:00:00 2001 From: gormster Date: Fri, 10 Jan 2020 21:58:01 +1100 Subject: [PATCH 1/2] Make XCTAssertEqual with accuracy more generic Equality with accuracy isn't limited to floating point tests. Sometimes integer (or other numeric types) need to be accurate within certain bounds for the purposes of testing. This change allows any numeric type that has magnitude and distance to be used with `XCTAssertEqual(_:_:accuracy:)` and `XCTAssertNotEqual(_:_:accuracy:)`. --- Sources/XCTest/Public/XCTAssert.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/XCTest/Public/XCTAssert.swift b/Sources/XCTest/Public/XCTAssert.swift index dc81cb90b..58e735f95 100644 --- a/Sources/XCTest/Public/XCTAssert.swift +++ b/Sources/XCTest/Public/XCTAssert.swift @@ -171,10 +171,10 @@ public func XCTAssertEqual(_ expression1: @autoclosure () throws - } } -public func XCTAssertEqual(_ expression1: @autoclosure () throws -> T, _ expression2: @autoclosure () throws -> T, accuracy: T, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) { +public func XCTAssertEqual(_ expression1: @autoclosure () throws -> T, _ expression2: @autoclosure () throws -> T, accuracy: T, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) { _XCTEvaluateAssertion(.equalWithAccuracy, message: message(), file: file, line: line) { let (value1, value2) = (try expression1(), try expression2()) - if abs(value1.distance(to: value2)) <= abs(accuracy.distance(to: T(0))) { + if abs(value1.distance(to: value2)) <= abs(accuracy.distance(to: T.zero)) { return .success } else { return .expectedFailure("(\"\(value1)\") is not equal to (\"\(value2)\") +/- (\"\(accuracy)\")") @@ -264,10 +264,10 @@ public func XCTAssertNotEqual(_ expression1: @autoclosure () throw } } -public func XCTAssertNotEqual(_ expression1: @autoclosure () throws -> T, _ expression2: @autoclosure () throws -> T, accuracy: T, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) { +public func XCTAssertNotEqual(_ expression1: @autoclosure () throws -> T, _ expression2: @autoclosure () throws -> T, accuracy: T, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) { _XCTEvaluateAssertion(.notEqualWithAccuracy, message: message(), file: file, line: line) { let (value1, value2) = (try expression1(), try expression2()) - if abs(value1.distance(to: value2)) > abs(accuracy.distance(to: T(0))) { + if abs(value1.distance(to: value2)) > abs(accuracy.distance(to: T.zero)) { return .success } else { return .expectedFailure("(\"\(value1)\") is equal to (\"\(value2)\") +/- (\"\(accuracy)\")") From 612fde824c2d229253edf09e3d3a8ad1a64fa3b0 Mon Sep 17 00:00:00 2001 From: gormster Date: Mon, 13 Jan 2020 17:18:29 +1100 Subject: [PATCH 2/2] Added regression test for generic equal with accuracy Didn't bother changing the name of the test case, though. Seemed like a big change for no real benefit. Also fixed one malformed (though still working) regex in the existing test checks. --- .../NegativeAccuracyTestCase/main.swift | 44 ++++++++++++++++--- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/Tests/Functional/NegativeAccuracyTestCase/main.swift b/Tests/Functional/NegativeAccuracyTestCase/main.swift index 87be1fa56..d98250917 100644 --- a/Tests/Functional/NegativeAccuracyTestCase/main.swift +++ b/Tests/Functional/NegativeAccuracyTestCase/main.swift @@ -9,6 +9,7 @@ #endif // Regression test for https://github.com/apple/swift-corelibs-xctest/pull/7 +// and https://github.com/apple/swift-corelibs-xctest/pull/294 // CHECK: Test Suite 'All tests' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+ // CHECK: Test Suite '.*\.xctest' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+ @@ -21,6 +22,10 @@ class NegativeAccuracyTestCase: XCTestCase { ("test_equalWithAccuracy_fails", test_equalWithAccuracy_fails), ("test_notEqualWithAccuracy_passes", test_notEqualWithAccuracy_passes), ("test_notEqualWithAccuracy_fails", test_notEqualWithAccuracy_fails), + ("test_equalWithAccuracy_int_passes", test_equalWithAccuracy_int_passes), + ("test_equalWithAccuracy_int_fails", test_equalWithAccuracy_int_fails), + ("test_notEqualWithAccuracy_int_passes", test_notEqualWithAccuracy_int_passes), + ("test_notEqualWithAccuracy_int_fails", test_notEqualWithAccuracy_int_fails), ] }() @@ -31,7 +36,7 @@ class NegativeAccuracyTestCase: XCTestCase { } // CHECK: Test Case 'NegativeAccuracyTestCase.test_equalWithAccuracy_fails' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+ -// CHECK: .*[/\\]NegativeAccuracyTestCase[/\\]main.swift:[[@LINE+3]]: error: NegativeAccuracyTestCase.test_equalWithAccuracy_fails : XCTAssertEqual failed: \(\"0\.0\"\) is not equal to \(\"0\.2\"\) \+\/- \(\"-0\.1\"\) - $ +// CHECK: .*[/\\]NegativeAccuracyTestCase[/\\]main.swift:[[@LINE+3]]: error: NegativeAccuracyTestCase.test_equalWithAccuracy_fails : XCTAssertEqual failed: \("0\.0"\) is not equal to \("0\.2"\) \+\/- \("-0\.1"\) - $ // CHECK: Test Case 'NegativeAccuracyTestCase.test_equalWithAccuracy_fails' failed \(\d+\.\d+ seconds\) func test_equalWithAccuracy_fails() { XCTAssertEqual(0, 0.2, accuracy: -0.1) @@ -40,22 +45,49 @@ class NegativeAccuracyTestCase: XCTestCase { // CHECK: Test Case 'NegativeAccuracyTestCase.test_notEqualWithAccuracy_passes' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+ // CHECK: Test Case 'NegativeAccuracyTestCase.test_notEqualWithAccuracy_passes' passed \(\d+\.\d+ seconds\) func test_notEqualWithAccuracy_passes() { - XCTAssertNotEqual(1, 2, accuracy: -0.5) + XCTAssertNotEqual(1.0, 2.0, accuracy: -0.5) } // CHECK: Test Case 'NegativeAccuracyTestCase.test_notEqualWithAccuracy_fails' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+ // CHECK: .*[/\\]NegativeAccuracyTestCase[/\\]main.swift:[[@LINE+3]]: error: NegativeAccuracyTestCase.test_notEqualWithAccuracy_fails : XCTAssertNotEqual failed: \("1\.0"\) is equal to \("2\.0"\) \+/- \("-1\.0"\) - $ // CHECK: Test Case 'NegativeAccuracyTestCase.test_notEqualWithAccuracy_fails' failed \(\d+\.\d+ seconds\) func test_notEqualWithAccuracy_fails() { - XCTAssertNotEqual(1, 2, accuracy: -1) + XCTAssertNotEqual(1.0, 2.0, accuracy: -1.0) } + +// CHECK: Test Case 'NegativeAccuracyTestCase.test_equalWithAccuracy_int_passes' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+ +// CHECK: Test Case 'NegativeAccuracyTestCase.test_equalWithAccuracy_int_passes' passed \(\d+\.\d+ seconds\) + func test_equalWithAccuracy_int_passes() { + XCTAssertEqual(10, 11, accuracy: 1) + } + +// CHECK: Test Case 'NegativeAccuracyTestCase.test_equalWithAccuracy_int_fails' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+ +// CHECK: .*[/\\]NegativeAccuracyTestCase[/\\]main.swift:[[@LINE+3]]: error: NegativeAccuracyTestCase.test_equalWithAccuracy_int_fails : XCTAssertEqual failed: \("10"\) is not equal to \("8"\) \+\/- \("1"\) - $ +// CHECK: Test Case 'NegativeAccuracyTestCase.test_equalWithAccuracy_int_fails' failed \(\d+\.\d+ seconds\) + func test_equalWithAccuracy_int_fails() { + XCTAssertEqual(10, 8, accuracy: 1) + } + +// CHECK: Test Case 'NegativeAccuracyTestCase.test_notEqualWithAccuracy_int_passes' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+ +// CHECK: Test Case 'NegativeAccuracyTestCase.test_notEqualWithAccuracy_int_passes' passed \(\d+\.\d+ seconds\) + func test_notEqualWithAccuracy_int_passes() { + XCTAssertNotEqual(-1, 5, accuracy: 5) + } + +// CHECK: Test Case 'NegativeAccuracyTestCase.test_notEqualWithAccuracy_int_fails' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+ +// CHECK: .*[/\\]NegativeAccuracyTestCase[/\\]main.swift:[[@LINE+3]]: error: NegativeAccuracyTestCase.test_notEqualWithAccuracy_int_fails : XCTAssertNotEqual failed: \("0"\) is equal to \("5"\) \+/- \("5"\) - $ +// CHECK: Test Case 'NegativeAccuracyTestCase.test_notEqualWithAccuracy_int_fails' failed \(\d+\.\d+ seconds\) + func test_notEqualWithAccuracy_int_fails() { + XCTAssertNotEqual(0, 5, accuracy: 5) + } + } // CHECK: Test Suite 'NegativeAccuracyTestCase' failed at \d+-\d+-\d+ \d+:\d+:\d+\.\d+ -// CHECK: \t Executed 4 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds +// CHECK: \t Executed 8 tests, with 4 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds XCTMain([testCase(NegativeAccuracyTestCase.allTests)]) // CHECK: Test Suite '.*\.xctest' failed at \d+-\d+-\d+ \d+:\d+:\d+\.\d+ -// CHECK: \t Executed 4 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds +// CHECK: \t Executed 8 tests, with 4 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds // CHECK: Test Suite 'All tests' failed at \d+-\d+-\d+ \d+:\d+:\d+\.\d+ -// CHECK: \t Executed 4 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds +// CHECK: \t Executed 8 tests, with 4 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds