-
-
Save alemar11/5be14b4439c85c36d618ba0b8aa9e3e0 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