Skip to content

Commit

Permalink
Merge pull request #2 from stefanrenne/feature/result
Browse files Browse the repository at this point in the history
Feature/result
  • Loading branch information
Stefan Renne authored Dec 30, 2019
2 parents 38d4b2a + 672762b commit 32f3700
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 1 deletion.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,16 @@ Observable<User>
.disposed(by: disposeBag)
```


### Bonus: Result Support

```swift
let errorHandler = ErrorHandler.default(for: self)
let result: Result<User, NetworkError> = .failure(NetworkError.authenticate)
let user: User? = result.get(onError: errorHandler)
```


## Customization options

### The way actions are performed for errors
Expand Down
20 changes: 20 additions & 0 deletions Sources/SwiftErrorHandler/Extension/Result+ErrorHandler.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// Result+ErrorHandler.swift
// SwiftErrorHandler
//
// Created by Stefan Renne on 30/12/2019.
//

import Foundation

public extension Result {

func get(onError handler: ErrorHandler, onErrorCompleted: OnErrorHandled = nil) -> Success? {
do {
return try get()
} catch {
handler.handle(error: error, onCompleted: onErrorCompleted)
return nil
}
}
}
2 changes: 1 addition & 1 deletion Tests/SwiftErrorHandlerTests/Helpers/MockedView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class MockedView: ErrorHandlerView {
private let onCompletedGroups: DispatchGroup
var lastResult: UIAlertController?

init(numberExpectedPresentedAlerts: Int, numberExpectedCustomHandlers: Int, numberExpectedonCompleted: Int) {
init(numberExpectedPresentedAlerts: Int = 0, numberExpectedCustomHandlers: Int = 0, numberExpectedonCompleted: Int = 0) {
presentedAlertsGroups = DispatchGroup.enter(number: numberExpectedPresentedAlerts)
customHandlersGroup = DispatchGroup.enter(number: numberExpectedCustomHandlers)
onCompletedGroups = DispatchGroup.enter(number: numberExpectedonCompleted)
Expand Down
146 changes: 146 additions & 0 deletions Tests/SwiftErrorHandlerTests/ResultErrorHandlerTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
//
// ResultErrorHandlerTests.swift
// SwiftErrorHandlerTests
//
// Created by Stefan Renne on 30/12/2019.
//

import XCTest
@testable import SwiftErrorHandler

class ResultErrorHandlerTests: XCTestCase {

func testItWontHandleSuccessResults() throws {
let view = MockedView()
let handler = ErrorHandler(for: view)

let result: Result<String, HandlerError1> = .success("win")
XCTAssertNotNil(result.get(onError: handler, onErrorCompleted: view.onCompleted))
}

func testItCanHandleSpecificErrors() throws {
let view = MockedView(numberExpectedPresentedAlerts: 0, numberExpectedCustomHandlers: 1, numberExpectedonCompleted: 1)
let handler = ErrorHandler(for: view)
.on(error: .type(HandlerError1.error1), then: .perform(action: view.customHandler))

let result: Result<Bool, HandlerError1> = .failure(HandlerError1.error1)
XCTAssertNil(result.get(onError: handler, onErrorCompleted: view.onCompleted))

XCTAssertTrue(view.didHandleResult())
}

func testItCantHandleSpecificErrorsWhereThereAreNoSpecificHandlers() throws {
let view = MockedView(numberExpectedPresentedAlerts: 0, numberExpectedCustomHandlers: 1, numberExpectedonCompleted: 1)
let handler = ErrorHandler(for: view)
.on(error: .type(HandlerError1.error1), then: .perform(action: view.customHandler))

let result: Result<Bool, HandlerError1> = .failure(HandlerError1.error2)
XCTAssertNil(result.get(onError: handler, onErrorCompleted: view.onCompleted))

XCTAssertFalse(view.didHandleResult())
}

func testItCanFallbackToADefaultHandler() throws {
let view = MockedView(numberExpectedPresentedAlerts: 0, numberExpectedCustomHandlers: 1, numberExpectedonCompleted: 1)
let handler = ErrorHandler(for: view)
.on(error: .type(HandlerError1.error1), then: .perform(action: view.unexpectedHandlerExecuted))
.onNoMatch(.perform(action: view.customHandler))

let result: Result<Bool, HandlerError1> = .failure(HandlerError1.error2)
XCTAssertNil(result.get(onError: handler, onErrorCompleted: view.onCompleted))

XCTAssertTrue(view.didHandleResult())
}

func testItPrefersASpecficHandlerAboveTheDefaultHandler() throws {
let view = MockedView(numberExpectedPresentedAlerts: 0, numberExpectedCustomHandlers: 1, numberExpectedonCompleted: 1)
let handler = ErrorHandler(for: view)
.on(error: .type(HandlerError1.error1), then: .perform(action: view.customHandler))
.onNoMatch(.perform(action: view.unexpectedHandlerExecuted))

let result: Result<Bool, HandlerError1> = .failure(HandlerError1.error1)
XCTAssertNil(result.get(onError: handler, onErrorCompleted: view.onCompleted))

XCTAssertTrue(view.didHandleResult())
}

func testItCanExecuteMultupleMatches() throws {
let view = MockedView(numberExpectedPresentedAlerts: 0, numberExpectedCustomHandlers: 2, numberExpectedonCompleted: 1)
let handler = ErrorHandler(for: view)
.on(error: .type(HandlerError1.error1), then: .perform(action: view.customHandler))
.on(error: .type(HandlerError1.error1), then: .perform(action: view.customHandler))
.onNoMatch(.perform(action: view.unexpectedHandlerExecuted))

let result: Result<Bool, HandlerError1> = .failure(HandlerError1.error1)
XCTAssertNil(result.get(onError: handler, onErrorCompleted: view.onCompleted))

XCTAssertTrue(view.didHandleResult())
}

func testItCanHaveHandlersThatAlwaysGetExecuted() throws {
let view = MockedView(numberExpectedPresentedAlerts: 0, numberExpectedCustomHandlers: 2, numberExpectedonCompleted: 1)
let handler = ErrorHandler(for: view)
.on(error: .type(HandlerError1.error1), then: .perform(action: view.customHandler))
.onNoMatch(.perform(action: view.unexpectedHandlerExecuted))
.always(.perform(action: view.customHandler))

let result: Result<Bool, HandlerError1> = .failure(HandlerError1.error1)
XCTAssertNil(result.get(onError: handler, onErrorCompleted: view.onCompleted))

XCTAssertTrue(view.didHandleResult())
}

func testItCanHaveMultipleAlwaysHandlers() {
let view = MockedView(numberExpectedPresentedAlerts: 0, numberExpectedCustomHandlers: 3, numberExpectedonCompleted: 0)
let handler = ErrorHandler(for: view)
.always(.perform(action: view.customHandler))
.always(.perform(action: view.customHandler))
.always(.perform(action: view.customHandler))

let result: Result<Bool, HandlerError1> = .failure(HandlerError1.error1)
XCTAssertNil(result.get(onError: handler, onErrorCompleted: nil))

XCTAssertTrue(view.didHandleResult())
}

func testItCanHaveMultipleDefaultHandlers() {
let view = MockedView(numberExpectedPresentedAlerts: 0, numberExpectedCustomHandlers: 3, numberExpectedonCompleted: 0)
let handler = ErrorHandler(for: view)
.onNoMatch(.perform(action: view.customHandler))
.onNoMatch(.perform(action: view.customHandler))
.onNoMatch(.perform(action: view.customHandler))

let result: Result<Bool, HandlerError1> = .failure(HandlerError1.error1)
XCTAssertNil(result.get(onError: handler, onErrorCompleted: nil))

XCTAssertTrue(view.didHandleResult())
}
}

extension ResultErrorHandlerTests {
private enum HandlerError1: Error {
case error1
case error2
case error3
}

private enum HandlerError2: Error {
case error4
}

}

extension ResultErrorHandlerTests {

static var allTests = [
("testItWontHandleSuccessResults", testItWontHandleSuccessResults),
("testItCanHandleSpecificErrors", testItCanHandleSpecificErrors),
("testItCantHandleSpecificErrorsWhereThereAreNoSpecificHandlers", testItCantHandleSpecificErrorsWhereThereAreNoSpecificHandlers),
("testItCanFallbackToADefaultHandler", testItCanFallbackToADefaultHandler),
("testItPrefersASpecficHandlerAboveTheDefaultHandler", testItPrefersASpecficHandlerAboveTheDefaultHandler),
("testItCanExecuteMultupleMatches", testItCanExecuteMultupleMatches),
("testItCanHaveHandlersThatAlwaysGetExecuted", testItCanHaveHandlersThatAlwaysGetExecuted),
("testItCanHaveMultipleAlwaysHandlers", testItCanHaveMultipleAlwaysHandlers),
("testItCanHaveMultipleDefaultHandlers", testItCanHaveMultipleDefaultHandlers)
]
}
1 change: 1 addition & 0 deletions Tests/SwiftErrorHandlerTests/XCTestManifests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public func allTests() -> [XCTestCaseEntry] {
return [
testCase(ActionHandlerTests.allTests),
testCase(ErrorHandlerTests.allTests),
testCase(ResultErrorHandlerTests.allTests),
testCase(ErrorMatcherTests.allTests)
]
}
Expand Down

0 comments on commit 32f3700

Please sign in to comment.