From be9f4f4ff39c4595313deeebaab8c902606737d5 Mon Sep 17 00:00:00 2001 From: Brian Croom Date: Wed, 4 Aug 2021 15:47:54 -0700 Subject: [PATCH] Merge pull request #325 from egorzhdan/XCTAssertIdentical Implement XCTAssertIdentical & XCTAssertNotIdentical --- Sources/XCTest/Public/XCTAssert.swift | 32 +++++++++++++++++++ .../FailureMessagesTestCase/main.swift | 29 +++++++++++++++-- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/Sources/XCTest/Public/XCTAssert.swift b/Sources/XCTest/Public/XCTAssert.swift index 109f2721a..b77287059 100644 --- a/Sources/XCTest/Public/XCTAssert.swift +++ b/Sources/XCTest/Public/XCTAssert.swift @@ -13,6 +13,8 @@ private enum _XCTAssertion { case equal case equalWithAccuracy + case identical + case notIdentical case greaterThan case greaterThanOrEqual case lessThan @@ -32,6 +34,8 @@ private enum _XCTAssertion { switch(self) { case .equal: return "XCTAssertEqual" case .equalWithAccuracy: return "XCTAssertEqual" + case .identical: return "XCTAssertIdentical" + case .notIdentical: return "XCTAssertNotIdentical" case .greaterThan: return "XCTAssertGreaterThan" case .greaterThanOrEqual: return "XCTAssertGreaterThanOrEqual" case .lessThan: return "XCTAssertLessThan" @@ -206,6 +210,34 @@ public func XCTAssertEqualWithAccuracy(_ expression1: @autoclo XCTAssertEqual(try expression1(), try expression2(), accuracy: accuracy, message(), file: file, line: line) } +private func describe(_ object: AnyObject?) -> String { + return object == nil ? String(describing: object) : String(describing: object!) +} + +/// Asserts that two values are identical. +public func XCTAssertIdentical(_ expression1: @autoclosure () throws -> AnyObject?, _ expression2: @autoclosure () throws -> AnyObject?, _ message: @autoclosure () -> String = "", file: StaticString = #filePath, line: UInt = #line) { + _XCTEvaluateAssertion(.identical, message: message(), file: file, line: line) { + let (value1, value2) = (try expression1(), try expression2()) + if value1 === value2 { + return .success + } else { + return .expectedFailure("(\"\(describe(value1))\") is not identical to (\"\(describe(value2))\")") + } + } +} + +/// Asserts that two values aren't identical. +public func XCTAssertNotIdentical(_ expression1: @autoclosure () throws -> AnyObject?, _ expression2: @autoclosure () throws -> AnyObject?, _ message: @autoclosure () -> String = "", file: StaticString = #filePath, line: UInt = #line) { + _XCTEvaluateAssertion(.notIdentical, message: message(), file: file, line: line) { + let (value1, value2) = (try expression1(), try expression2()) + if value1 !== value2 { + return .success + } else { + return .expectedFailure("(\"\(describe(value1))\") is identical to (\"\(describe(value2))\")") + } + } +} + public func XCTAssertFalse(_ expression: @autoclosure () throws -> Bool, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) { _XCTEvaluateAssertion(.`false`, message: message(), file: file, line: line) { let value = try expression() diff --git a/Tests/Functional/FailureMessagesTestCase/main.swift b/Tests/Functional/FailureMessagesTestCase/main.swift index 73ab06fa0..efd967169 100644 --- a/Tests/Functional/FailureMessagesTestCase/main.swift +++ b/Tests/Functional/FailureMessagesTestCase/main.swift @@ -28,6 +28,8 @@ class FailureMessagesTestCase: XCTestCase { ("testAssertFalse", testAssertFalse), ("testAssertGreaterThan", testAssertGreaterThan), ("testAssertGreaterThanOrEqual", testAssertGreaterThanOrEqual), + ("testAssertIdentical", testAssertIdentical), + ("testAssertNotIdentical", testAssertNotIdentical), ("testAssertLessThan", testAssertLessThan), ("testAssertLessThanOrEqual", testAssertLessThanOrEqual), ("testAssertNil", testAssertNil), @@ -121,6 +123,27 @@ class FailureMessagesTestCase: XCTestCase { XCTAssertGreaterThanOrEqual(-1, 0, "message", file: "test.swift") } +// CHECK: Test Case 'FailureMessagesTestCase.testAssertIdentical' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+ +// CHECK: test.swift:[[@LINE+7]]: error: FailureMessagesTestCase.testAssertIdentical : XCTAssertIdentical failed: \("a"\) is not identical to \("b"\) - message +// CHECK: Test Case 'FailureMessagesTestCase.testAssertIdentical' failed \(\d+\.\d+ seconds\) + func testAssertIdentical() { + let object = XCTestExpectation() + XCTAssertIdentical(object, object) + XCTAssertIdentical(nil, nil) + XCTAssertIdentical(true as AnyObject, true as AnyObject) + XCTAssertIdentical("a" as AnyObject, "b" as AnyObject, "message", file: "test.swift") + } + +// CHECK: Test Case 'FailureMessagesTestCase.testAssertNotIdentical' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+ +// CHECK: test.swift:[[@LINE+6]]: error: FailureMessagesTestCase.testAssertNotIdentical : XCTAssertNotIdentical failed: \("nil"\) is identical to \("nil"\) - message +// CHECK: Test Case 'FailureMessagesTestCase.testAssertNotIdentical' failed \(\d+\.\d+ seconds\) + func testAssertNotIdentical() { + XCTAssertNotIdentical("a" as AnyObject, "b" as AnyObject) + XCTAssertNotIdentical(true as AnyObject, false as AnyObject) + XCTAssertNotIdentical(XCTestExpectation(), XCTestExpectation()) + XCTAssertNotIdentical(nil, nil, "message", file: "test.swift") + } + // CHECK: Test Case 'FailureMessagesTestCase.testAssertLessThan' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+ // CHECK: test.swift:[[@LINE+3]]: error: FailureMessagesTestCase.testAssertLessThan : XCTAssertLessThan failed: \("0"\) is not less than \("0"\) - message // CHECK: Test Case 'FailureMessagesTestCase.testAssertLessThan' failed \(\d+\.\d+ seconds\) @@ -213,11 +236,11 @@ class FailureMessagesTestCase: XCTestCase { } } // CHECK: Test Suite 'FailureMessagesTestCase' failed at \d+-\d+-\d+ \d+:\d+:\d+\.\d+ -// CHECK: \t Executed 24 tests, with 24 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds +// CHECK: \t Executed 26 tests, with 26 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds XCTMain([testCase(FailureMessagesTestCase.allTests)]) // CHECK: Test Suite '.*\.xctest' failed at \d+-\d+-\d+ \d+:\d+:\d+\.\d+ -// CHECK: \t Executed 24 tests, with 24 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds +// CHECK: \t Executed 26 tests, with 26 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 24 tests, with 24 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds +// CHECK: \t Executed 26 tests, with 26 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds