mirror of
https://github.com/apple/swift-nio.git
synced 2026-05-20 20:30:36 +00:00
### Motivation: In some (probably niche) scenarios, especially in pre-Concurrency UI applications on Darwin, it can be useful to wait for an a value whilst still running the current `RunLoop`. That allows the UI and other things to work whilst we're waiting for a future to complete. ### Modifications: - Add `NIOFoundationCompat.EventLoopFuture.waitSpinningRunLoop()`. ### Result: Better compatibility with Cocoa.
65 lines
2.1 KiB
Swift
65 lines
2.1 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the SwiftNIO open source project
|
|
//
|
|
// Copyright (c) 2024 Apple Inc. and the SwiftNIO project authors
|
|
// Licensed under Apache License v2.0
|
|
//
|
|
// See LICENSE.txt for license information
|
|
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import NIO
|
|
import NIOFoundationCompat
|
|
import XCTest
|
|
|
|
final class WaitSpinningRunLoopTests: XCTestCase {
|
|
private let loop = MultiThreadedEventLoopGroup.singleton.any()
|
|
|
|
func testPreFailedWorks() {
|
|
struct Dummy: Error {}
|
|
let future: EventLoopFuture<Never> = self.loop.makeFailedFuture(Dummy())
|
|
XCTAssertThrowsError(try future.waitSpinningRunLoop()) { error in
|
|
XCTAssert(error is Dummy)
|
|
}
|
|
}
|
|
|
|
func testPreSucceededWorks() {
|
|
let future = self.loop.makeSucceededFuture("hello")
|
|
XCTAssertEqual("hello", try future.waitSpinningRunLoop())
|
|
}
|
|
|
|
func testFailingAfterALittleWhileWorks() {
|
|
struct Dummy: Error {}
|
|
let future: EventLoopFuture<Never> = self.loop.scheduleTask(in: .milliseconds(10)) {
|
|
throw Dummy()
|
|
}.futureResult
|
|
XCTAssertThrowsError(try future.waitSpinningRunLoop()) { error in
|
|
XCTAssert(error is Dummy)
|
|
}
|
|
}
|
|
|
|
func testSucceedingAfterALittleWhileWorks() {
|
|
let future = self.loop.scheduleTask(in: .milliseconds(10)) {
|
|
"hello"
|
|
}.futureResult
|
|
XCTAssertEqual("hello", try future.waitSpinningRunLoop())
|
|
}
|
|
|
|
func testWeCanStillUseOurRunLoopWhilstBlocking() {
|
|
let promise = self.loop.makePromise(of: String.self)
|
|
let myRunLoop = RunLoop.current
|
|
let timer = Timer(timeInterval: 0.1, repeats: false) { [loop = self.loop] _ in
|
|
loop.scheduleTask(in: .microseconds(10)) {
|
|
promise.succeed("hello")
|
|
}
|
|
}
|
|
myRunLoop.add(timer, forMode: .default)
|
|
XCTAssertEqual("hello", try promise.futureResult.waitSpinningRunLoop())
|
|
}
|
|
|
|
}
|