Swift Xcode Asynchronous Testing

A while back I posted my tweak to some Xcode testing for asynchronous calls. Here’s an update I did in Swift for XCTestCase.

extension XCTestCase {
  /**
   For use testing async functions.
   Will wait for completion of the function.
   You need to provide a test function for when the call is completed.
   The ultimate timeout should be provided for cases of there not
   being a response.
   
   let _ = self.waitUntilReady(completionTest: { () -> Bool in
   return remoteInterface?.isBusy == false
   })
   
   or as a trailing closure:
   
   let _ = self.waitUntilReady() {
   return remoteInterface?.isBusy == false
   }
   
   optionally using your own timeout:
   
   let _ = self.waitUntilReady(timeout: 20) {
   return remoteInterface?.isBusy == false
   }
   
   */
  func waitUntilReady(timeout seconds:TimeInterval = 30, completionTest: () -> Bool) -> TimeInterval {
    let start = Date.timeIntervalSinceReferenceDate
    let loopUntil = Date(timeIntervalSinceNow: seconds)
    
    while completionTest() == false && loopUntil.timeIntervalSinceNow > 0 {
      RunLoop.current.run(mode: .defaultRunLoopMode, before: loopUntil)
    }
    
    let finish = NSDate.timeIntervalSinceReferenceDate
    let runtime = finish - start
    return runtime
  }
}