Last active
July 4, 2022 10:12
-
-
Save ytyubox/89990452142f78a832b16d05600ade18 to your computer and use it in GitHub Desktop.
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
extension Result { | |
func tryMap<T>(_ transform:(Success) throws -> T) -> Result<T, Swift.Error> { | |
switch self { | |
case let .success(success): | |
do { | |
return .success(try transform(success)) | |
} catch { | |
return .failure(error) | |
} | |
case let .failure(failure): | |
return .failure(failure) | |
} | |
} | |
} | |
import XCTest | |
class ResultTryMapTests: XCTestCase { | |
private typealias Mapper<Input, Output> = (Input) throws -> Output | |
func testTryMapSouldSuccesIfSuccessfullyTransform() throws { | |
let alwaysSuccessMapper: Mapper<Int, String> = { _ in "any text" } | |
let sut = Result<Int, Error>.success(1) | |
let result = try XCTUnwrap(try? sut.tryMap(alwaysSuccessMapper).get()) | |
XCTAssertEqual(result, "any text") | |
} | |
func testTryMapSouldFailureWithNewErrorIfFailsTransform() throws { | |
let alwaysThrowsMapper: Mapper<Int, String> = { _ in throw AnyError.anyFailure } | |
let sut = Result<Int, Error>.success(1) | |
let result = sut.tryMap(alwaysThrowsMapper) | |
XCTAssertThrowsError(try result.get()) { | |
error in | |
let anyError = error as? AnyError | |
XCTAssertNotNil(anyError) | |
XCTAssertEqual(anyError, .anyFailure) | |
} | |
} | |
func testTryMapSouldFailureWithOldErrorIfResultAlreadyAFailure() throws { | |
let alwaysThrowsMapper: Mapper<Int, String> = { _ in throw AnyError.anyFailure } | |
let sut = Result<Int, Error>.failure(AnyError.originalFailure) | |
let result = sut.tryMap(alwaysThrowsMapper) | |
XCTAssertThrowsError(try result.get()) { | |
error in | |
let anyError = error as? AnyError | |
XCTAssertNotNil(anyError) | |
XCTAssertEqual(anyError, .originalFailure) | |
} | |
} | |
func testTryMapWillExcuteTransformOnlyOnceIfResultisASuccess() throws { | |
var captured = [Int]() | |
let alwaysSuccessMapper: Mapper<Int, String> = { input in | |
captured.append(input) | |
return "" | |
} | |
let sut = Result<Int, Error>.success(0) | |
_ = sut.tryMap(alwaysSuccessMapper) | |
XCTAssertEqual(captured, [0]) | |
} | |
func testTryMapWillExcuteTransformOnlyOnceIfResultAlreadyAFailure() throws { | |
var captured = [Int]() | |
let alwaysSuccessMapper: Mapper<Int, String> = { input in | |
captured.append(input) | |
return "" | |
} | |
let sut = Result<Int, Error>.failure(AnyError.originalFailure) | |
_ = sut.tryMap(alwaysSuccessMapper) | |
XCTAssertTrue(captured.isEmpty) | |
} | |
func testTryMapWillExcuteTransformOnlyOnceIfResultAlreadyASuccessOnTransformIsSuccess() throws { | |
var captured = [Int]() | |
let alwaysSuccessMapper: Mapper<Int, String> = { input in | |
captured.append(input) | |
return "" | |
} | |
let sut = Result<Int, Error>.success(0) | |
_ = sut.tryMap(alwaysSuccessMapper) | |
XCTAssertEqual(captured, [0]) | |
} | |
func testTryMapWillExcuteTransformOnlyOnceIfResultAlreadyASuccessOnTransformIsThrows() throws { | |
var captured = [Int]() | |
let alwaysThrowsMapper: Mapper<Int, String> = { input in | |
captured.append(input) | |
throw AnyError.anyFailure | |
} | |
let sut = Result<Int, Error>.success(0) | |
_ = sut.tryMap(alwaysThrowsMapper) | |
XCTAssertEqual(captured, [0]) | |
} | |
// MARK: - helper | |
private enum AnyError: Error { | |
case anyFailure | |
case originalFailure | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment