Last active
December 3, 2017 16:35
-
-
Save rudolf-adamkovic/a37dbc4fda13700e65309503b9a676a7 to your computer and use it in GitHub Desktop.
PreconditionFailable protocol
This file contains hidden or 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
/* PRODUCTION */ | |
protocol PreconditionFailable { | |
associatedtype PreconditionFailure | |
} | |
extension PreconditionFailable { | |
static func precondition(_ condition: Bool, _ message: PreconditionFailure) { | |
guard !condition else { return } | |
PreconditionFailureHandler.trap(String(describing: message)) | |
RunLoop.spin() | |
} | |
static func preconditionFailure(_ message: PreconditionFailure) -> Never { | |
PreconditionFailureHandler.trap(String(describing: message)) | |
RunLoop.spin() | |
} | |
} | |
struct PreconditionFailureHandler { | |
static var trap: (String) -> Void = { message in | |
fatalError(message) | |
} | |
} | |
/* TESTING */ | |
protocol PreconditionFailableTesting { | |
associatedtype PreconditionFailableType: PreconditionFailable | |
} | |
extension PreconditionFailableTesting where Self: XCTestCase { | |
func expectPreconditionFailure( | |
_ expectedFailure: PreconditionFailableType.PreconditionFailure, | |
file: StaticString = #file, | |
line: UInt = #line, | |
trigger: @escaping () -> Void | |
) { | |
let failureExpectation = expectation(description: "Precondition failure testing expectation") | |
let originalTrap = PreconditionFailureHandler.trap | |
PreconditionFailureHandler.trap = { message in | |
XCTAssertEqual(message, String(describing: expectedFailure), file: file, line: line) | |
failureExpectation.fulfill() | |
RunLoop.spin() | |
} | |
DispatchQueue(label: "Precondition failure testing queue").async(execute: trigger) | |
waitForExpectations(timeout: 1) { error in | |
if error != nil { | |
let failureDescription = String(describing: expectedFailure) | |
XCTFail("Precondition failure: " + failureDescription, file: file, line: line) | |
} | |
} | |
PreconditionFailureHandler.trap = originalTrap | |
} | |
} | |
/* UTILITIES */ | |
extension RunLoop { | |
static func spin() -> Never { | |
repeat { | |
RunLoop.current.run() | |
} while (true) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment