diff --git a/Nimble.xcodeproj/project.pbxproj b/Nimble.xcodeproj/project.pbxproj index 23edb64b9..c1e4e082b 100644 --- a/Nimble.xcodeproj/project.pbxproj +++ b/Nimble.xcodeproj/project.pbxproj @@ -320,6 +320,9 @@ 7B5358BE1C38479700A23FAA /* SatisfyAnyOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */; }; 7B5358BF1C38479700A23FAA /* SatisfyAnyOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */; }; 7B5358C01C38479700A23FAA /* SatisfyAnyOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */; }; + 898F28B025D9F4C30052B8D0 /* AlwaysFailMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898F28AF25D9F4C30052B8D0 /* AlwaysFailMatcher.swift */; }; + 898F28B125D9F4C30052B8D0 /* AlwaysFailMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898F28AF25D9F4C30052B8D0 /* AlwaysFailMatcher.swift */; }; + 898F28B225D9F4C30052B8D0 /* AlwaysFailMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898F28AF25D9F4C30052B8D0 /* AlwaysFailMatcher.swift */; }; 964CFEFD1C4FF48900513336 /* ThrowAssertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964CFEFC1C4FF48900513336 /* ThrowAssertion.swift */; }; 964CFEFE1C4FF48900513336 /* ThrowAssertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964CFEFC1C4FF48900513336 /* ThrowAssertion.swift */; }; 964CFEFF1C4FF48900513336 /* ThrowAssertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964CFEFC1C4FF48900513336 /* ThrowAssertion.swift */; }; @@ -617,6 +620,7 @@ 7B5358B91C3846C900A23FAA /* SatisfyAnyOfTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SatisfyAnyOfTest.swift; sourceTree = ""; }; 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SatisfyAnyOf.swift; sourceTree = ""; }; 7B5358C11C39155600A23FAA /* ObjCSatisfyAnyOfTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCSatisfyAnyOfTest.m; sourceTree = ""; }; + 898F28AF25D9F4C30052B8D0 /* AlwaysFailMatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlwaysFailMatcher.swift; sourceTree = ""; }; 8DF1C3F61C94FC75004B2D36 /* ObjcStringersTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjcStringersTest.m; sourceTree = ""; }; 964CFEFC1C4FF48900513336 /* ThrowAssertion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThrowAssertion.swift; sourceTree = ""; }; 965B0D081B62B8ED0005AE66 /* ObjCUserDescriptionTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCUserDescriptionTest.m; sourceTree = ""; }; @@ -707,6 +711,7 @@ children = ( 1F14FB63194180C5009F2A08 /* utils.swift */, 1F0648CB19639F5A001F9C46 /* ObjectWithLazyProperty.swift */, + 898F28AF25D9F4C30052B8D0 /* AlwaysFailMatcher.swift */, ); path = Helpers; sourceTree = ""; @@ -1404,6 +1409,7 @@ buildActionMask = 2147483647; files = ( 1F4A569A1A3B3539009E1637 /* ObjCEqualTest.m in Sources */, + 898F28B125D9F4C30052B8D0 /* AlwaysFailMatcher.swift in Sources */, 1F925EEC195C12C800ED456B /* RaisesExceptionTest.swift in Sources */, 62FB326A23B78D500047BED9 /* BeginWithPrefixTest.swift in Sources */, 1F925EFF195C187600ED456B /* EndWithTest.swift in Sources */, @@ -1545,6 +1551,7 @@ buildActionMask = 2147483647; files = ( CD79C9AD1D2CC848004B6F9A /* ObjCBeTrueTest.m in Sources */, + 898F28B225D9F4C30052B8D0 /* AlwaysFailMatcher.swift in Sources */, CD79C9B41D2CC848004B6F9A /* ObjCRaiseExceptionTest.m in Sources */, 62FB326923B78D4F0047BED9 /* BeginWithPrefixTest.swift in Sources */, 1F5DF1A31BDCA10200C3A531 /* BeLogicalTest.swift in Sources */, @@ -1691,6 +1698,7 @@ buildActionMask = 2147483647; files = ( 1F4A569B1A3B3539009E1637 /* ObjCEqualTest.m in Sources */, + 898F28B025D9F4C30052B8D0 /* AlwaysFailMatcher.swift in Sources */, 1F925EED195C12C800ED456B /* RaisesExceptionTest.swift in Sources */, 62FB326B23B78D510047BED9 /* BeginWithPrefixTest.swift in Sources */, 1F925F00195C187600ED456B /* EndWithTest.swift in Sources */, diff --git a/Sources/Nimble/Matchers/SatisfyAllOf.swift b/Sources/Nimble/Matchers/SatisfyAllOf.swift index fd7ae1f69..9385bc13b 100644 --- a/Sources/Nimble/Matchers/SatisfyAllOf.swift +++ b/Sources/Nimble/Matchers/SatisfyAllOf.swift @@ -15,11 +15,13 @@ public func satisfyAllOf(_ matchers: U...) -> Predicate internal func satisfyAllOf(_ predicates: [Predicate]) -> Predicate { return Predicate.define { actualExpression in var postfixMessages = [String]() - var matches = true + var status: PredicateStatus = .matches for predicate in predicates { let result = try predicate.satisfies(actualExpression) - if result.toBoolean(expectation: .toNotMatch) { - matches = false + if result.status == .fail { + status = .fail + } else if result.status == .doesNotMatch, status != .fail { + status = .doesNotMatch } postfixMessages.append("{\(result.message.expectedMessage)}") } @@ -36,7 +38,7 @@ internal func satisfyAllOf(_ predicates: [Predicate]) -> Predicate { ) } - return PredicateResult(bool: matches, message: msg) + return PredicateResult(status: status, message: msg) } } diff --git a/Sources/Nimble/Matchers/SatisfyAnyOf.swift b/Sources/Nimble/Matchers/SatisfyAnyOf.swift index 037ccc938..90221acad 100644 --- a/Sources/Nimble/Matchers/SatisfyAnyOf.swift +++ b/Sources/Nimble/Matchers/SatisfyAnyOf.swift @@ -15,11 +15,13 @@ public func satisfyAnyOf(_ matchers: U...) -> Predicate internal func satisfyAnyOf(_ predicates: [Predicate]) -> Predicate { return Predicate.define { actualExpression in var postfixMessages = [String]() - var matches = false + var status: PredicateStatus = .doesNotMatch for predicate in predicates { let result = try predicate.satisfies(actualExpression) - if result.toBoolean(expectation: .toMatch) { - matches = true + if result.status == .fail { + status = .fail + } else if result.status == .matches, status != .fail { + status = .matches } postfixMessages.append("{\(result.message.expectedMessage)}") } @@ -36,7 +38,7 @@ internal func satisfyAnyOf(_ predicates: [Predicate]) -> Predicate { ) } - return PredicateResult(bool: matches, message: msg) + return PredicateResult(status: status, message: msg) } } diff --git a/Tests/NimbleTests/Helpers/AlwaysFailMatcher.swift b/Tests/NimbleTests/Helpers/AlwaysFailMatcher.swift new file mode 100644 index 000000000..f4d4fd691 --- /dev/null +++ b/Tests/NimbleTests/Helpers/AlwaysFailMatcher.swift @@ -0,0 +1,22 @@ +import XCTest +import Nimble + +func alwaysFail() -> Predicate { + return Predicate { _ throws -> PredicateResult in + return PredicateResult(status: .fail, message: .fail("This matcher should always fail")) + } +} + +final class AlwaysFailTest: XCTestCase { + func testAlwaysFail() { + failsWithErrorMessage( + "This matcher should always fail") { + expect(true).toNot(alwaysFail()) + } + + failsWithErrorMessage( + "This matcher should always fail") { + expect(true).to(alwaysFail()) + } + } +} diff --git a/Tests/NimbleTests/Matchers/SatisfyAllOfTest.swift b/Tests/NimbleTests/Matchers/SatisfyAllOfTest.swift index f85b5fcb2..caae73501 100644 --- a/Tests/NimbleTests/Matchers/SatisfyAllOfTest.swift +++ b/Tests/NimbleTests/Matchers/SatisfyAllOfTest.swift @@ -28,6 +28,14 @@ final class SatisfyAllOfTest: XCTestCase { "expected to not match all of: {be greater than <10.5>}, and {be less than <100.75>}, and {be close to <50.1> (within 0.0001)}, got 50.10001") { expect(50.10001).toNot(satisfyAllOf(beGreaterThan(10.5), beLessThan(100.75), beCloseTo(50.1))) } + failsWithErrorMessage( + "expected to not match all of: {This matcher should always fail}, and {This matcher should always fail}, got true") { + expect(true).toNot(satisfyAllOf(alwaysFail(), alwaysFail())) + } + failsWithErrorMessage( + "expected to match all of: {This matcher should always fail}, and {This matcher should always fail}, got true") { + expect(true).to(satisfyAllOf(alwaysFail(), alwaysFail())) + } } func testOperatorAnd() { diff --git a/Tests/NimbleTests/Matchers/SatisfyAnyOfTest.swift b/Tests/NimbleTests/Matchers/SatisfyAnyOfTest.swift index 102616d20..098e3a3a8 100644 --- a/Tests/NimbleTests/Matchers/SatisfyAnyOfTest.swift +++ b/Tests/NimbleTests/Matchers/SatisfyAnyOfTest.swift @@ -28,6 +28,14 @@ final class SatisfyAnyOfTest: XCTestCase { "expected to not match one of: {be less than <10.5>}, or {be greater than <100.75>}, or {be close to <50.1> (within 0.0001)}, got 50.10001") { expect(50.10001).toNot(satisfyAnyOf(beLessThan(10.5), beGreaterThan(100.75), beCloseTo(50.1))) } + failsWithErrorMessage( + "expected to match one of: {This matcher should always fail}, or {This matcher should always fail}, got true") { + expect(true).to(satisfyAnyOf(alwaysFail(), alwaysFail())) + } + failsWithErrorMessage( + "expected to not match one of: {This matcher should always fail}, or {This matcher should always fail}, got true") { + expect(true).toNot(satisfyAnyOf(alwaysFail(), alwaysFail())) + } } func testOperatorOr() {