Commit f050ed45 authored by Stefan van den Oord's avatar Stefan van den Oord

Converting to Xcode 6.3

parent a186e06d
......@@ -12,16 +12,16 @@ pod 'IGDigest', '~> 1.1.0'
pod 'OpenSSL-Framework', '~> 1.0.201'
target 'PulseTests' do
pod 'Quick', '~> 0.2.2'
pod 'Nimble', '~> 0.3.0'
pod 'Quick', '~> 0.2'
pod 'Nimble', '~> 0.3'
end
target 'PulseIntegrationTests' do
pod 'Quick', '~> 0.2.2'
pod 'Nimble', '~> 0.3.0'
pod 'Quick', '~> 0.2'
pod 'Nimble', '~> 0.3'
end
target 'PulseSystemTests' do
pod 'Quick', '~> 0.2.2'
pod 'Nimble', '~> 0.3.0'
pod 'Quick', '~> 0.2'
pod 'Nimble', '~> 0.3'
end
......@@ -3,9 +3,9 @@ PODS:
- CocoaAsyncSocket (7.4.1)
- IGDigest (1.1.2)
- lz4 (123)
- Nimble (0.3.1)
- Nimble (0.4.2)
- OpenSSL-Framework (1.0.201)
- Quick (0.2.3)
- Quick (0.3.1)
- SwiftBytes (0.1.0)
DEPENDENCIES:
......@@ -13,9 +13,9 @@ DEPENDENCIES:
- CocoaAsyncSocket (~> 7.4)
- IGDigest (~> 1.1.0)
- lz4 (~> 123)
- Nimble (~> 0.3.0)
- Nimble (~> 0.3)
- OpenSSL-Framework (~> 1.0.201)
- Quick (~> 0.2.2)
- Quick (~> 0.2)
- SwiftBytes (~> 0.1.0)
SPEC CHECKSUMS:
......@@ -23,9 +23,9 @@ SPEC CHECKSUMS:
CocoaAsyncSocket: 7cbf214b27f8e7f7574db6a3fd96352ffaed433d
IGDigest: 066753c10f3f1b593b00037b9ee93dc96b9e7762
lz4: 04eccb717fb91bcc7b22868bdb545fdffa27f053
Nimble: 1b3c765852d63b9540a91e528e1e4f8afab79b6f
Nimble: 49b7a7da8919f42823d37c6d68cc6d15a7009f32
OpenSSL-Framework: 2d2289869dd1cfd0df0b340398bcf64094ecfe12
Quick: 2c59914d3b2548a0e8ed0288062d965d9bab03e2
Quick: 824572d3d198d51e52cf4aa722cebf7e59952a35
SwiftBytes: e7a808f61a9954ee173e1c3c09d211e3a212c2db
COCOAPODS: 0.36.3
......@@ -3,9 +3,9 @@ PODS:
- CocoaAsyncSocket (7.4.1)
- IGDigest (1.1.2)
- lz4 (123)
- Nimble (0.3.1)
- Nimble (0.4.2)
- OpenSSL-Framework (1.0.201)
- Quick (0.2.3)
- Quick (0.3.1)
- SwiftBytes (0.1.0)
DEPENDENCIES:
......@@ -13,9 +13,9 @@ DEPENDENCIES:
- CocoaAsyncSocket (~> 7.4)
- IGDigest (~> 1.1.0)
- lz4 (~> 123)
- Nimble (~> 0.3.0)
- Nimble (~> 0.3)
- OpenSSL-Framework (~> 1.0.201)
- Quick (~> 0.2.2)
- Quick (~> 0.2)
- SwiftBytes (~> 0.1.0)
SPEC CHECKSUMS:
......@@ -23,9 +23,9 @@ SPEC CHECKSUMS:
CocoaAsyncSocket: 7cbf214b27f8e7f7574db6a3fd96352ffaed433d
IGDigest: 066753c10f3f1b593b00037b9ee93dc96b9e7762
lz4: 04eccb717fb91bcc7b22868bdb545fdffa27f053
Nimble: 1b3c765852d63b9540a91e528e1e4f8afab79b6f
Nimble: 49b7a7da8919f42823d37c6d68cc6d15a7009f32
OpenSSL-Framework: 2d2289869dd1cfd0df0b340398bcf64094ecfe12
Quick: 2c59914d3b2548a0e8ed0288062d965d9bab03e2
Quick: 824572d3d198d51e52cf4aa722cebf7e59952a35
SwiftBytes: e7a808f61a9954ee173e1c3c09d211e3a212c2db
COCOAPODS: 0.36.3
......@@ -9,5 +9,4 @@ public protocol AssertionHandler {
/// Defaults to a private test handler that passes through to XCTest.
///
/// @see AssertionHandler
var CurrentAssertionHandler: AssertionHandler = XCTestHandler()
public var NimbleAssertionHandler: AssertionHandler = NimbleXCTestHandler()
......@@ -40,11 +40,11 @@ public class AssertionRecorder : AssertionHandler {
///
/// @see AssertionHandler
public func withAssertionHandler(tempAssertionHandler: AssertionHandler, closure: () -> Void) {
let oldRecorder = CurrentAssertionHandler
let oldRecorder = NimbleAssertionHandler
let capturer = NMBExceptionCapture(handler: nil, finally: ({
CurrentAssertionHandler = oldRecorder
NimbleAssertionHandler = oldRecorder
}))
CurrentAssertionHandler = tempAssertionHandler
NimbleAssertionHandler = tempAssertionHandler
capturer.tryBlock {
closure()
}
......
import Foundation
import XCTest
class XCTestHandler : AssertionHandler {
func assert(assertion: Bool, message: String, location: SourceLocation) {
/// Default handler for Nimble. This assertion handler passes failures along to
/// XCTest.
public class NimbleXCTestHandler : AssertionHandler {
public func assert(assertion: Bool, message: String, location: SourceLocation) {
if !assertion {
XCTFail(message, file: location.file, line: location.line)
}
......
......@@ -4,7 +4,7 @@ import Foundation
/// bridges to Objective-C via the @objc keyword. This class encapsulates callback-style
/// asynchronous waiting logic so that it may be called from Objective-C and Swift.
@objc public class NMBWait {
public class func until(#timeout: NSTimeInterval, action: (() -> Void) -> Void, file: String = __FILE__, line: UInt = __LINE__) -> Void {
public class func until(#timeout: NSTimeInterval, file: String = __FILE__, line: UInt = __LINE__, action: (() -> Void) -> Void) -> Void {
var completed = false
var token: dispatch_once_t = 0
let result = pollBlock(pollInterval: 0.01, timeoutInterval: timeout) {
......@@ -23,21 +23,21 @@ import Foundation
}
}
public class func until(action: (() -> Void) -> Void, file: String = __FILE__, line: UInt = __LINE__) -> Void {
until(timeout: 1, action: action, file: file, line: line)
public class func until(file: String = __FILE__, line: UInt = __LINE__, action: (() -> Void) -> Void) -> Void {
until(timeout: 1, file: file, line: line, action: action)
}
}
/// Wait asynchronously until the done closure is called.
///
/// This will advance the run loop.
public func waitUntil(#timeout: NSTimeInterval, action: (() -> Void) -> Void, file: String = __FILE__, line: UInt = __LINE__) -> Void {
NMBWait.until(timeout: timeout, action: action, file: file, line: line)
public func waitUntil(#timeout: NSTimeInterval, file: String = __FILE__, line: UInt = __LINE__, action: (() -> Void) -> Void) -> Void {
NMBWait.until(timeout: timeout, file: file, line: line, action: action)
}
/// Wait asynchronously until the done closure is called.
///
/// This will advance the run loop.
public func waitUntil(action: (() -> Void) -> Void, file: String = __FILE__, line: UInt = __LINE__) -> Void {
NMBWait.until(action, file: file, line: line)
public func waitUntil(file: String = __FILE__, line: UInt = __LINE__, action: (() -> Void) -> Void) -> Void {
NMBWait.until(file: file, line: line, action: action)
}
\ No newline at end of file
/// Make an expectation on a given actual value. The value given is lazily evaluated.
public func expect<T>(expression: @autoclosure () -> T?, file: String = __FILE__, line: UInt = __LINE__) -> Expectation<T> {
public func expect<T>(@autoclosure(escaping) expression: () -> T?, file: String = __FILE__, line: UInt = __LINE__) -> Expectation<T> {
return Expectation(
expression: Expression(
expression: expression,
location: SourceLocation(file: file, line: line)))
location: SourceLocation(file: file, line: line),
isClosure: true))
}
/// Make an expectation on a given actual value. The closure is lazily invoked.
......@@ -11,12 +12,13 @@ public func expect<T>(file: String = __FILE__, line: UInt = __LINE__, expression
return Expectation(
expression: Expression(
expression: expression,
location: SourceLocation(file: file, line: line)))
location: SourceLocation(file: file, line: line),
isClosure: true))
}
/// Always fails the test with a message and a specified location.
public func fail(message: String, #location: SourceLocation) {
CurrentAssertionHandler.assert(false, message: message, location: location)
NimbleAssertionHandler.assert(false, message: message, location: location)
}
/// Always fails the test with a message.
......
......@@ -4,7 +4,7 @@ public struct Expectation<T> {
let expression: Expression<T>
public func verify(pass: Bool, _ message: String) {
CurrentAssertionHandler.assert(pass, message: message, location: expression.location)
NimbleAssertionHandler.assert(pass, message: message, location: expression.location)
}
public func to<U where U: Matcher, U.ValueType == T>(matcher: U) {
......
......@@ -16,21 +16,24 @@ public struct Expression<T> {
internal let _expression: (Bool) -> T?
internal let _withoutCaching: Bool
public let location: SourceLocation
public let isClosure: Bool
public init(expression: () -> T?, location: SourceLocation) {
public init(expression: () -> T?, location: SourceLocation, isClosure: Bool = false) {
self._expression = memoizedClosure(expression)
self.location = location
self._withoutCaching = false
self.isClosure = isClosure
}
public init(memoizedExpression: (Bool) -> T?, location: SourceLocation, withoutCaching: Bool) {
public init(memoizedExpression: (Bool) -> T?, location: SourceLocation, withoutCaching: Bool, isClosure: Bool = false) {
self._expression = memoizedExpression
self.location = location
self._withoutCaching = withoutCaching
self.isClosure = isClosure
}
public func cast<U>(block: (T?) -> U?) -> Expression<U> {
return Expression<U>(expression: ({ block(self.evaluate()) }), location: self.location)
return Expression<U>(expression: ({ block(self.evaluate()) }), location: self.location, isClosure: self.isClosure)
}
public func evaluate() -> T? {
......@@ -38,6 +41,6 @@ public struct Expression<T> {
}
public func withoutCaching() -> Expression<T> {
return Expression(memoizedExpression: self._expression, location: location, withoutCaching: true)
return Expression(memoizedExpression: self._expression, location: location, withoutCaching: true, isClosure: isClosure)
}
}
......@@ -16,7 +16,7 @@ public class FailureMessage {
if let actualValue = actualValue {
value = "\(expected) \(to) \(postfixMessage), got \(actualValue)\(postfixActual)"
}
var lines: [String] = (value as NSString).componentsSeparatedByString("\n") as [String]
var lines: [String] = (value as NSString).componentsSeparatedByString("\n") as! [String]
let whitespace = NSCharacterSet.whitespaceAndNewlineCharacterSet()
lines = lines.map { line in line.stringByTrimmingCharactersInSet(whitespace) }
return "".join(lines)
......
import Foundation
public func allPass<T,U where U: SequenceType, U.Generator.Element == T>
(passFunc: (T?) -> Bool) -> NonNilMatcherFunc<U> {
return allPass("pass a condition", passFunc)
}
public func allPass<T,U where U: SequenceType, U.Generator.Element == T>
(passName:String, passFunc: (T?) -> Bool) -> NonNilMatcherFunc<U> {
return createAllPassMatcher() {
expression, failureMessage in
failureMessage.postfixMessage = passName
return passFunc(expression.evaluate())
}
}
public func allPass<U,V where U: SequenceType, V: NonNilBasicMatcher, U.Generator.Element == V.ValueType>
(matcher: V) -> NonNilMatcherFunc<U> {
let wrapper = NonNilMatcherWrapper(NonNilBasicMatcherWrapper(matcher))
return createAllPassMatcher() {wrapper.matches($0, failureMessage: $1)}
}
public func allPass<U,V where U: SequenceType, V: BasicMatcher, U.Generator.Element == V.ValueType>
(matcher: V) -> NonNilMatcherFunc<U> {
let wrapper = BasicMatcherWrapper(matcher: matcher)
return createAllPassMatcher() {wrapper.matches($0, failureMessage: $1)}
}
public func allPass<U,V where U: SequenceType, V: Matcher, U.Generator.Element == V.ValueType>
(matcher: V) -> NonNilMatcherFunc<U> {
return createAllPassMatcher() {matcher.matches($0, failureMessage: $1)}
}
private func createAllPassMatcher<T,U where U: SequenceType, U.Generator.Element == T>
(elementEvaluator:(Expression<T>, FailureMessage) -> Bool) -> NonNilMatcherFunc<U> {
return NonNilMatcherFunc { actualExpression, failureMessage in
failureMessage.actualValue = nil
if let actualValue = actualExpression.evaluate() {
for currentElement in actualValue {
let exp = Expression(
expression: {currentElement}, location: actualExpression.location)
if !elementEvaluator(exp, failureMessage) {
failureMessage.postfixMessage =
"all \(failureMessage.postfixMessage),"
+ " but failed first at element <\(stringify(currentElement))>"
+ " in <\(stringify(actualValue))>"
return false
}
}
failureMessage.postfixMessage = "all \(failureMessage.postfixMessage)"
} else {
failureMessage.postfixMessage = "all pass (use beNil() to match nils)"
return false
}
return true
}
}
extension NMBObjCMatcher {
public class func allPassMatcher(matcher: NMBObjCMatcher) -> NMBObjCMatcher {
return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage, location in
let actualValue = actualExpression.evaluate()
var nsObjects = [NSObject]()
var collectionIsUsable = true
if let value = actualValue as? NSFastEnumeration {
let generator = NSFastGenerator(value)
while let obj:AnyObject = generator.next() {
if let nsObject = obj as? NSObject {
nsObjects.append(nsObject)
} else {
collectionIsUsable = false
break
}
}
} else {
collectionIsUsable = false
}
if !collectionIsUsable {
failureMessage.postfixMessage =
"allPass only works with NSFastEnumeration (NSArray, NSSet, ...) of NSObjects"
failureMessage.expected = ""
failureMessage.to = ""
return false
}
let expr = Expression(expression: ({ nsObjects }), location: location)
let elementEvaluator: (Expression<NSObject>, FailureMessage) -> Bool = {
expression, failureMessage in
return matcher.matches(
{expression.evaluate()}, failureMessage: failureMessage, location: expr.location)
}
return createAllPassMatcher(elementEvaluator).matches(
expr, failureMessage: failureMessage)
}
}
}
......@@ -30,7 +30,7 @@ public func >(lhs: Expectation<NMBComparable>, rhs: NMBComparable?) {
extension NMBObjCMatcher {
public class func beGreaterThanMatcher(expected: NMBComparable?) -> NMBObjCMatcher {
return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage, location in
let expr = actualExpression.cast { $0 as NMBComparable? }
let expr = actualExpression.cast { $0 as? NMBComparable }
return beGreaterThan(expected).matches(expr, failureMessage: failureMessage)
}
}
......
......@@ -32,7 +32,7 @@ public func >=<T: NMBComparable>(lhs: Expectation<T>, rhs: T) {
extension NMBObjCMatcher {
public class func beGreaterThanOrEqualToMatcher(expected: NMBComparable?) -> NMBObjCMatcher {
return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage, location in
let expr = actualExpression.cast { $0 as NMBComparable? }
let expr = actualExpression.cast { $0 as? NMBComparable }
return beGreaterThanOrEqualTo(expected).matches(expr, failureMessage: failureMessage)
}
}
......
......@@ -29,7 +29,7 @@ public func <(lhs: Expectation<NMBComparable>, rhs: NMBComparable?) {
extension NMBObjCMatcher {
public class func beLessThanMatcher(expected: NMBComparable?) -> NMBObjCMatcher {
return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage, location in
let expr = actualExpression.cast { $0 as NMBComparable? }
let expr = actualExpression.cast { $0 as! NMBComparable? }
return beLessThan(expected).matches(expr, failureMessage: failureMessage)
}
}
......
......@@ -43,7 +43,7 @@ extension NMBObjCMatcher {
let actual = actualExpression.evaluate()
if let actualString = actual as? String {
let expr = actualExpression.cast { $0 as? String }
return beginWith(expected as String).matches(expr, failureMessage: failureMessage)
return beginWith(expected as! String).matches(expr, failureMessage: failureMessage)
} else {
let expr = actualExpression.cast { $0 as? NMBOrderedCollection }
return beginWith(expected).matches(expr, failureMessage: failureMessage)
......
......@@ -28,6 +28,19 @@ public func contain(substrings: String...) -> NonNilMatcherFunc<String> {
}
}
/// A Nimble matcher that succeeds when the actual string contains the expected substring.
public func contain(substrings: NSString...) -> NonNilMatcherFunc<NSString> {
return NonNilMatcherFunc { actualExpression, failureMessage in
failureMessage.postfixMessage = "contain <\(arrayAsString(substrings))>"
if let actual = actualExpression.evaluate() {
return all(substrings) {
return actual.containsString($0.description)
}
}
return false
}
}
/// A Nimble matcher that succeeds when the actual collection contains the expected object.
public func contain(items: AnyObject?...) -> NonNilMatcherFunc<NMBContainer> {
return NonNilMatcherFunc { actualExpression, failureMessage in
......@@ -48,7 +61,7 @@ extension NMBObjCMatcher {
return contain(expected).matches(expr, failureMessage: failureMessage)
} else if let value = actualValue as? NSString {
let expr = Expression(expression: ({ value as String }), location: location)
return contain(expected as String).matches(expr, failureMessage: failureMessage)
return contain(expected as! String).matches(expr, failureMessage: failureMessage)
} else if actualValue != nil {
failureMessage.postfixMessage = "contain <\(stringify(expected))> (only works for NSArrays, NSSets, NSHashTables, and NSStrings)"
} else {
......
......@@ -53,7 +53,7 @@ extension NMBObjCMatcher {
let actual = actualExpression.evaluate()
if let actualString = actual as? String {
let expr = Expression(expression: ({ actualString }), location: location)
return endWith(expected as String).matches(expr, failureMessage: failureMessage)
return endWith(expected as! String).matches(expr, failureMessage: failureMessage)
} else {
let expr = Expression(expression: ({ actual as? NMBOrderedCollection }), location: location)
return endWith(expected).matches(expr, failureMessage: failureMessage)
......
......@@ -50,6 +50,52 @@ public func equal<T: Equatable>(expectedValue: [T]?) -> NonNilMatcherFunc<[T]> {
}
}
/// A Nimble matcher that succeeds when the actual set is equal to the expected set.
public func equal<T>(expectedValue: Set<T>?) -> NonNilMatcherFunc<Set<T>> {
return equal(expectedValue, stringify: stringify)
}
/// A Nimble matcher that succeeds when the actual set is equal to the expected set.
public func equal<T: Comparable>(expectedValue: Set<T>?) -> NonNilMatcherFunc<Set<T>> {
return equal(expectedValue, stringify: {
if let set = $0 {
return stringify(Array(set).sorted { $0 < $1 })
} else {
return "nil"
}
})
}
private func equal<T>(expectedValue: Set<T>?, #stringify: Set<T>? -> String) -> NonNilMatcherFunc<Set<T>> {
return NonNilMatcherFunc { actualExpression, failureMessage in
failureMessage.postfixMessage = "equal <\(stringify(expectedValue))>"
if let expectedValue = expectedValue {
if let actualValue = actualExpression.evaluate() {
failureMessage.actualValue = "<\(stringify(actualValue))>"
if expectedValue == actualValue {
return true
}
let missing = expectedValue.subtract(actualValue)
if missing.count > 0 {
failureMessage.postfixActual += ", missing <\(stringify(missing))>"
}
let extra = actualValue.subtract(expectedValue)
if extra.count > 0 {
failureMessage.postfixActual += ", extra <\(stringify(extra))>"
}
}
} else {
failureMessage.postfixActual = " (use beNil() to match nils)"
}
return false
}
}
public func ==<T: Equatable>(lhs: Expectation<T>, rhs: T?) {
lhs.to(equal(rhs))
}
......@@ -66,6 +112,22 @@ public func !=<T: Equatable>(lhs: Expectation<[T]>, rhs: [T]?) {
lhs.toNot(equal(rhs))
}
public func ==<T>(lhs: Expectation<Set<T>>, rhs: Set<T>?) {
lhs.to(equal(rhs))
}
public func !=<T>(lhs: Expectation<Set<T>>, rhs: Set<T>?) {
lhs.toNot(equal(rhs))
}
public func ==<T: Comparable>(lhs: Expectation<Set<T>>, rhs: Set<T>?) {
lhs.to(equal(rhs))
}
public func !=<T: Comparable>(lhs: Expectation<Set<T>>, rhs: Set<T>?) {
lhs.toNot(equal(rhs))
}
public func ==<T: Equatable, C: Equatable>(lhs: Expectation<[T: C]>, rhs: [T: C]?) {
lhs.to(equal(rhs))
}
......
......@@ -20,7 +20,7 @@ extension NMBObjCMatcher {
public class func matchMatcher(expected: NSString) -> NMBMatcher {
return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage, location in
let actual = actualExpression.cast { $0 as? String }
return match(expected).matches(actual, failureMessage: failureMessage)
return match(expected.description).matches(actual, failureMessage: failureMessage)
}
}
}
......
......@@ -82,11 +82,11 @@ extension NSDecimalNumber : NMBDoubleConvertible { } // TODO: not the best to do
}
extension NSNumber : NMBComparable {
public func NMB_compare(otherObject: NMBComparable!) -> NSComparisonResult {
return compare(otherObject as NSNumber)
return compare(otherObject as! NSNumber)
}
}
extension NSString : NMBComparable {
public func NMB_compare(otherObject: NMBComparable!) -> NSComparisonResult {
return compare(otherObject as NSString)
return compare(otherObject as! String)
}
}
......@@ -5,7 +5,7 @@ internal func identityAsString(value: AnyObject?) -> String {
if value == nil {
return "nil"
}
return NSString(format: "<%p>", unsafeBitCast(value!, Int.self))
return NSString(format: "<%p>", unsafeBitCast(value!, Int.self)).description
}
internal func arrayAsString<T>(items: [T], joiner: String = ", ") -> String {
......@@ -41,8 +41,8 @@ extension NSArray : NMBStringer {
}
internal func stringify<T>(value: T) -> String {
if value is Double {
return NSString(format: "%.4f", (value as Double))
if let value = value as? Double {
return NSString(format: "%.4f", (value)).description
}
return toString(value)
}
......
......@@ -2,8 +2,14 @@ import Foundation
struct AsyncMatcherWrapper<T, U where U: Matcher, U.ValueType == T>: Matcher {
let fullMatcher: U
let timeoutInterval: NSTimeInterval = 1
let pollInterval: NSTimeInterval = 0.01
let timeoutInterval: NSTimeInterval
let pollInterval: NSTimeInterval
init(fullMatcher: U, timeoutInterval: NSTimeInterval = 1, pollInterval: NSTimeInterval = 0.01) {
self.fullMatcher = fullMatcher
self.timeoutInterval = timeoutInterval
self.pollInterval = pollInterval
}
func matches(actualExpression: Expression<T>, failureMessage: FailureMessage) -> Bool {
let uncachedExpression = actualExpression.withoutCaching()
......@@ -34,25 +40,36 @@ struct AsyncMatcherWrapper<T, U where U: Matcher, U.ValueType == T>: Matcher {
}
}
private let toEventuallyRequiresClosureError = "expect(...).toEventually(...) requires an explicit closure (eg - expect { ... }.toEventually(...) )\nSwift 1.2 @autoclosure behavior has changed in an incompatible way for Nimble to function"
extension Expectation {
public func toEventually<U where U: Matcher, U.ValueType == T>(matcher: U, timeout: NSTimeInterval = 1, pollInterval: NSTimeInterval = 0.01) {
to(AsyncMatcherWrapper(
fullMatcher: FullMatcherWrapper(
matcher: matcher,
to: "to eventually",
toNot: "to eventually not"),
timeoutInterval: timeout,
pollInterval: pollInterval))
if expression.isClosure {
to(AsyncMatcherWrapper(
fullMatcher: FullMatcherWrapper(
matcher: matcher,
to: "to eventually",
toNot: "to eventually not"),
timeoutInterval: timeout,
pollInterval: pollInterval))
} else {
verify(false, toEventuallyRequiresClosureError)
}
}
public func toEventuallyNot<U where U: Matcher, U.ValueType == T>(matcher: U, timeout: NSTimeInterval = 1, pollInterval: NSTimeInterval = 0.01) {
toNot(AsyncMatcherWrapper(
fullMatcher: FullMatcherWrapper(
matcher: matcher,
to: "to eventually",
toNot: "to eventually not"),
timeoutInterval: timeout,
pollInterval: pollInterval))
if expression.isClosure {
toNot(AsyncMatcherWrapper(
fullMatcher: FullMatcherWrapper(
matcher: matcher,
to: "to eventually",
toNot: "to eventually not"),
timeoutInterval: timeout,
pollInterval: pollInterval))
} else {
verify(false, toEventuallyRequiresClosureError)
}
}
public func toEventually<U where U: BasicMatcher, U.ValueType == T>(matcher: U, timeout: NSTimeInterval = 1, pollInterval: NSTimeInterval = 0.01) {
......
......@@ -96,6 +96,10 @@ NIMBLE_EXPORT id<NMBMatcher> NMB_match(id expectedValue);
NIMBLE_SHORT(id<NMBMatcher> match(id expectedValue),
NMB_match(expectedValue));
NIMBLE_EXPORT id<NMBMatcher> NMB_allPass(id matcher);
NIMBLE_SHORT(id<NMBMatcher> allPass(id matcher),
NMB_allPass(matcher));
// In order to preserve breakpoint behavior despite using macros to fill in __FILE__ and __LINE__,
// define a builder that populates __FILE__ and __LINE__, and returns a block that takes timeout
// and action arguments. See https://github.com/Quick/Quick/pull/185 for details.
......
......@@ -84,18 +84,22 @@ NIMBLE_EXPORT id<NMBMatcher> NMB_match(id expectedValue) {
return [NMBObjCMatcher matchMatcher:expectedValue];
}
NIMBLE_EXPORT id<NMBMatcher> NMB_allPass(id expectedValue) {
return [NMBObjCMatcher allPassMatcher:expectedValue];
}
NIMBLE_EXPORT NMBObjCRaiseExceptionMatcher *NMB_raiseException() {
return [NMBObjCMatcher raiseExceptionMatcher];
}
NIMBLE_EXPORT NMBWaitUntilTimeoutBlock nmb_wait_until_timeout_builder(NSString *file, NSUInteger line) {
return ^(NSTimeInterval timeout, void (^action)(void (^)(void))) {
[NMBWait untilTimeout:timeout action:action file:file line:line];
[NMBWait untilTimeout:timeout file:file line:line action:action];
};
}
NIMBLE_EXPORT NMBWaitUntilBlock nmb_wait_until_builder(NSString *file, NSUInteger line) {
return ^(void (^action)(void (^)(void))) {
[NMBWait until:action file:file line:line];
[NMBWait untilFile:file line:line action:action];
};
}
# Nimble
[![Build Status](https://travis-ci.org/Quick/Nimble.svg?branch=master)](https://travis-ci.org/Quick/Nimble)
[![Build Status](https://travis-ci.org/Quick/Nimble.svg?branch=swift-1.1)](https://travis-ci.org/Quick/Nimble)
Use Nimble to express the expected outcomes of Swift
or Objective-C expressions. Inspired by
......@@ -40,6 +40,7 @@ expect(ocean.isClean).toEventually(beTruthy())
- [Exceptions](#exceptions)
- [Collection Membership](#collection-membership)
- [Strings](#strings)
- [Checking if all elements of a collection pass a condition](#checking-if-all-elements-of-a-collection-pass-a-condition)