|
|
@@ -152,8 +152,8 @@ class ResultTestCase: BaseTestCase {
|
|
|
let value = "success value"
|
|
|
|
|
|
// When
|
|
|
- let result1 = Result(value: { value }) // syntax 1
|
|
|
- let result2 = Result { value } // syntax 2
|
|
|
+ let result1 = Result(value: { value })
|
|
|
+ let result2 = Result { value }
|
|
|
|
|
|
// Then
|
|
|
for result in [result1, result2] {
|
|
|
@@ -167,8 +167,8 @@ class ResultTestCase: BaseTestCase {
|
|
|
struct ResultError: Error {}
|
|
|
|
|
|
// When
|
|
|
- let result1 = Result(value: { throw ResultError() }) // syntax 1
|
|
|
- let result2 = Result { throw ResultError() } // syntax 2
|
|
|
+ let result1 = Result(value: { throw ResultError() })
|
|
|
+ let result2 = Result { throw ResultError() }
|
|
|
|
|
|
// Then
|
|
|
for result in [result1, result2] {
|
|
|
@@ -180,11 +180,14 @@ class ResultTestCase: BaseTestCase {
|
|
|
// MARK: - Unwrap Tests
|
|
|
|
|
|
func testThatUnwrapReturnsSuccessValue() {
|
|
|
- // Given, When
|
|
|
+ // Given
|
|
|
let result = Result<String>.success("success value")
|
|
|
|
|
|
+ // When
|
|
|
+ let unwrappedValue = try? result.unwrap()
|
|
|
+
|
|
|
// Then
|
|
|
- XCTAssertEqual(try result.unwrap(), "success value")
|
|
|
+ XCTAssertEqual(unwrappedValue, "success value")
|
|
|
}
|
|
|
|
|
|
func testThatUnwrapThrowsFailureError() {
|
|
|
@@ -246,7 +249,7 @@ class ResultTestCase: BaseTestCase {
|
|
|
}
|
|
|
|
|
|
func testThatFlatMapCatchesTransformationError() {
|
|
|
- // Given, When
|
|
|
+ // Given
|
|
|
struct TransformError: Error {}
|
|
|
let result = Result<String>.success("success value")
|
|
|
|
|
|
@@ -262,7 +265,7 @@ class ResultTestCase: BaseTestCase {
|
|
|
}
|
|
|
|
|
|
func testThatFlatMapPreservesFailureError() {
|
|
|
- // Given, When
|
|
|
+ // Given
|
|
|
struct ResultError: Error {}
|
|
|
struct TransformError: Error {}
|
|
|
let result = Result<String>.failure(ResultError())
|
|
|
@@ -277,4 +280,194 @@ class ResultTestCase: BaseTestCase {
|
|
|
XCTFail("flatMap should preserve the failure error")
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ // MARK: - map/flatMapError Tests
|
|
|
+
|
|
|
+ func testMapErrorTransformsErrorValue() {
|
|
|
+ // Given
|
|
|
+ struct ResultError: Error {}
|
|
|
+ struct OtherError: Error { let error: Error }
|
|
|
+ let result: Result<String> = .failure(ResultError())
|
|
|
+
|
|
|
+ // When
|
|
|
+ let mappedResult = result.mapError { OtherError(error: $0) }
|
|
|
+
|
|
|
+ // Then
|
|
|
+ if let error = mappedResult.error {
|
|
|
+ XCTAssertTrue(error is OtherError)
|
|
|
+ } else {
|
|
|
+ XCTFail("mapError should transform error value")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func testMapErrorPreservesSuccessError() {
|
|
|
+ // Given
|
|
|
+ struct ResultError: Error {}
|
|
|
+ struct OtherError: Error { let error: Error }
|
|
|
+ let result: Result<String> = .success("success")
|
|
|
+
|
|
|
+ // When
|
|
|
+ let mappedResult = result.mapError { OtherError(error: $0) }
|
|
|
+
|
|
|
+ // Then
|
|
|
+ XCTAssertEqual(mappedResult.value, "success")
|
|
|
+ }
|
|
|
+
|
|
|
+ func testFlatMapErrorTransformsErrorValue() {
|
|
|
+ // Given
|
|
|
+ struct ResultError: Error {}
|
|
|
+ struct OtherError: Error { let error: Error }
|
|
|
+ let result: Result<String> = .failure(ResultError())
|
|
|
+
|
|
|
+ // When
|
|
|
+ let mappedResult = result.flatMapError { OtherError(error: $0) }
|
|
|
+
|
|
|
+ // Then
|
|
|
+ if let error = mappedResult.error {
|
|
|
+ XCTAssertTrue(error is OtherError)
|
|
|
+ } else {
|
|
|
+ XCTFail("mapError should transform error value")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func testFlatMapErrorCapturesThrownError() {
|
|
|
+ // Given
|
|
|
+ struct ResultError: Error {}
|
|
|
+ struct OtherError: Error {
|
|
|
+ let error: Error
|
|
|
+ init(error: Error) throws { throw ThrownError() }
|
|
|
+ }
|
|
|
+ struct ThrownError: Error {}
|
|
|
+ let result: Result<String> = .failure(ResultError())
|
|
|
+
|
|
|
+ // When
|
|
|
+ let mappedResult = result.flatMapError { try OtherError(error: $0) }
|
|
|
+ // Then
|
|
|
+ if let error = mappedResult.error {
|
|
|
+ XCTAssertTrue(error is ThrownError)
|
|
|
+ } else {
|
|
|
+ XCTFail("mapError should capture thrown error value")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // MARK: with/if Tests
|
|
|
+
|
|
|
+ func testWithValueExecutesWhenSuccess() {
|
|
|
+ // Given
|
|
|
+ let result: Result<String> = .success("success")
|
|
|
+ var string = "failure"
|
|
|
+
|
|
|
+ // When
|
|
|
+ result.withValue { string = $0 }
|
|
|
+
|
|
|
+ // Then
|
|
|
+ XCTAssertEqual(string, "success")
|
|
|
+ }
|
|
|
+
|
|
|
+ func testWithValueDoesNotExecutesWhenFailure() {
|
|
|
+ // Given
|
|
|
+ struct ResultError: Error {}
|
|
|
+ let result: Result<String> = .failure(ResultError())
|
|
|
+ var string = "failure"
|
|
|
+
|
|
|
+ // When
|
|
|
+ result.withValue { string = $0 }
|
|
|
+
|
|
|
+ // Then
|
|
|
+ XCTAssertEqual(string, "failure")
|
|
|
+ }
|
|
|
+
|
|
|
+ func testWithErrorExecutesWhenFailure() {
|
|
|
+ // Given
|
|
|
+ struct ResultError: Error {}
|
|
|
+ let result: Result<String> = .failure(ResultError())
|
|
|
+ var string = "success"
|
|
|
+
|
|
|
+ // When
|
|
|
+ result.withError { string = "\(type(of: $0))" }
|
|
|
+
|
|
|
+ // Then
|
|
|
+ XCTAssertEqual(string, "(ResultError #1)")
|
|
|
+ }
|
|
|
+
|
|
|
+ func testWithErrorDoesNotExecuteWhenSuccess() {
|
|
|
+ // Given
|
|
|
+ let result: Result<String> = .success("success")
|
|
|
+ var string = "success"
|
|
|
+
|
|
|
+ // When
|
|
|
+ result.withError { string = "\(type(of: $0))" }
|
|
|
+
|
|
|
+ // Then
|
|
|
+ XCTAssertEqual(string, "success")
|
|
|
+ }
|
|
|
+
|
|
|
+ func testIfSuccessExecutesWhenSuccess() {
|
|
|
+ // Given
|
|
|
+ let result: Result<String> = .success("success")
|
|
|
+ var string = "failure"
|
|
|
+
|
|
|
+ // When
|
|
|
+ result.ifSuccess { string = "success" }
|
|
|
+
|
|
|
+ // Then
|
|
|
+ XCTAssertEqual(string, "success")
|
|
|
+ }
|
|
|
+
|
|
|
+ func testIfSuccessDoesNotExecutesWhenFailure() {
|
|
|
+ // Given
|
|
|
+ struct ResultError: Error {}
|
|
|
+ let result: Result<String> = .failure(ResultError())
|
|
|
+ var string = "failure"
|
|
|
+
|
|
|
+ // When
|
|
|
+ result.ifSuccess { string = "success" }
|
|
|
+
|
|
|
+ // Then
|
|
|
+ XCTAssertEqual(string, "failure")
|
|
|
+ }
|
|
|
+
|
|
|
+ func testIfFailureExecutesWhenFailure() {
|
|
|
+ // Given
|
|
|
+ struct ResultError: Error {}
|
|
|
+ let result: Result<String> = .failure(ResultError())
|
|
|
+ var string = "success"
|
|
|
+
|
|
|
+ // When
|
|
|
+ result.ifFailure { string = "failure" }
|
|
|
+
|
|
|
+ // Then
|
|
|
+ XCTAssertEqual(string, "failure")
|
|
|
+ }
|
|
|
+
|
|
|
+ func testIfFailureDoesNotExecuteWhenSuccess() {
|
|
|
+ // Given
|
|
|
+ let result: Result<String> = .success("success")
|
|
|
+ var string = "success"
|
|
|
+
|
|
|
+ // When
|
|
|
+ result.ifFailure { string = "failure" }
|
|
|
+
|
|
|
+ // Then
|
|
|
+ XCTAssertEqual(string, "success")
|
|
|
+ }
|
|
|
+
|
|
|
+ func testFunctionalMethodsCanBeChained() {
|
|
|
+ // Given
|
|
|
+ struct ResultError: Error {}
|
|
|
+ let result: Result<String> = .success("first")
|
|
|
+ var string = "first"
|
|
|
+ var success = false
|
|
|
+
|
|
|
+ // When
|
|
|
+ let endResult = result.map { _ in "second" }
|
|
|
+ .flatMap { _ in "third" }
|
|
|
+ .withValue { if $0 == "third" { string = "fourth" } }
|
|
|
+ .ifSuccess { success = true }
|
|
|
+
|
|
|
+ // Then
|
|
|
+ XCTAssertEqual(endResult.value, "third")
|
|
|
+ XCTAssertEqual(string, "fourth")
|
|
|
+ XCTAssertTrue(success)
|
|
|
+ }
|
|
|
}
|