Files
SwiftShell/SwiftShellTests/CatchingFire.swift
T
Kare Morstol d6055c6062 Remove CatchingFire framework and add it as a single file.
Carthage 0.9.1 is not compatible with the catching fire framework as it has too many SDKs (5). It seems 2 is the limit. In any case it was a bit too much trouble and overhead just to include the functionality of this one file.
2015-09-19 19:09:30 +02:00

162 lines
5.2 KiB
Swift

//
// CatchingFire.swift
// CatchingFire
//
// Created by Marius Rackwitz on 7.7.15.
// Copyright © 2015 Marius Rackwitz. All rights reserved.
//
// Copied from https://github.com/mrackwitz/CatchingFire/blob/master/src/CatchingFire.swift
import XCTest
/// This allows you to write safe tests for the happy path of failable functions.
/// It helps you to avoid the `try!` operator in tests.
///
/// If you want to test a function, which may fail in general, you may think of using `try`.
/// But this would mean that you have to declare your test method as throwing, which causes that
/// XCTest doesn't execute the test anymore.
///
/// So in consequence, you would usually need to write:
///
/// XCTAssertEqual(try! fib(x), 21)
///
/// If the expression fails, your whole test suite doesn't execute further and aborts immediately,
/// which is very undesirable, especially on CI, but also for your workflow when you use TDD.
///
/// Instead you can write now:
///
/// AssertNoThrow {
/// XCTAssertEqual(try fib(x), 21)
/// }
///
/// Or alternatively:
///
/// AssertNoThrow(try fib(x)).map { (y: Int) in
/// XCTAssertEqual(y, 21)
/// }
///
/// If the expression fails, your test fails.
///
public func AssertNoThrow<R>(@autoclosure closure: () throws -> R) -> R? {
var result: R?
AssertNoThrow() {
result = try closure()
}
return result
}
public func AssertNoThrow(@noescape closure: () throws -> ()) {
do {
try closure()
} catch let error {
XCTFail("Caught unexpected error <\(error)>.")
}
}
/// This allows to easily write exhaustive tests for the exception paths of failable functions.
/// It helps you to avoid writing the same boilerplate code over and over again for tests.
///
/// If you want to test a function, that it fails for given arguments, you would usually need
/// to write:
///
/// do {
/// try fib(-1)
/// XCTFail("Expected to fail, but did not failed!")
/// } catch Error.ArgumentMayNotBeNegative {
/// // succeed silently
/// } catch error {
/// XCTFail("Failed with a different error than expected!")
/// }
///
/// Instead you can write now:
///
/// AssertThrows(Error.ArgumentMayNotBeNegative) {
/// try fib(-1)
/// }
///
/// If the expression or closure doesn't throw the expected error, your test fails.
///
public func AssertThrows<R, E where E: ErrorType>(expectedError: E, @autoclosure _ closure: () throws -> R) -> () {
AssertThrows(expectedError) { try closure() }
}
public func AssertThrows<E where E: ErrorType>(expectedError: E, @noescape _ closure: () throws -> ()) -> () {
do {
try closure()
XCTFail("Expected to catch <\(expectedError)>, "
+ "but no error was thrown.")
} catch expectedError {
return // that's what we expected
} catch {
XCTFail("Caught error <\(error)>, "
+ "but not of the expected type and value "
+ "<\(expectedError)>.")
}
}
public func AssertThrows<R, E where E: ErrorType, E: Equatable>(expectedError: E, @autoclosure _ closure: () throws -> R) -> () {
AssertThrows(expectedError) { try closure() }
}
public func AssertThrows<E where E: ErrorType, E: Equatable>(expectedError: E, @noescape _ closure: () throws -> ()) -> () {
do {
try closure()
XCTFail("Expected to catch <\(expectedError)>, "
+ "but no error was thrown.")
} catch let error as E {
XCTAssertEqual(error, expectedError,
"Caught error <\(error)> is of the expected type <\(E.self)>, "
+ "but not the expected case <\(expectedError)>.")
} catch {
XCTFail("Caught error <\(error)>, "
+ "but not of the expected type and value "
+ "<\(expectedError)>.")
}
}
/// Implement pattern matching for ErrorTypes
internal func ~=(lhs: ErrorType, rhs: ErrorType) -> Bool {
return lhs._domain == rhs._domain
&& rhs._code == rhs._code
}
/// Helper struct to catch errors thrown by others, which aren't publicly exposed.
///
/// Note:
/// Don't use this when a given ErrorType implementation exists.
/// If you want to use that to test errors thrown in your own framework, you should
/// consider to adopt an enumeration-based approach first in the framework code itself and expose
/// them instead as part of the public API. Even if you have some internal error cases, you can
//// put them in a separate enum and import your framework as `@testable` in your tests without
/// affecting the public API, if that matters.
///
public struct Error : ErrorType {
public let domain: String
public let code: Int
public var _domain: String {
return domain
}
public var _code: Int {
return code
}
}
/// Extend our Error type to conform `Equatable`.
extension Error : Equatable {}
/// Implement the `==` operator as required by protocol `Equatable`.
public func ==(lhs: Error, rhs: Error) -> Bool {
return lhs._domain == rhs._domain
&& lhs._code == rhs._code
}
/// Implement pattern matching for Error & ErrorType
public func ~=(lhs: Error, rhs: ErrorType) -> Bool {
return lhs._domain == rhs._domain
&& rhs._code == rhs._code
}