Skip to content

Commit 26a9795

Browse files
Rodrigo Kreutzikesyo
authored andcommitted
Adding toNever expectation
1 parent 17a1f9c commit 26a9795

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

Sources/Nimble/Matchers/Async.swift

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,43 @@ private func async<T>(style: ExpectationStyle, predicate: Predicate<T>, timeout:
4848
}
4949
}
5050

51+
private func toNeverPredicate<T>(predicate: Predicate<T>, timeout: DispatchTimeInterval, poll: DispatchTimeInterval, fnName: String) -> Predicate<T> {
52+
return Predicate { actualExpression in
53+
let uncachedExpression = actualExpression.withoutCaching()
54+
let fnName = "expect(...).\(fnName)(...)"
55+
var lastPredicateResult: PredicateResult?
56+
let result = pollBlock(
57+
pollInterval: poll,
58+
timeoutInterval: timeout,
59+
file: actualExpression.location.file,
60+
line: actualExpression.location.line,
61+
fnName: fnName) {
62+
lastPredicateResult = try predicate.satisfies(uncachedExpression)
63+
return lastPredicateResult!.toBoolean(expectation: .toMatch)
64+
}
65+
switch result {
66+
case .completed:
67+
return PredicateResult(
68+
status: .fail,
69+
message: lastPredicateResult?.message ?? .fail("matched the predicate when it shouldn't have")
70+
)
71+
case .timedOut:
72+
return PredicateResult(status: .doesNotMatch, message: .expectedTo("never match the predicate"))
73+
case let .errorThrown(error):
74+
return PredicateResult(status: .fail, message: .fail("unexpected error thrown: <\(error)>"))
75+
case let .raisedException(exception):
76+
return PredicateResult(status: .fail, message: .fail("unexpected exception raised: \(exception)"))
77+
case .blockedRunLoop:
78+
// swiftlint:disable:next line_length
79+
let message = lastPredicateResult?.message.appended(message: " (timed out, but main run loop was unresponsive).") ??
80+
.fail("main run loop was unresponsive")
81+
return PredicateResult(status: .fail, message: message)
82+
case .incomplete:
83+
internalError("Reached .incomplete state for \(fnName)(...).")
84+
}
85+
}
86+
}
87+
5188
private let toEventuallyRequiresClosureError = FailureMessage(
5289
stringValue: """
5390
expect(...).toEventually(...) requires an explicit closure (eg - expect { ... }.toEventually(...) )
@@ -113,4 +150,23 @@ extension Expectation {
113150
public func toNotEventually(_ predicate: Predicate<T>, timeout: DispatchTimeInterval = AsyncDefaults.timeout, pollInterval: DispatchTimeInterval = AsyncDefaults.pollInterval, description: String? = nil) {
114151
return toEventuallyNot(predicate, timeout: timeout, pollInterval: pollInterval, description: description)
115152
}
153+
154+
public func toNever(_ predicate: Predicate<T>, until: DispatchTimeInterval = AsyncDefaults.timeout, pollInterval: DispatchTimeInterval = AsyncDefaults.pollInterval, description: String? = nil) {
155+
nimblePrecondition(expression.isClosure, "NimbleInternalError", toEventuallyRequiresClosureError.stringValue)
156+
157+
158+
let (pass, msg) = execute(
159+
expression,
160+
.toNotMatch,
161+
toNeverPredicate(predicate: predicate, timeout: until, poll: pollInterval, fnName: "toNever"),
162+
to: "to never",
163+
description: description,
164+
captureExceptions: false
165+
)
166+
verify(pass, msg)
167+
}
168+
169+
public func neverTo(_ predicate: Predicate<T>, until: DispatchTimeInterval = AsyncDefaults.timeout, pollInterval: DispatchTimeInterval = AsyncDefaults.pollInterval, description: String? = nil) {
170+
return toNever(predicate, until: until, pollInterval: pollInterval, description: description)
171+
}
116172
}

Tests/NimbleTests/AsynchronousTest.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,4 +250,38 @@ final class AsyncTest: XCTestCase {
250250
}
251251
}
252252

253+
func testToNeverPositiveMatches() {
254+
255+
var value = 0
256+
deferToMainQueue { value = 1 }
257+
expect { value }.toNever(beGreaterThan(1))
258+
259+
deferToMainQueue { value = 0 }
260+
expect { value }.neverTo(beGreaterThan(1))
261+
}
262+
263+
func testToNeverNegativeMatches() {
264+
265+
var value = 0
266+
failsWithErrorMessage("expected to never equal <0>, got <0>") {
267+
expect { value }.toNever(equal(0))
268+
}
269+
failsWithErrorMessage("expected to never equal <0>, got <0>") {
270+
expect { value }.neverTo(equal(0))
271+
}
272+
failsWithErrorMessage("expected to never equal <1>, got <1>") {
273+
deferToMainQueue { value = 1 }
274+
expect { value }.toNever(equal(1))
275+
}
276+
failsWithErrorMessage("expected to never equal <1>, got <1>") {
277+
deferToMainQueue { value = 1 }
278+
expect { value }.neverTo(equal(1))
279+
}
280+
failsWithErrorMessage("unexpected error thrown: <\(errorToThrow)>") {
281+
expect { try self.doThrowError() }.toNever(equal(0))
282+
}
283+
failsWithErrorMessage("unexpected error thrown: <\(errorToThrow)>") {
284+
expect { try self.doThrowError() }.neverTo(equal(0))
285+
}
286+
}
253287
}

0 commit comments

Comments
 (0)