Merge pull request #220 from lanza/all

Change typod add_custom_target to add_custom_command
diff --git a/Sources/XCTest/Private/XCPredicateExpectation.swift b/Sources/XCTest/Private/XCPredicateExpectation.swift
index e396e3d..1784db7 100644
--- a/Sources/XCTest/Private/XCPredicateExpectation.swift
+++ b/Sources/XCTest/Private/XCPredicateExpectation.swift
@@ -13,16 +13,16 @@
 
 internal class XCPredicateExpectation: XCTestExpectation {
     internal let predicate: NSPredicate
-    internal let object: AnyObject
+    internal let object: Any?
     internal var timer: Timer?
     internal let handler: XCPredicateExpectationHandler?
     private let evaluationInterval = 0.01
     
-    internal init(predicate: NSPredicate, object: AnyObject, description: String, file: StaticString, line: Int, testCase: XCTestCase, handler: XCPredicateExpectationHandler? = nil) {
+    internal init(predicate: NSPredicate, object: Any? = nil, file: StaticString, line: Int, testCase: XCTestCase, handler: XCPredicateExpectationHandler? = nil) {
         self.predicate = predicate
         self.object = object
         self.handler = handler
-        self.timer = nil
+        let description = "Expect predicate `\(predicate)`" + (object.map { " for object \($0)" } ?? "")
         super.init(description: description, file: file, line: line, testCase: testCase)
     }
     
diff --git a/Sources/XCTest/Public/Asynchronous/XCTestCase+PredicateExpectation.swift b/Sources/XCTest/Public/Asynchronous/XCTestCase+PredicateExpectation.swift
index bebf316..3f4e89e 100644
--- a/Sources/XCTest/Public/Asynchronous/XCTestCase+PredicateExpectation.swift
+++ b/Sources/XCTest/Public/Asynchronous/XCTestCase+PredicateExpectation.swift
@@ -19,7 +19,7 @@
     /// - Parameter predicate: The predicate that will be used to evaluate the
     ///   object.
     /// - Parameter object: The object that is evaluated against the conditions
-    ///   specified by the predicate.
+    ///   specified by the predicate, if any. Default is nil.
     /// - Parameter file: The file name to use in the error message if
     ///   this expectation is not waited for. Default is the file
     ///   containing the call to this method. It is rare to provide this
@@ -33,11 +33,10 @@
     ///   first successful evaluation will fulfill the expectation. If provided,
     ///   the handler can override that behavior which leaves the caller
     ///   responsible for fulfilling the expectation.
-    @discardableResult func expectation(for predicate: NSPredicate, evaluatedWith object: AnyObject, file: StaticString = #file, line: Int = #line, handler: XCPredicateExpectationHandler? = nil) -> XCTestExpectation {
+    @discardableResult func expectation(for predicate: NSPredicate, evaluatedWith object: Any? = nil, file: StaticString = #file, line: Int = #line, handler: XCPredicateExpectationHandler? = nil) -> XCTestExpectation {
         let expectation = XCPredicateExpectation(
             predicate: predicate,
             object: object,
-            description: "Expect `\(predicate)` for object \(object)",
             file: file,
             line: line,
             testCase: self,
diff --git a/Sources/XCTest/Public/XCTestCase+Performance.swift b/Sources/XCTest/Public/XCTestCase+Performance.swift
index 28b736c..88f4df2 100644
--- a/Sources/XCTest/Public/XCTestCase+Performance.swift
+++ b/Sources/XCTest/Public/XCTestCase+Performance.swift
@@ -33,7 +33,7 @@
 
 public extension XCTPerformanceMetric {
     /// Records wall clock time in seconds between `startMeasuring`/`stopMeasuring`.
-    public static let wallClockTime = XCTPerformanceMetric(rawValue: WallClockTimeMetric.name)
+    static let wallClockTime = XCTPerformanceMetric(rawValue: WallClockTimeMetric.name)
 }
 
 /// The following methods are called from within a test method to carry out 
diff --git a/Sources/XCTest/Public/XCTestErrors.swift b/Sources/XCTest/Public/XCTestErrors.swift
index 18014a4..a18af0a 100644
--- a/Sources/XCTest/Public/XCTestErrors.swift
+++ b/Sources/XCTest/Public/XCTestErrors.swift
@@ -36,10 +36,10 @@
 public extension XCTestError {
     /// Indicates that one or more expectations failed to be fulfilled in time
     /// during a call to `waitForExpectations(timeout:handler:)`
-    public static var timeoutWhileWaiting: XCTestError.Code { return .timeoutWhileWaiting }
+    static var timeoutWhileWaiting: XCTestError.Code { return .timeoutWhileWaiting }
 
     /// Indicates that a test assertion failed while waiting for expectations
     /// during a call to `waitForExpectations(timeout:handler:)`
     /// FIXME: swift-corelibs-xctest does not currently produce this error code.
-    public static var failureWhileWaiting: XCTestError.Code { return .failureWhileWaiting }
+    static var failureWhileWaiting: XCTestError.Code { return .failureWhileWaiting }
 }
diff --git a/Tests/Functional/Asynchronous/Predicates/Expectations/main.swift b/Tests/Functional/Asynchronous/Predicates/Expectations/main.swift
index 346a06b..dfc06a3 100644
--- a/Tests/Functional/Asynchronous/Predicates/Expectations/main.swift
+++ b/Tests/Functional/Asynchronous/Predicates/Expectations/main.swift
@@ -13,66 +13,100 @@
 
 // CHECK: Test Suite 'PredicateExpectationsTestCase' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+
 class PredicateExpectationsTestCase: XCTestCase {
-    // CHECK: Test Case 'PredicateExpectationsTestCase.test_immediatelyTruePredicateAndObject_passes' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+
-    // CHECK: Test Case 'PredicateExpectationsTestCase.test_immediatelyTruePredicateAndObject_passes' passed \(\d+\.\d+ seconds\)
-    func test_immediatelyTruePredicateAndObject_passes() {
+    // CHECK: Test Case 'PredicateExpectationsTestCase.test_immediatelyTruePredicate_passes' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+
+    // CHECK: Test Case 'PredicateExpectationsTestCase.test_immediatelyTruePredicate_passes' passed \(\d+\.\d+ seconds\)
+    func test_immediatelyTruePredicate_passes() {
         let predicate = NSPredicate(value: true)
-        let object = NSObject()
-        expectation(for: predicate, evaluatedWith: object)
+        expectation(for: predicate)
         waitForExpectations(timeout: 0.1)
     }
 
-    // CHECK: Test Case 'PredicateExpectationsTestCase.test_immediatelyFalsePredicateAndObject_fails' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+
-    // CHECK: .*/Tests/Functional/Asynchronous/Predicates/Expectations/main.swift:[[@LINE+6]]: error: PredicateExpectationsTestCase.test_immediatelyFalsePredicateAndObject_fails : Asynchronous wait failed - Exceeded timeout of 0.1 seconds, with unfulfilled expectations: Expect `<NSPredicate: 0x[0-9A-Fa-f]{1,16}>` for object <NSObject: 0x[0-9A-Fa-f]{1,16}>
-    // CHECK: Test Case 'PredicateExpectationsTestCase.test_immediatelyFalsePredicateAndObject_fails' failed \(\d+\.\d+ seconds\)
-    func test_immediatelyFalsePredicateAndObject_fails() {
+    // CHECK: Test Case 'PredicateExpectationsTestCase.test_immediatelyFalsePredicate_fails' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+
+    // CHECK: .*/Tests/Functional/Asynchronous/Predicates/Expectations/main.swift:[[@LINE+5]]: error: PredicateExpectationsTestCase.test_immediatelyFalsePredicate_fails : Asynchronous wait failed - Exceeded timeout of 0.1 seconds, with unfulfilled expectations: Expect predicate `<NSPredicate: 0x[0-9A-Fa-f]{1,16}>`
+    // CHECK: Test Case 'PredicateExpectationsTestCase.test_immediatelyFalsePredicate_fails' failed \(\d+\.\d+ seconds\)
+    func test_immediatelyFalsePredicate_fails() {
         let predicate = NSPredicate(value: false)
-        let object = NSObject()
-        expectation(for: predicate, evaluatedWith: object)
+        expectation(for: predicate)
         waitForExpectations(timeout: 0.1)
     }
 
-    // CHECK: Test Case 'PredicateExpectationsTestCase.test_delayedTruePredicateAndObject_passes' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+
-    // CHECK: Test Case 'PredicateExpectationsTestCase.test_delayedTruePredicateAndObject_passes' passed \(\d+\.\d+ seconds\)
-    func test_delayedTruePredicateAndObject_passes() {
+    // CHECK: Test Case 'PredicateExpectationsTestCase.test_delayedTruePredicate_passes' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+
+    // CHECK: Test Case 'PredicateExpectationsTestCase.test_delayedTruePredicate_passes' passed \(\d+\.\d+ seconds\)
+    func test_delayedTruePredicate_passes() {
         var didEvaluate = false
         let predicate = NSPredicate(block: { evaluatedObject, bindings in
+            XCTAssertNil(evaluatedObject)
             defer { didEvaluate = true }
             return didEvaluate
         })
-        expectation(for: predicate, evaluatedWith: NSObject())
+        expectation(for: predicate)
         waitForExpectations(timeout: 0.1)
     }
     
-    // CHECK: Test Case 'PredicateExpectationsTestCase.test_immediatelyTrueDelayedFalsePredicateAndObject_passes' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+
-    // CHECK: Test Case 'PredicateExpectationsTestCase.test_immediatelyTrueDelayedFalsePredicateAndObject_passes' passed \(\d+\.\d+ seconds\)
-    func test_immediatelyTrueDelayedFalsePredicateAndObject_passes() {
+    // CHECK: Test Case 'PredicateExpectationsTestCase.test_immediatelyTrueDelayedFalsePredicate_passes' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+
+    // CHECK: Test Case 'PredicateExpectationsTestCase.test_immediatelyTrueDelayedFalsePredicate_passes' passed \(\d+\.\d+ seconds\)
+    func test_immediatelyTrueDelayedFalsePredicate_passes() {
         var didEvaluate = false
         let predicate = NSPredicate(block: { evaluatedObject, bindings in
+            XCTAssertNil(evaluatedObject)
             defer { didEvaluate = true }
             return !didEvaluate
         })
-        expectation(for: predicate, evaluatedWith: NSObject())
+        expectation(for: predicate)
         XCTAssertTrue(didEvaluate)
         
         waitForExpectations(timeout: 0.1)
     }
+
+    // CHECK: Test Case 'PredicateExpectationsTestCase.test_blockPredicateWithNilObject_passes' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+
+    // CHECK: Test Case 'PredicateExpectationsTestCase.test_blockPredicateWithNilObject_passes' passed \(\d+\.\d+ seconds\)
+    func test_blockPredicateWithNilObject_passes() {
+        var flag = false
+        let predicate = NSPredicate(block: { _, _ in
+            return flag
+        })
+        expectation(for: predicate, evaluatedWith: nil)
+        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
+            flag = true
+        }
+        waitForExpectations(timeout: 1)
+        XCTAssertTrue(flag)
+    }
+
+    // CHECK: Test Case 'PredicateExpectationsTestCase.test_blockPredicateWithObject_passes' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+
+    // CHECK: Test Case 'PredicateExpectationsTestCase.test_blockPredicateWithObject_passes' passed \(\d+\.\d+ seconds\)
+    func test_blockPredicateWithObject_passes() {
+        class Foo { var x = false }
+        let foo = Foo()
+        let predicate = NSPredicate(block: { evaluatedObject, _ in
+            guard let object = evaluatedObject as? Foo else { return false }
+            return object.x
+        })
+        expectation(for: predicate, evaluatedWith: foo)
+        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
+            foo.x = true
+        }
+        waitForExpectations(timeout: 1)
+        XCTAssertTrue(foo.x)
+    }
     
     static var allTests = {
         return [
-                   ("test_immediatelyTruePredicateAndObject_passes", test_immediatelyTruePredicateAndObject_passes),
-                   ("test_immediatelyFalsePredicateAndObject_fails", test_immediatelyFalsePredicateAndObject_fails),
-                   ("test_delayedTruePredicateAndObject_passes", test_delayedTruePredicateAndObject_passes),
-                   ("test_immediatelyTrueDelayedFalsePredicateAndObject_passes", test_immediatelyTrueDelayedFalsePredicateAndObject_passes),
+                   ("test_immediatelyTruePredicate_passes", test_immediatelyTruePredicate_passes),
+                   ("test_immediatelyFalsePredicate_fails", test_immediatelyFalsePredicate_fails),
+                   ("test_delayedTruePredicate_passes", test_delayedTruePredicate_passes),
+                   ("test_immediatelyTrueDelayedFalsePredicate_passes", test_immediatelyTrueDelayedFalsePredicate_passes),
+                   ("test_blockPredicateWithNilObject_passes", test_blockPredicateWithNilObject_passes),
+                   ("test_blockPredicateWithObject_passes", test_blockPredicateWithObject_passes),
         ]
     }()
 }
 
 // CHECK: Test Suite 'PredicateExpectationsTestCase' failed at \d+-\d+-\d+ \d+:\d+:\d+\.\d+
-// CHECK: \t Executed 4 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: \t Executed 6 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
 XCTMain([testCase(PredicateExpectationsTestCase.allTests)])
 
 // CHECK: Test Suite '.*\.xctest' failed at \d+-\d+-\d+ \d+:\d+:\d+\.\d+
-// CHECK: \t Executed 4 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: \t Executed 6 tests, with 1 failure \(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 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: \t Executed 6 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
diff --git a/Tests/Functional/Asynchronous/Predicates/Handler/main.swift b/Tests/Functional/Asynchronous/Predicates/Handler/main.swift
index 813f24f..128a781 100644
--- a/Tests/Functional/Asynchronous/Predicates/Handler/main.swift
+++ b/Tests/Functional/Asynchronous/Predicates/Handler/main.swift
@@ -24,7 +24,7 @@
         waitForExpectations(timeout: 0.1)
     }
     // CHECK: Test Case 'PredicateHandlerTestCase.test_predicateIsTrue_handlerReturnsFalse_fails' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+
-    // CHECK: .*/Tests/Functional/Asynchronous/Predicates/Handler/main.swift:[[@LINE+8]]: error: PredicateHandlerTestCase.test_predicateIsTrue_handlerReturnsFalse_fails : Asynchronous wait failed - Exceeded timeout of 0.1 seconds, with unfulfilled expectations: Expect `<NSPredicate: 0x[0-9a-fA-F]{1,16}>` for object <NSObject: 0x[0-9a-fA-F]{1,16}>
+    // CHECK: .*/Tests/Functional/Asynchronous/Predicates/Handler/main.swift:[[@LINE+8]]: error: PredicateHandlerTestCase.test_predicateIsTrue_handlerReturnsFalse_fails : Asynchronous wait failed - Exceeded timeout of 0.1 seconds, with unfulfilled expectations: Expect predicate `<NSPredicate: 0x[0-9a-fA-F]{1,16}>` for object <NSObject: 0x[0-9a-fA-F]{1,16}>
     // CHECK: Test Case 'PredicateHandlerTestCase.test_predicateIsTrue_handlerReturnsFalse_fails' failed \(\d+\.\d+ seconds\)
     func test_predicateIsTrue_handlerReturnsFalse_fails() {
         let predicate = NSPredicate(value: true)
@@ -36,7 +36,7 @@
     }
     
     // CHECK: Test Case 'PredicateHandlerTestCase.test_predicateIsTrueAfterTimeout_handlerIsNotCalled_fails' started at \d+-\d+-\d+ \d+:\d+:\d+\.\d+
-    // CHECK: .*/Tests/Functional/Asynchronous/Predicates/Handler/main.swift:[[@LINE+14]]: error: PredicateHandlerTestCase.test_predicateIsTrueAfterTimeout_handlerIsNotCalled_fails : Asynchronous wait failed - Exceeded timeout of 0.1 seconds, with unfulfilled expectations: Expect `<NSPredicate: 0x[0-9a-fA-F]{1,16}>` for object \d{4}-\d{2}-\d{2} \d+:\d+:\d+ \+\d+
+    // CHECK: .*/Tests/Functional/Asynchronous/Predicates/Handler/main.swift:[[@LINE+14]]: error: PredicateHandlerTestCase.test_predicateIsTrueAfterTimeout_handlerIsNotCalled_fails : Asynchronous wait failed - Exceeded timeout of 0.1 seconds, with unfulfilled expectations: Expect predicate `<NSPredicate: 0x[0-9a-fA-F]{1,16}>` for object \d{4}-\d{2}-\d{2} \d+:\d+:\d+ \+\d+
     // CHECK: Test Case 'PredicateHandlerTestCase.test_predicateIsTrueAfterTimeout_handlerIsNotCalled_fails' failed \(\d+\.\d+ seconds\)
     func test_predicateIsTrueAfterTimeout_handlerIsNotCalled_fails() {
         let halfSecLaterDate = NSDate(timeIntervalSinceNow: 0.2)