Skip to content

SR-1417: Add non-optional overloads of XCTAssertEqual and XCTAssertNo… #2551

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 84 additions & 8 deletions stdlib/public/SDK/XCTest/XCTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ public func XCTAssertFalse(_ expression: @autoclosure () throws -> Boolean, _ me
}
}

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

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

switch result {
case .success:
if expressionValue1Optional != expressionValue2Optional {
let expressionValue1: T = expressionValue1Optional!
let expressionValue2: T = expressionValue2Optional!

if expressionValue1 != expressionValue2 {
// TODO: @auto_string expression1
// TODO: @auto_string expression2

let expressionValueStr1 = "\(expressionValue1Optional)"
let expressionValueStr2 = "\(expressionValue2Optional)"
let expressionValueStr1 = "\(expressionValue1)"
let expressionValueStr2 = "\(expressionValue2)"

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

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

// evaluate each expression exactly once
var expressionValue1Optional: T?
var expressionValue2Optional: T?

let result = _XCTRunThrowableBlock {
expressionValue1Optional = try expression1()
expressionValue2Optional = try expression2()
}

switch result {
case .success:
if expressionValue1Optional != expressionValue2Optional {
// TODO: @auto_string expression1
// TODO: @auto_string expression2

let expressionValueStr1 = "\(expressionValue1Optional)"
let expressionValueStr2 = "\(expressionValue2Optional)"

_XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message, file, line)
}

case .failedWithError(let error):
_XCTRegisterFailure(false, "XCTAssertEqual failed: threw error \"\(error)\"", message, file, line)

case .failedWithException(_, _, let reason):
_XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message, file, line)

case .failedWithUnknownException:
_XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message, file, line)
}
}

// FIXME: Due to <rdar://problem/16768059> we need overrides of XCTAssertEqual for:
// ContiguousArray<T>
// ArraySlice<T>
Expand Down Expand Up @@ -431,7 +469,7 @@ public func XCTAssertEqual<T, U : Equatable>(_ expression1: @autoclosure () thro
}
}

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

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

switch result {
case .success:
if expressionValue1Optional == expressionValue2Optional {
let expressionValue1: T = expressionValue1Optional!
let expressionValue2: T = expressionValue2Optional!

if expressionValue1 == expressionValue2 {
// TODO: @auto_string expression1
// TODO: @auto_string expression2

let expressionValueStr1 = "\(expressionValue1Optional)"
let expressionValueStr2 = "\(expressionValue2Optional)"
let expressionValueStr1 = "\(expressionValue1)"
let expressionValueStr2 = "\(expressionValue2)"

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

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

// evaluate each expression exactly once
var expressionValue1Optional: T?
var expressionValue2Optional: T?

let result = _XCTRunThrowableBlock {
expressionValue1Optional = try expression1()
expressionValue2Optional = try expression2()
}

switch result {
case .success:
if expressionValue1Optional == expressionValue2Optional {
// TODO: @auto_string expression1
// TODO: @auto_string expression2

let expressionValueStr1 = "\(expressionValue1Optional)"
let expressionValueStr2 = "\(expressionValue2Optional)"

_XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message, file, line)
}

case .failedWithError(let error):
_XCTRegisterFailure(false, "XCTAssertNotEqual failed: threw error \"\(error)\"", message, file, line)

case .failedWithException(_, _, let reason):
_XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message, file, line)

case .failedWithUnknownException:
_XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message, file, line)
}
}

// FIXME: Due to <rdar://problem/16768059> we need overrides of XCTAssertNotEqual for:
// ContiguousArray<T>
// ArraySlice<T>
Expand Down
32 changes: 32 additions & 0 deletions validation-test/stdlib/XCTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,38 @@ XCTestTestSuite.test("exceptions") {
expectFalse(testRun.hasSucceeded)
}

XCTestTestSuite.test("XCTAssertEqual/Optional<T>") {
class AssertEqualOptionalTestCase: XCTestCase {
dynamic func test_whenOptionalsAreEqual_passes() {
XCTAssertEqual(Optional(1),Optional(1))
}

dynamic func test_whenOptionalsAreNotEqual_fails() {
XCTAssertEqual(Optional(1),Optional(2))
}
}

let passingTestCase = AssertEqualOptionalTestCase(selector: #selector(AssertEqualOptionalTestCase.test_whenOptionalsAreEqual_passes))
execute(passingTestCase.run)
let passingTestRun = passingTestCase.testRun!
expectEqual(1, passingTestRun.testCaseCount)
expectEqual(1, passingTestRun.executionCount)
expectEqual(0, passingTestRun.failureCount)
expectEqual(0, passingTestRun.unexpectedExceptionCount)
expectEqual(0, passingTestRun.totalFailureCount)
expectTrue(passingTestRun.hasSucceeded)

let failingTestCase = AssertEqualOptionalTestCase(selector: #selector(AssertEqualOptionalTestCase.test_whenOptionalsAreNotEqual_fails))
execute(failingTestCase.run)
let failingTestRun = failingTestCase.testRun!
expectEqual(1, failingTestRun.testCaseCount)
expectEqual(1, failingTestRun.executionCount)
expectEqual(1, failingTestRun.failureCount)
expectEqual(0, failingTestRun.unexpectedExceptionCount)
expectEqual(1, failingTestRun.totalFailureCount)
expectFalse(failingTestRun.hasSucceeded)
}
Copy link
Contributor

@modocache modocache May 16, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to test that your overloads accomplish the stated goal? In other words, could we check the failure message?

I think this is possible by using XCTestObservationCenter:

// pseudocode, not sure if this will work
class MyObserver: XCTestObservation {
  func testCase(_ testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: UInt) {
    expectEqual(description, "XCTAssertEqual failed: (\"1\") is not equal to (\"2\") - ")
  }
}
let observer = MyObserver()
XCTestObservationCenter.center().addTestObserver(observer)
let failingTestCase = AssertEqualOptionalTestCase(selector: #selector(AssertEqualOptionalTestCase.test_whenOptionalsAreNotEqual_fails))
execute(failingTestCase.run)
XCTestObservationCenter.center().removeTestObserver(observer)


XCTestTestSuite.test("XCTAssertEqual/Array<T>") {
class AssertEqualArrayTestCase: XCTestCase {
dynamic func test_whenArraysAreEqual_passes() {
Expand Down