Skip to content

Commit 956b6b1

Browse files
nsalmoriabriancroom
authored andcommitted
SR-1417: Add non-optional overloads of XCTAssertEqual and XCTAssertNotEqual
Previously, the only version of the functions that accepted values was the one that implicitly wraps them into Optionals. This generated a confusing error message when the assert failed. Having a separate overload that accepts non-optional types ensures that the correct description is printed when the assert fails.
1 parent 56bb5dd commit 956b6b1

File tree

2 files changed

+116
-8
lines changed

2 files changed

+116
-8
lines changed

stdlib/public/SDK/XCTest/XCTest.swift

Lines changed: 84 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ public func XCTAssertFalse(_ expression: @autoclosure () throws -> Boolean, _ me
238238
}
239239
}
240240

241-
public func XCTAssertEqual<T : Equatable>(_ expression1: @autoclosure () throws -> T?, _ expression2: @autoclosure () throws -> T?, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) -> Void {
241+
public func XCTAssertEqual<T : Equatable>(_ expression1: @autoclosure () throws -> T, _ expression2: @autoclosure () throws -> T, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) -> Void {
242242
let assertionType = _XCTAssertionType.equal
243243

244244
// evaluate each expression exactly once
@@ -252,12 +252,15 @@ public func XCTAssertEqual<T : Equatable>(_ expression1: @autoclosure () throws
252252

253253
switch result {
254254
case .success:
255-
if expressionValue1Optional != expressionValue2Optional {
255+
let expressionValue1: T = expressionValue1Optional!
256+
let expressionValue2: T = expressionValue2Optional!
257+
258+
if expressionValue1 != expressionValue2 {
256259
// TODO: @auto_string expression1
257260
// TODO: @auto_string expression2
258261

259-
let expressionValueStr1 = "\(expressionValue1Optional)"
260-
let expressionValueStr2 = "\(expressionValue2Optional)"
262+
let expressionValueStr1 = "\(expressionValue1)"
263+
let expressionValueStr2 = "\(expressionValue2)"
261264

262265
_XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message, file, line)
263266
}
@@ -273,6 +276,41 @@ public func XCTAssertEqual<T : Equatable>(_ expression1: @autoclosure () throws
273276
}
274277
}
275278

279+
public func XCTAssertEqual<T : Equatable>(_ expression1: @autoclosure () throws -> T?, _ expression2: @autoclosure () throws -> T?, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) -> Void {
280+
let assertionType = _XCTAssertionType.equal
281+
282+
// evaluate each expression exactly once
283+
var expressionValue1Optional: T?
284+
var expressionValue2Optional: T?
285+
286+
let result = _XCTRunThrowableBlock {
287+
expressionValue1Optional = try expression1()
288+
expressionValue2Optional = try expression2()
289+
}
290+
291+
switch result {
292+
case .success:
293+
if expressionValue1Optional != expressionValue2Optional {
294+
// TODO: @auto_string expression1
295+
// TODO: @auto_string expression2
296+
297+
let expressionValueStr1 = "\(expressionValue1Optional)"
298+
let expressionValueStr2 = "\(expressionValue2Optional)"
299+
300+
_XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message, file, line)
301+
}
302+
303+
case .failedWithError(let error):
304+
_XCTRegisterFailure(false, "XCTAssertEqual failed: threw error \"\(error)\"", message, file, line)
305+
306+
case .failedWithException(_, _, let reason):
307+
_XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message, file, line)
308+
309+
case .failedWithUnknownException:
310+
_XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message, file, line)
311+
}
312+
}
313+
276314
// FIXME: Due to <rdar://problem/16768059> we need overrides of XCTAssertEqual for:
277315
// ContiguousArray<T>
278316
// ArraySlice<T>
@@ -431,7 +469,7 @@ public func XCTAssertEqual<T, U : Equatable>(_ expression1: @autoclosure () thro
431469
}
432470
}
433471

434-
public func XCTAssertNotEqual<T : Equatable>(_ expression1: @autoclosure () throws -> T?, _ expression2: @autoclosure () throws -> T?, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) -> Void {
472+
public func XCTAssertNotEqual<T : Equatable>(_ expression1: @autoclosure () throws -> T, _ expression2: @autoclosure () throws -> T, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) -> Void {
435473
let assertionType = _XCTAssertionType.notEqual
436474

437475
// evaluate each expression exactly once
@@ -445,12 +483,15 @@ public func XCTAssertNotEqual<T : Equatable>(_ expression1: @autoclosure () thro
445483

446484
switch result {
447485
case .success:
448-
if expressionValue1Optional == expressionValue2Optional {
486+
let expressionValue1: T = expressionValue1Optional!
487+
let expressionValue2: T = expressionValue2Optional!
488+
489+
if expressionValue1 == expressionValue2 {
449490
// TODO: @auto_string expression1
450491
// TODO: @auto_string expression2
451492

452-
let expressionValueStr1 = "\(expressionValue1Optional)"
453-
let expressionValueStr2 = "\(expressionValue2Optional)"
493+
let expressionValueStr1 = "\(expressionValue1)"
494+
let expressionValueStr2 = "\(expressionValue2)"
454495

455496
_XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message, file, line)
456497
}
@@ -466,6 +507,41 @@ public func XCTAssertNotEqual<T : Equatable>(_ expression1: @autoclosure () thro
466507
}
467508
}
468509

510+
public func XCTAssertNotEqual<T : Equatable>(_ expression1: @autoclosure () throws -> T?, _ expression2: @autoclosure () throws -> T?, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) -> Void {
511+
let assertionType = _XCTAssertionType.notEqual
512+
513+
// evaluate each expression exactly once
514+
var expressionValue1Optional: T?
515+
var expressionValue2Optional: T?
516+
517+
let result = _XCTRunThrowableBlock {
518+
expressionValue1Optional = try expression1()
519+
expressionValue2Optional = try expression2()
520+
}
521+
522+
switch result {
523+
case .success:
524+
if expressionValue1Optional == expressionValue2Optional {
525+
// TODO: @auto_string expression1
526+
// TODO: @auto_string expression2
527+
528+
let expressionValueStr1 = "\(expressionValue1Optional)"
529+
let expressionValueStr2 = "\(expressionValue2Optional)"
530+
531+
_XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message, file, line)
532+
}
533+
534+
case .failedWithError(let error):
535+
_XCTRegisterFailure(false, "XCTAssertNotEqual failed: threw error \"\(error)\"", message, file, line)
536+
537+
case .failedWithException(_, _, let reason):
538+
_XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message, file, line)
539+
540+
case .failedWithUnknownException:
541+
_XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message, file, line)
542+
}
543+
}
544+
469545
// FIXME: Due to <rdar://problem/16768059> we need overrides of XCTAssertNotEqual for:
470546
// ContiguousArray<T>
471547
// ArraySlice<T>

validation-test/stdlib/XCTest.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,38 @@ XCTestTestSuite.test("exceptions") {
4444
expectFalse(testRun.hasSucceeded)
4545
}
4646

47+
XCTestTestSuite.test("XCTAssertEqual/Optional<T>") {
48+
class AssertEqualOptionalTestCase: XCTestCase {
49+
dynamic func test_whenOptionalsAreEqual_passes() {
50+
XCTAssertEqual(Optional(1),Optional(1))
51+
}
52+
53+
dynamic func test_whenOptionalsAreNotEqual_fails() {
54+
XCTAssertEqual(Optional(1),Optional(2))
55+
}
56+
}
57+
58+
let passingTestCase = AssertEqualOptionalTestCase(selector: #selector(AssertEqualOptionalTestCase.test_whenOptionalsAreEqual_passes))
59+
execute(passingTestCase.run)
60+
let passingTestRun = passingTestCase.testRun!
61+
expectEqual(1, passingTestRun.testCaseCount)
62+
expectEqual(1, passingTestRun.executionCount)
63+
expectEqual(0, passingTestRun.failureCount)
64+
expectEqual(0, passingTestRun.unexpectedExceptionCount)
65+
expectEqual(0, passingTestRun.totalFailureCount)
66+
expectTrue(passingTestRun.hasSucceeded)
67+
68+
let failingTestCase = AssertEqualOptionalTestCase(selector: #selector(AssertEqualOptionalTestCase.test_whenOptionalsAreNotEqual_fails))
69+
execute(failingTestCase.run)
70+
let failingTestRun = failingTestCase.testRun!
71+
expectEqual(1, failingTestRun.testCaseCount)
72+
expectEqual(1, failingTestRun.executionCount)
73+
expectEqual(1, failingTestRun.failureCount)
74+
expectEqual(0, failingTestRun.unexpectedExceptionCount)
75+
expectEqual(1, failingTestRun.totalFailureCount)
76+
expectFalse(failingTestRun.hasSucceeded)
77+
}
78+
4779
XCTestTestSuite.test("XCTAssertEqual/Array<T>") {
4880
class AssertEqualArrayTestCase: XCTestCase {
4981
dynamic func test_whenArraysAreEqual_passes() {

0 commit comments

Comments
 (0)