addition of assertSuccess() and assertFailure() on EventLoopFuture (#2417)
* added assertSuccess() and assertFailure() * test functions for assertSuccess() and assertFailure() * removed callbacks approach and add precondition variants * added test for precondition variants * self.always to handle future w/o creating a promise, added fileID and line for debug * updated test for asserts on EventLoopFuture
This commit is contained in:
parent
546eaa261e
commit
7f4d10bd94
|
@ -2187,6 +2187,88 @@ extension EventLoopFuture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: assertion
|
||||||
|
|
||||||
|
extension EventLoopFuture {
|
||||||
|
/// Attaches a callback to the `EventLoopFuture` that asserts the original future's success.
|
||||||
|
///
|
||||||
|
/// If the original future fails, it triggers an assertion failure, causing a runtime error during development.
|
||||||
|
/// The assertion failure will include the file and line of the calling site.
|
||||||
|
///
|
||||||
|
/// - parameters:
|
||||||
|
/// - file: The file this function was called in, for debugging purposes.
|
||||||
|
/// - line: The line this function was called on, for debugging purposes.
|
||||||
|
@inlinable
|
||||||
|
public func assertSuccess(file: StaticString = #fileID, line: UInt = #line) -> EventLoopFuture<Value> {
|
||||||
|
return self.always { result in
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
()
|
||||||
|
case .failure(let error):
|
||||||
|
assertionFailure("Expected success, but got failure: \(error)", file: file, line: line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Attaches a callback to the `EventLoopFuture` that asserts the original future's failure.
|
||||||
|
///
|
||||||
|
/// If the original future succeeds, it triggers an assertion failure, causing a runtime error during development.
|
||||||
|
/// The assertion failure will include the file and line of the calling site.
|
||||||
|
///
|
||||||
|
/// - parameters:
|
||||||
|
/// - file: The file this function was called in, for debugging purposes.
|
||||||
|
/// - line: The line this function was called on, for debugging purposes.
|
||||||
|
@inlinable
|
||||||
|
public func assertFailure(file: StaticString = #fileID, line: UInt = #line) -> EventLoopFuture<Value> {
|
||||||
|
return self.always { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let value):
|
||||||
|
assertionFailure("Expected failure, but got success: \(value)", file: file, line: line)
|
||||||
|
case .failure:
|
||||||
|
()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attaches a callback to the `EventLoopFuture` that preconditions the original future's success.
|
||||||
|
///
|
||||||
|
/// If the original future fails, it triggers a precondition failure, causing a runtime error during development.
|
||||||
|
/// The precondition failure will include the file and line of the calling site.
|
||||||
|
///
|
||||||
|
/// - parameters:
|
||||||
|
/// - file: The file this function was called in, for debugging purposes.
|
||||||
|
/// - line: The line this function was called on, for debugging purposes.
|
||||||
|
@inlinable
|
||||||
|
public func preconditionSuccess(file: StaticString = #fileID, line: UInt = #line) -> EventLoopFuture<Value> {
|
||||||
|
return self.always { result in
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
()
|
||||||
|
case .failure(let error):
|
||||||
|
Swift.preconditionFailure("Expected success, but got failure: \(error)", file: file, line: line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attaches a callback to the `EventLoopFuture` that preconditions the original future's failure.
|
||||||
|
///
|
||||||
|
/// If the original future succeeds, it triggers a precondition failure, causing a runtime error during development.
|
||||||
|
/// The precondition failure will include the file and line of the calling site.
|
||||||
|
///
|
||||||
|
/// - parameters:
|
||||||
|
/// - file: The file this function was called in, for debugging purposes.
|
||||||
|
/// - line: The line this function was called on, for debugging purposes.
|
||||||
|
@inlinable
|
||||||
|
public func preconditionFailure(file: StaticString = #fileID, line: UInt = #line) -> EventLoopFuture<Value> {
|
||||||
|
return self.always { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let value):
|
||||||
|
Swift.preconditionFailure("Expected failure, but got success: \(value)", file: file, line: line)
|
||||||
|
case .failure:
|
||||||
|
()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An opaque identifier for a specific `EventLoopFuture`.
|
/// An opaque identifier for a specific `EventLoopFuture`.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1496,4 +1496,49 @@ class EventLoopFutureTest : XCTestCase {
|
||||||
|
|
||||||
XCTAssertEqual((1...10).reduce(0, +), try all.wait())
|
XCTAssertEqual((1...10).reduce(0, +), try all.wait())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testAssertSuccess() {
|
||||||
|
let eventLoop = EmbeddedEventLoop()
|
||||||
|
|
||||||
|
let promise = eventLoop.makePromise(of: String.self)
|
||||||
|
let assertedFuture = promise.futureResult.assertSuccess()
|
||||||
|
promise.succeed("hello")
|
||||||
|
|
||||||
|
XCTAssertNoThrow(try assertedFuture.wait())
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAssertFailure() {
|
||||||
|
let eventLoop = EmbeddedEventLoop()
|
||||||
|
|
||||||
|
let promise = eventLoop.makePromise(of: String.self)
|
||||||
|
let assertedFuture = promise.futureResult.assertFailure()
|
||||||
|
promise.fail(EventLoopFutureTestError.example)
|
||||||
|
|
||||||
|
XCTAssertThrowsError(try assertedFuture.wait()) { error in
|
||||||
|
XCTAssertEqual(error as? EventLoopFutureTestError, EventLoopFutureTestError.example)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testPreconditionSuccess() {
|
||||||
|
let eventLoop = EmbeddedEventLoop()
|
||||||
|
|
||||||
|
let promise = eventLoop.makePromise(of: String.self)
|
||||||
|
let preconditionedFuture = promise.futureResult.preconditionSuccess()
|
||||||
|
promise.succeed("hello")
|
||||||
|
|
||||||
|
XCTAssertNoThrow(try preconditionedFuture.wait())
|
||||||
|
}
|
||||||
|
|
||||||
|
func testPreconditionFailure() {
|
||||||
|
let eventLoop = EmbeddedEventLoop()
|
||||||
|
|
||||||
|
let promise = eventLoop.makePromise(of: String.self)
|
||||||
|
let preconditionedFuture = promise.futureResult.preconditionFailure()
|
||||||
|
promise.fail(EventLoopFutureTestError.example)
|
||||||
|
|
||||||
|
XCTAssertThrowsError(try preconditionedFuture.wait()) { error in
|
||||||
|
XCTAssertEqual(error as? EventLoopFutureTestError, EventLoopFutureTestError.example)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue