Skip to content

Commit

Permalink
Merge pull request Quick#600 from Quick/reduce-nmbobjcmatcher-usages
Browse files Browse the repository at this point in the history
Reduce NMBObjCMatcher usages
  • Loading branch information
ikesyo authored Sep 18, 2018
2 parents ea906b6 + 339f2bb commit b6c0e11
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 33 deletions.
11 changes: 7 additions & 4 deletions Sources/Nimble/Matchers/BeLogical.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}
}
Expand Down
25 changes: 16 additions & 9 deletions Sources/Nimble/Matchers/Contain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,27 +69,34 @@ public func contain(_ items: [Any?]) -> Predicate<NMBContainer> {

#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 {
let expr = Expression(expression: ({ value as NMBContainer }), location: location)

// 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())
}
}
}
Expand Down
24 changes: 12 additions & 12 deletions Sources/Nimble/Matchers/ContainElementSatisfying.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,32 @@ public func containElementSatisfying<S: Sequence, T>(_ 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 {
continue
}

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)
}
}
}
Expand Down
23 changes: 16 additions & 7 deletions Sources/Nimble/Matchers/HaveCount.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,27 @@ public func haveCount(_ expectedValue: Int) -> Predicate<NMBCollection> {

#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())
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions Tests/NimbleTests/objc/ObjCContainTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,13 @@ - (void)testVariadicArguments {
});
}

- (void)testUnsupportedTypes {
expectFailureMessage(@"expected to contain <foo> (only works for NSArrays, NSSets, NSHashTables, and NSStrings), got <1>", ^{
expect(@1).to(contain(@"foo"));
});
expectFailureMessage(@"expected to not contain <foo> (only works for NSArrays, NSSets, NSHashTables, and NSStrings), got <1>", ^{
expect(@1).toNot(contain(@"foo"));
});
}

@end
1 change: 0 additions & 1 deletion Tests/NimbleTests/objc/ObjCEndWithTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
9 changes: 9 additions & 0 deletions Tests/NimbleTests/objc/ObjCHaveCountTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,13 @@ - (void)testHaveCountForUnsupportedTypes {
});
}

- (void)testNilMatches {
expectNilFailureMessage(@"expected to have a collection with count 3, got <nil>", ^{
expect(nil).to(haveCount(3));
});
expectNilFailureMessage(@"expected to not have a collection with count 3, got <nil>", ^{
expect(nil).toNot(haveCount(3));
});
}

@end

0 comments on commit b6c0e11

Please sign in to comment.