Skip to content

Commit

Permalink
Add a matcher to negate a passed in matcher (#1151)
Browse files Browse the repository at this point in the history
  • Loading branch information
younata authored Aug 8, 2024
1 parent 6ba9e68 commit 26e5348
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Nimble.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@
898F28B025D9F4C30052B8D0 /* AlwaysFailMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898F28AF25D9F4C30052B8D0 /* AlwaysFailMatcher.swift */; };
899441EF2902EE4B00C1FAF9 /* AsyncAwaitTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 899441EE2902EE4B00C1FAF9 /* AsyncAwaitTest.swift */; };
899441F82902EF2500C1FAF9 /* DSL+AsyncAwait.swift in Sources */ = {isa = PBXBuildFile; fileRef = 899441F32902EF0900C1FAF9 /* DSL+AsyncAwait.swift */; };
89B8C60F2C6476A6001F12D3 /* Negation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89B8C60E2C6476A6001F12D3 /* Negation.swift */; };
89B8C6112C6478F2001F12D3 /* NegationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89B8C6102C6478F2001F12D3 /* NegationTest.swift */; };
89C297CC2A911CDA002A143F /* AsyncTimerSequenceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89C297CB2A911CDA002A143F /* AsyncTimerSequenceTest.swift */; };
89C297CE2A92AB34002A143F /* AsyncPromiseTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89C297CD2A92AB34002A143F /* AsyncPromiseTest.swift */; };
89D8AC852B3211C600410644 /* CwlCatchException in Frameworks */ = {isa = PBXBuildFile; productRef = 89D8AC842B3211C600410644 /* CwlCatchException */; };
Expand Down Expand Up @@ -327,6 +329,8 @@
898F28AF25D9F4C30052B8D0 /* AlwaysFailMatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlwaysFailMatcher.swift; sourceTree = "<group>"; };
899441EE2902EE4B00C1FAF9 /* AsyncAwaitTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncAwaitTest.swift; sourceTree = "<group>"; };
899441F32902EF0900C1FAF9 /* DSL+AsyncAwait.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DSL+AsyncAwait.swift"; sourceTree = "<group>"; };
89B8C60E2C6476A6001F12D3 /* Negation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Negation.swift; sourceTree = "<group>"; };
89B8C6102C6478F2001F12D3 /* NegationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NegationTest.swift; sourceTree = "<group>"; };
89C297CB2A911CDA002A143F /* AsyncTimerSequenceTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncTimerSequenceTest.swift; sourceTree = "<group>"; };
89C297CD2A92AB34002A143F /* AsyncPromiseTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncPromiseTest.swift; sourceTree = "<group>"; };
89EEF5A42A03293100988224 /* AsyncMatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncMatcher.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -536,6 +540,7 @@
8923E60E2B47D06E00F3961A /* MapTest.swift */,
AE7ADE481C80C00D00B94CD3 /* MatchErrorTest.swift */,
DDB4D5EF19FE442800E9D9FE /* MatchTest.swift */,
89B8C6102C6478F2001F12D3 /* NegationTest.swift */,
1FCF914E1C61C85A00B15DCB /* PostNotificationTest.swift */,
1F925EEB195C12C800ED456B /* RaisesExceptionTest.swift */,
A8A3B6E920712FC100E25A08 /* SatisfyAllOfTest.swift */,
Expand Down Expand Up @@ -597,6 +602,7 @@
1FD8CD1D1968AB07008ED995 /* MatcherProtocols.swift */,
AE7ADE441C80BF8000B94CD3 /* MatchError.swift */,
1FA0C3FE1E30B14500623165 /* Matcher.swift */,
89B8C60E2C6476A6001F12D3 /* Negation.swift */,
1FCF91521C61C8A400B15DCB /* PostNotification.swift */,
1FD8CD1E1968AB07008ED995 /* RaisesException.swift */,
A8F6B5BC2070186D00FCB5ED /* SatisfyAllOf.swift */,
Expand Down Expand Up @@ -893,6 +899,7 @@
964CFEFE1C4FF48900513336 /* ThrowAssertion.swift in Sources */,
1FD8CD591968AB07008ED995 /* EndWith.swift in Sources */,
1FD8CD351968AB07008ED995 /* DSL.swift in Sources */,
89B8C60F2C6476A6001F12D3 /* Negation.swift in Sources */,
7B5358BF1C38479700A23FAA /* SatisfyAnyOf.swift in Sources */,
896962412A5FABD000A7929D /* AsyncAllPass.swift in Sources */,
891729D72B18431D005CC866 /* Requirement.swift in Sources */,
Expand Down Expand Up @@ -920,6 +927,7 @@
1F925F00195C187600ED456B /* EndWithTest.swift in Sources */,
1F1B5AD51963E13900CA8BF9 /* BeAKindOfTest.swift in Sources */,
1F925F0F195C18F500ED456B /* BeLessThanOrEqualToTest.swift in Sources */,
89B8C6112C6478F2001F12D3 /* NegationTest.swift in Sources */,
CDBC39B92462EA7D00069677 /* PredicateTest.swift in Sources */,
8969624A2A5FAD5F00A7929D /* AsyncAllPassTest.swift in Sources */,
1F4A56671A3B305F009E1637 /* ObjCAsyncTest.m in Sources */,
Expand Down
37 changes: 37 additions & 0 deletions Sources/Nimble/Matchers/Negation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/// A matcher that negates the passed in matcher
///
/// - Note: If the passed-in matcher unconditionally fails, then `not` also unconditionally fails.
public func not<T>(_ matcher: Matcher<T>) -> Matcher<T> {
Matcher { actualExpression in
negateMatcherResult(
try matcher.satisfies(actualExpression)
)
}
}

/// A matcher that negates the passed in matcher
///
/// - Note: If the passed-in matcher unconditionally fails, then `not` also unconditionally fails.
public func not<T>(_ matcher: AsyncMatcher<T>) -> AsyncMatcher<T> {
AsyncMatcher { actualExpression in
negateMatcherResult(
try await matcher.satisfies(actualExpression)
)
}
}

private func negateMatcherResult(_ matcherResult: MatcherResult) -> MatcherResult {
let status: MatcherStatus
switch matcherResult.status {
case .matches:
status = .doesNotMatch
case .doesNotMatch:
status = .matches
case .fail:
status = .fail
}
return MatcherResult(
status: status,
message: matcherResult.message.prepended(expectation: "not ")
)
}
43 changes: 43 additions & 0 deletions Tests/NimbleTests/Matchers/NegationTest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import XCTest
import Nimble
#if SWIFT_PACKAGE
import NimbleSharedTestHelpers
#endif

final class NegationTest: XCTestCase {
func testSyncNil() {
expect(nil as Int?).toNot(not(beNil()))

failsWithErrorMessage("expected to not be nil, got <nil>") {
expect(nil as Int?).to(not(beNil()))
}
}

func testSyncNonNil() {
expect(1).to(not(equal(2)))

failsWithErrorMessage("expected to not equal <2>, got <2>") {
expect(2).to(not(equal(2)))
}
}

func testAsyncNil() async {
@Sendable func nilFunc() async -> Int? {
nil
}

await expect(nilFunc).toNot(not(beNil()))

await failsWithErrorMessage("expected to not be nil, got <nil>") {
await expect(nilFunc).to(not(beNil()))
}
}

func testAsyncNonNil() async {
await expect(1).to(not(asyncEqual(2)))

await failsWithErrorMessage("expected to not equal <2>, got <2>") {
await expect(2).to(not(asyncEqual(2)))
}
}
}

0 comments on commit 26e5348

Please sign in to comment.