Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support both Swift 3.x and Swift 4 #457

Merged
merged 4 commits into from
Aug 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Nimble.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1796,6 +1796,7 @@
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
TVOS_DEPLOYMENT_TARGET = 9.0;
Expand Down Expand Up @@ -1850,6 +1851,7 @@
METAL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
TVOS_DEPLOYMENT_TARGET = 9.0;
Expand Down
26 changes: 13 additions & 13 deletions Sources/Nimble/Adapters/NMBExpectation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ public class NMBExpectation: NSObject {
}
}

public var withTimeout: (TimeInterval) -> NMBExpectation {
@objc public var withTimeout: (TimeInterval) -> NMBExpectation {
return ({ timeout in self._timeout = timeout
return self
})
}

public var to: (NMBMatcher) -> Void {
@objc public var to: (NMBMatcher) -> Void {
return ({ matcher in
if let pred = matcher as? NMBPredicate {
self.expectValue.to(from(objcPredicate: pred))
Expand All @@ -65,7 +65,7 @@ public class NMBExpectation: NSObject {
})
}

public var toWithDescription: (NMBMatcher, String) -> Void {
@objc public var toWithDescription: (NMBMatcher, String) -> Void {
return ({ matcher, description in
if let pred = matcher as? NMBPredicate {
self.expectValue.to(from(objcPredicate: pred), description: description)
Expand All @@ -75,7 +75,7 @@ public class NMBExpectation: NSObject {
})
}

public var toNot: (NMBMatcher) -> Void {
@objc public var toNot: (NMBMatcher) -> Void {
return ({ matcher in
if let pred = matcher as? NMBPredicate {
self.expectValue.toNot(from(objcPredicate: pred))
Expand All @@ -85,7 +85,7 @@ public class NMBExpectation: NSObject {
})
}

public var toNotWithDescription: (NMBMatcher, String) -> Void {
@objc public var toNotWithDescription: (NMBMatcher, String) -> Void {
return ({ matcher, description in
if let pred = matcher as? NMBPredicate {
self.expectValue.toNot(from(objcPredicate: pred), description: description)
Expand All @@ -95,11 +95,11 @@ public class NMBExpectation: NSObject {
})
}

public var notTo: (NMBMatcher) -> Void { return toNot }
@objc public var notTo: (NMBMatcher) -> Void { return toNot }

public var notToWithDescription: (NMBMatcher, String) -> Void { return toNotWithDescription }
@objc public var notToWithDescription: (NMBMatcher, String) -> Void { return toNotWithDescription }

public var toEventually: (NMBMatcher) -> Void {
@objc public var toEventually: (NMBMatcher) -> Void {
return ({ matcher in
if let pred = matcher as? NMBPredicate {
self.expectValue.toEventually(
Expand All @@ -117,7 +117,7 @@ public class NMBExpectation: NSObject {
})
}

public var toEventuallyWithDescription: (NMBMatcher, String) -> Void {
@objc public var toEventuallyWithDescription: (NMBMatcher, String) -> Void {
return ({ matcher, description in
if let pred = matcher as? NMBPredicate {
self.expectValue.toEventually(
Expand All @@ -135,7 +135,7 @@ public class NMBExpectation: NSObject {
})
}

public var toEventuallyNot: (NMBMatcher) -> Void {
@objc public var toEventuallyNot: (NMBMatcher) -> Void {
return ({ matcher in
if let pred = matcher as? NMBPredicate {
self.expectValue.toEventuallyNot(
Expand All @@ -153,7 +153,7 @@ public class NMBExpectation: NSObject {
})
}

public var toEventuallyNotWithDescription: (NMBMatcher, String) -> Void {
@objc public var toEventuallyNotWithDescription: (NMBMatcher, String) -> Void {
return ({ matcher, description in
if let pred = matcher as? NMBPredicate {
self.expectValue.toEventuallyNot(
Expand All @@ -171,9 +171,9 @@ public class NMBExpectation: NSObject {
})
}

public var toNotEventually: (NMBMatcher) -> Void { return toEventuallyNot }
@objc public var toNotEventually: (NMBMatcher) -> Void { return toEventuallyNot }

public var toNotEventuallyWithDescription: (NMBMatcher, String) -> Void { return toEventuallyNotWithDescription }
@objc public var toNotEventuallyWithDescription: (NMBMatcher, String) -> Void { return toEventuallyNotWithDescription }

@objc public class func failWithMessage(_ message: String, file: FileString, line: UInt) {
fail(message, location: SourceLocation(file: file, line: line))
Expand Down
24 changes: 20 additions & 4 deletions Sources/Nimble/DSL+Wait.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ private enum ErrorResult {
/// 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.
internal class NMBWait: NSObject {
// About these kind of lines, `@objc` attributes are only required for Objective-C
// support, so that should be conditional on Darwin platforms and normal Xcode builds
// (non-SwiftPM builds).
#if (os(macOS) || os(iOS) || os(tvOS) || os(watchOS)) && !SWIFT_PACKAGE
@objc
internal class func until(
timeout: TimeInterval,
file: FileString = #file,
Expand All @@ -20,6 +25,17 @@ internal class NMBWait: NSObject {
action(done)
}
}
#else
internal class func until(
timeout: TimeInterval,
file: FileString = #file,
line: UInt = #line,
action: @escaping (@escaping () -> Void) -> Void) {
return throwableUntil(timeout: timeout, file: file, line: line) { done in
action(done)
}
}
#endif

// Using a throwable closure makes this method not objc compatible.
internal class func throwableUntil(
Expand Down Expand Up @@ -70,16 +86,16 @@ internal class NMBWait: NSObject {
}
}

#if SWIFT_PACKAGE
#if (os(macOS) || os(iOS) || os(tvOS) || os(watchOS)) && !SWIFT_PACKAGE
@objc(untilFile:line:action:)
internal class func until(_ file: FileString = #file, line: UInt = #line, action: @escaping (() -> Void) -> Void) {
until(timeout: 1, file: file, line: line, action: action)
}
#else
@objc(untilFile:line:action:)
#else
internal class func until(_ file: FileString = #file, line: UInt = #line, action: @escaping (() -> Void) -> Void) {
until(timeout: 1, file: file, line: line, action: action)
}
#endif
#endif
}

internal func blockedRunLoopErrorMessageFor(_ fnName: String, leeway: TimeInterval) -> String {
Expand Down
6 changes: 3 additions & 3 deletions Sources/Nimble/Matchers/BeCloseTo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public class NMBObjCBeCloseToMatcher: NSObject, NMBMatcher {
_delta = within
}

public func matches(_ actualExpression: @escaping () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool {
@objc public func matches(_ actualExpression: @escaping () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool {
let actualBlock: () -> NMBDoubleConvertible? = ({
return actualExpression() as? NMBDoubleConvertible
})
Expand All @@ -52,7 +52,7 @@ public class NMBObjCBeCloseToMatcher: NSObject, NMBMatcher {
return try! matcher.matches(expr, failureMessage: failureMessage)
}

public func doesNotMatch(_ actualExpression: @escaping () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool {
@objc public func doesNotMatch(_ actualExpression: @escaping () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool {
let actualBlock: () -> NMBDoubleConvertible? = ({
return actualExpression() as? NMBDoubleConvertible
})
Expand All @@ -61,7 +61,7 @@ public class NMBObjCBeCloseToMatcher: NSObject, NMBMatcher {
return try! matcher.doesNotMatch(expr, failureMessage: failureMessage)
}

public var within: (CDouble) -> NMBObjCBeCloseToMatcher {
@objc public var within: (CDouble) -> NMBObjCBeCloseToMatcher {
return ({ delta in
return NMBObjCBeCloseToMatcher(expected: self._expected, within: delta)
})
Expand Down
12 changes: 6 additions & 6 deletions Sources/Nimble/Matchers/RaisesException.swift
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public class NMBObjCRaiseExceptionMatcher: NSObject, NMBMatcher {
_block = block
}

public func matches(_ actualBlock: @escaping () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool {
@objc public func matches(_ actualBlock: @escaping () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool {
let block: () -> Any? = ({ _ = actualBlock(); return nil })
let expr = Expression(expression: block, location: location)

Expand All @@ -126,11 +126,11 @@ public class NMBObjCRaiseExceptionMatcher: NSObject, NMBMatcher {
).matches(expr, failureMessage: failureMessage)
}

public func doesNotMatch(_ actualBlock: @escaping () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool {
@objc public func doesNotMatch(_ actualBlock: @escaping () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool {
return !matches(actualBlock, failureMessage: failureMessage, location: location)
}

public var named: (_ name: String) -> NMBObjCRaiseExceptionMatcher {
@objc public var named: (_ name: String) -> NMBObjCRaiseExceptionMatcher {
return ({ name in
return NMBObjCRaiseExceptionMatcher(
name: name,
Expand All @@ -141,7 +141,7 @@ public class NMBObjCRaiseExceptionMatcher: NSObject, NMBMatcher {
})
}

public var reason: (_ reason: String?) -> NMBObjCRaiseExceptionMatcher {
@objc public var reason: (_ reason: String?) -> NMBObjCRaiseExceptionMatcher {
return ({ reason in
return NMBObjCRaiseExceptionMatcher(
name: self._name,
Expand All @@ -152,7 +152,7 @@ public class NMBObjCRaiseExceptionMatcher: NSObject, NMBMatcher {
})
}

public var userInfo: (_ userInfo: NSDictionary?) -> NMBObjCRaiseExceptionMatcher {
@objc public var userInfo: (_ userInfo: NSDictionary?) -> NMBObjCRaiseExceptionMatcher {
return ({ userInfo in
return NMBObjCRaiseExceptionMatcher(
name: self._name,
Expand All @@ -163,7 +163,7 @@ public class NMBObjCRaiseExceptionMatcher: NSObject, NMBMatcher {
})
}

public var satisfyingBlock: (_ block: ((NSException) -> Void)?) -> NMBObjCRaiseExceptionMatcher {
@objc public var satisfyingBlock: (_ block: ((NSException) -> Void)?) -> NMBObjCRaiseExceptionMatcher {
return ({ block in
return NMBObjCRaiseExceptionMatcher(
name: self._name,
Expand Down
15 changes: 14 additions & 1 deletion Sources/Nimble/Utils/Async.swift
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,18 @@ internal class AwaitPromiseBuilder<T> {
// checked.
//
// In addition, stopping the run loop is used to halt code executed on the main run loop.
#if swift(>=4.0)
trigger.timeoutSource.schedule(
deadline: DispatchTime.now() + timeoutInterval,
repeating: .never,
leeway: timeoutLeeway
)
#else
trigger.timeoutSource.scheduleOneshot(
deadline: DispatchTime.now() + timeoutInterval,
leeway: timeoutLeeway)
leeway: timeoutLeeway
)
#endif
trigger.timeoutSource.setEventHandler {
guard self.promise.asyncResult.isIncomplete() else { return }
let timedOutSem = DispatchSemaphore(value: 0)
Expand Down Expand Up @@ -320,7 +329,11 @@ internal class Awaiter {
let asyncSource = createTimerSource(asyncQueue)
let trigger = AwaitTrigger(timeoutSource: timeoutSource, actionSource: asyncSource) {
let interval = DispatchTimeInterval.nanoseconds(Int(pollInterval * TimeInterval(NSEC_PER_SEC)))
#if swift(>=4.0)
asyncSource.schedule(deadline: .now(), repeating: interval, leeway: pollLeeway)
#else
asyncSource.scheduleRepeating(deadline: .now(), interval: interval, leeway: pollLeeway)
#endif
asyncSource.setEventHandler {
do {
if let result = try closure() {
Expand Down
8 changes: 5 additions & 3 deletions Tests/NimbleTests/Helpers/utils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,21 @@ func deferToMainQueue(action: @escaping () -> Void) {
}
}

#if (os(macOS) || os(iOS) || os(tvOS) || os(watchOS)) && !SWIFT_PACKAGE
public class NimbleHelper: NSObject {
public class func expectFailureMessage(_ message: NSString, block: @escaping () -> Void, file: FileString, line: UInt) {
@objc public class func expectFailureMessage(_ message: NSString, block: @escaping () -> Void, file: FileString, line: UInt) {
failsWithErrorMessage(String(describing: message), file: file, line: line, preferOriginalSourceLocation: true, closure: block)
}

public class func expectFailureMessages(_ messages: [NSString], block: @escaping () -> Void, file: FileString, line: UInt) {
@objc public class func expectFailureMessages(_ messages: [NSString], block: @escaping () -> Void, file: FileString, line: UInt) {
failsWithErrorMessage(messages.map({String(describing: $0)}), file: file, line: line, preferOriginalSourceLocation: true, closure: block)
}

public class func expectFailureMessageForNil(_ message: NSString, block: @escaping () -> Void, file: FileString, line: UInt) {
@objc public class func expectFailureMessageForNil(_ message: NSString, block: @escaping () -> Void, file: FileString, line: UInt) {
failsWithErrorMessageForNil(String(describing: message), file: file, line: line, preferOriginalSourceLocation: true, closure: block)
}
}
#endif

extension Date {
init(dateTimeString: String) {
Expand Down