Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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