From 339f2bb7ba2c471c254a882a2a8a1565fb631ad0 Mon Sep 17 00:00:00 2001 From: Sho Ikeda Date: Fri, 7 Sep 2018 00:21:36 +0900 Subject: [PATCH] Reduce NMBObjCMatcher usages --- Sources/Nimble/Matchers/BeLogical.swift | 11 +++++--- Sources/Nimble/Matchers/Contain.swift | 25 ++++++++++++------- .../Matchers/ContainElementSatisfying.swift | 24 +++++++++--------- Sources/Nimble/Matchers/HaveCount.swift | 23 +++++++++++------ Tests/NimbleTests/objc/ObjCContainTest.m | 9 +++++++ Tests/NimbleTests/objc/ObjCEndWithTest.m | 1 - Tests/NimbleTests/objc/ObjCHaveCountTest.m | 9 +++++++ 7 files changed, 69 insertions(+), 33 deletions(-) diff --git a/Sources/Nimble/Matchers/BeLogical.swift b/Sources/Nimble/Matchers/BeLogical.swift index b703846a6..8df95af80 100644 --- a/Sources/Nimble/Matchers/BeLogical.swift +++ b/Sources/Nimble/Matchers/BeLogical.swift @@ -141,10 +141,13 @@ extension NMBObjCMatcher { } } - @objc public class func beFalseMatcher() -> NMBObjCMatcher { - return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in - let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false } - return try beFalse().matches(expr, failureMessage: failureMessage) + @objc public class func beFalseMatcher() -> NMBMatcher { + return NMBPredicate { actualExpression in + let expr = actualExpression.cast { value -> Bool? in + guard let value = value else { return nil } + return (value as? NSNumber)?.boolValue ?? false + } + return try beFalse().satisfies(expr).toObjectiveC() } } } diff --git a/Sources/Nimble/Matchers/Contain.swift b/Sources/Nimble/Matchers/Contain.swift index cd3096f15..ec755cf72 100644 --- a/Sources/Nimble/Matchers/Contain.swift +++ b/Sources/Nimble/Matchers/Contain.swift @@ -69,8 +69,8 @@ public func contain(_ items: [Any?]) -> Predicate { #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) extension NMBObjCMatcher { - @objc public class func containMatcher(_ expected: [NSObject]) -> NMBObjCMatcher { - return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + @objc public class func containMatcher(_ expected: [NSObject]) -> NMBMatcher { + return NMBPredicate { actualExpression in let location = actualExpression.location let actualValue = try actualExpression.evaluate() if let value = actualValue as? NMBContainer { @@ -78,18 +78,25 @@ extension NMBObjCMatcher { // A straightforward cast on the array causes this to crash, so we have to cast the individual items let expectedOptionals: [Any?] = expected.map({ $0 as Any? }) - return try contain(expectedOptionals).matches(expr, failureMessage: failureMessage) + return try contain(expectedOptionals).satisfies(expr).toObjectiveC() } else if let value = actualValue as? NSString { let expr = Expression(expression: ({ value as String }), location: location) // swiftlint:disable:next force_cast - return try contain(expected as! [String]).matches(expr, failureMessage: failureMessage) - } else if actualValue != nil { - // swiftlint:disable:next line_length - failureMessage.postfixMessage = "contain <\(arrayAsString(expected))> (only works for NSArrays, NSSets, NSHashTables, and NSStrings)" + return try contain(expected as! [String]).satisfies(expr).toObjectiveC() + } + + let message: ExpectationMessage + if actualValue != nil { + message = ExpectationMessage.expectedActualValueTo( + // swiftlint:disable:next line_length + "contain <\(arrayAsString(expected))> (only works for NSArrays, NSSets, NSHashTables, and NSStrings)" + ) } else { - failureMessage.postfixMessage = "contain <\(arrayAsString(expected))>" + message = ExpectationMessage + .expectedActualValueTo("contain <\(arrayAsString(expected))>") + .appendedBeNilHint() } - return false + return NMBPredicateResult(status: .fail, message: message.toObjectiveC()) } } } diff --git a/Sources/Nimble/Matchers/ContainElementSatisfying.swift b/Sources/Nimble/Matchers/ContainElementSatisfying.swift index 8a23a6cf9..827c489be 100644 --- a/Sources/Nimble/Matchers/ContainElementSatisfying.swift +++ b/Sources/Nimble/Matchers/ContainElementSatisfying.swift @@ -26,18 +26,20 @@ public func containElementSatisfying(_ predicate: @escaping ((T) #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) extension NMBObjCMatcher { - @objc public class func containElementSatisfyingMatcher(_ predicate: @escaping ((NSObject) -> Bool)) -> NMBObjCMatcher { - return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + @objc public class func containElementSatisfyingMatcher(_ predicate: @escaping ((NSObject) -> Bool)) -> NMBMatcher { + return NMBPredicate { actualExpression in let value = try actualExpression.evaluate() guard let enumeration = value as? NSFastEnumeration else { - // swiftlint:disable:next line_length - failureMessage.postfixMessage = "containElementSatisfying must be provided an NSFastEnumeration object" - failureMessage.actualValue = nil - failureMessage.expected = "" - failureMessage.to = "" - return false + let message = ExpectationMessage.fail( + "containElementSatisfying must be provided an NSFastEnumeration object" + ) + return NMBPredicateResult(status: .fail, message: message.toObjectiveC()) } + let message = ExpectationMessage + .expectedTo("find object in collection that satisfies predicate") + .toObjectiveC() + var iterator = NSFastEnumerationIterator(enumeration) while let item = iterator.next() { guard let object = item as? NSObject else { @@ -45,13 +47,11 @@ public func containElementSatisfying(_ predicate: @escaping ((T) } if predicate(object) { - return true + return NMBPredicateResult(status: .matches, message: message) } } - failureMessage.actualValue = nil - failureMessage.postfixMessage = "find object in collection that satisfies predicate" - return false + return NMBPredicateResult(status: .doesNotMatch, message: message) } } } diff --git a/Sources/Nimble/Matchers/HaveCount.swift b/Sources/Nimble/Matchers/HaveCount.swift index 1ca29c4d3..59ff4c52e 100644 --- a/Sources/Nimble/Matchers/HaveCount.swift +++ b/Sources/Nimble/Matchers/HaveCount.swift @@ -47,18 +47,27 @@ public func haveCount(_ expectedValue: Int) -> Predicate { #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) extension NMBObjCMatcher { - @objc public class func haveCountMatcher(_ expected: NSNumber) -> NMBObjCMatcher { - return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + @objc public class func haveCountMatcher(_ expected: NSNumber) -> NMBMatcher { + return NMBPredicate { actualExpression in let location = actualExpression.location let actualValue = try actualExpression.evaluate() if let value = actualValue as? NMBCollection { let expr = Expression(expression: ({ value as NMBCollection}), location: location) - return try haveCount(expected.intValue).matches(expr, failureMessage: failureMessage) - } else if let actualValue = actualValue { - failureMessage.postfixMessage = "get type of NSArray, NSSet, NSDictionary, or NSHashTable" - failureMessage.actualValue = "\(String(describing: type(of: actualValue)))" + return try haveCount(expected.intValue).satisfies(expr).toObjectiveC() } - return false + + let message: ExpectationMessage + if let actualValue = actualValue { + message = ExpectationMessage.expectedCustomValueTo( + "get type of NSArray, NSSet, NSDictionary, or NSHashTable", + "\(String(describing: type(of: actualValue)))" + ) + } else { + message = ExpectationMessage + .expectedActualValueTo("have a collection with count \(stringify(expected.intValue))") + .appendedBeNilHint() + } + return NMBPredicateResult(status: .fail, message: message.toObjectiveC()) } } } diff --git a/Tests/NimbleTests/objc/ObjCContainTest.m b/Tests/NimbleTests/objc/ObjCContainTest.m index 8b954feed..62d6e4573 100644 --- a/Tests/NimbleTests/objc/ObjCContainTest.m +++ b/Tests/NimbleTests/objc/ObjCContainTest.m @@ -64,4 +64,13 @@ - (void)testVariadicArguments { }); } +- (void)testUnsupportedTypes { + expectFailureMessage(@"expected to contain (only works for NSArrays, NSSets, NSHashTables, and NSStrings), got <1>", ^{ + expect(@1).to(contain(@"foo")); + }); + expectFailureMessage(@"expected to not contain (only works for NSArrays, NSSets, NSHashTables, and NSStrings), got <1>", ^{ + expect(@1).toNot(contain(@"foo")); + }); +} + @end diff --git a/Tests/NimbleTests/objc/ObjCEndWithTest.m b/Tests/NimbleTests/objc/ObjCEndWithTest.m index b960f01b1..b48b3fcd9 100644 --- a/Tests/NimbleTests/objc/ObjCEndWithTest.m +++ b/Tests/NimbleTests/objc/ObjCEndWithTest.m @@ -13,7 +13,6 @@ - (void)testPositiveMatches { expect(@"hello world!").toNot(endWith(@"hello")); expect(array).to(endWith(@2)); expect(array).toNot(endWith(@1)); - expect(@1).toNot(contain(@"foo")); } - (void)testNegativeMatches { diff --git a/Tests/NimbleTests/objc/ObjCHaveCountTest.m b/Tests/NimbleTests/objc/ObjCHaveCountTest.m index 31053c8ee..ea0e31fbd 100644 --- a/Tests/NimbleTests/objc/ObjCHaveCountTest.m +++ b/Tests/NimbleTests/objc/ObjCHaveCountTest.m @@ -171,4 +171,13 @@ - (void)testHaveCountForUnsupportedTypes { }); } +- (void)testNilMatches { + expectNilFailureMessage(@"expected to have a collection with count 3, got ", ^{ + expect(nil).to(haveCount(3)); + }); + expectNilFailureMessage(@"expected to not have a collection with count 3, got ", ^{ + expect(nil).toNot(haveCount(3)); + }); +} + @end