Created
October 21, 2016 16:02
-
-
Save matthew-healy/b433018964aa88b5358e82f01fdfda30 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
// Swift translation of https://pspdfkit.com/blog/2016/running-ui-tests-with-ludicrous-speed/ | |
class ConditionTester { | |
typealias TestCondition = () -> (Bool) | |
private let condition: TestCondition | |
private var fulfilled: Bool { return condition() } | |
private var currentRunLoop: CFRunLoop { | |
return RunLoop.current.getCFRunLoop() | |
} | |
init(condition: @escaping TestCondition) { | |
self.condition = condition | |
} | |
func wait(for timeout: TimeInterval) -> Bool { | |
let timer = getRepeatingTimer() | |
timer.resume() | |
let observer = getRunLoopObserver(checkingCondition: condition) | |
CFRunLoopAddObserver(currentRunLoop, observer, CFRunLoopMode.defaultMode) | |
CFRunLoopRunInMode(.defaultMode, timeout, false) | |
CFRunLoopRemoveObserver(currentRunLoop, observer, CFRunLoopMode.defaultMode) | |
timer.cancel() | |
return fulfilled | |
} | |
private func getRepeatingTimer() -> DispatchSourceTimer { | |
let timer: DispatchSourceTimer = DispatchSource.makeTimerSource(queue: getCurrentQueue()) | |
timer.scheduleRepeating( | |
deadline: .now(), | |
interval: .milliseconds(50), | |
leeway: .milliseconds(50) | |
) | |
timer.setEventHandler { /* noop */ } | |
return timer | |
} | |
private func getCurrentQueue() -> DispatchQueue { | |
let currentQueueName = String(validatingUTF8: __dispatch_queue_get_label(nil)) ?? "" | |
return DispatchQueue(label: currentQueueName) | |
} | |
private func getRunLoopObserver(checkingCondition condition: @escaping TestCondition) -> CFRunLoopObserver { | |
let observer = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, CFRunLoopActivity.beforeWaiting.rawValue, true, 0) { _ in | |
if self.fulfilled { | |
CFRunLoopStop(self.currentRunLoop) | |
} | |
} | |
return observer! | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Maybe this is of interest for you, especially the init method. http://stackoverflow.com/questions/24102617/how-to-use-swift-autoclosure