Skip to content

Commit

Permalink
Merge pull request #24 from railwaymen/fix_not_copying_error_parser
Browse files Browse the repository at this point in the history
Error Parser made a structure not a class for avoiding impact on loca…
  • Loading branch information
PiotrPawlus committed Jun 19, 2020
2 parents 68759b9 + 6aee829 commit 9d2bcca
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 40 deletions.
2 changes: 1 addition & 1 deletion Sources/Restler/Internal/RestlerRequestInternal.swift
Expand Up @@ -54,7 +54,7 @@ extension Restler {
self.encoder = dependencies.encoder
self.decoder = dependencies.decoder
self.dispatchQueueManager = dependencies.dispatchQueueManager
self.errorParser = dependencies.errorParser
self.errorParser = form.errorParser
self.method = dependencies.method.combinedWith(query: form.query, body: form.body)
self.errors = form.errors
self.header = form.header
Expand Down
18 changes: 7 additions & 11 deletions Sources/Restler/Public/Classes/Errors/ErrorParser.swift
@@ -1,30 +1,26 @@
import Foundation

extension Restler {
open class ErrorParser: RestlerErrorParserType {
private var decodingErrors: [RestlerErrorDecodable.Type] = []
public struct ErrorParser: RestlerErrorParserType {
public var decodingErrors: [RestlerErrorDecodable.Type] = []

// MARK: - Initialization
public init(decodingErrors: [RestlerErrorDecodable.Type] = []) {
self.decodingErrors = decodingErrors
}

// MARK: - Open
open func decode<T>(_ type: T.Type) where T: RestlerErrorDecodable {
// MARK: - Public
public mutating func decode<T>(_ type: T.Type) where T: RestlerErrorDecodable {
self.decodingErrors.append(type)
}

open func stopDecoding<T>(_ type: T.Type) where T: RestlerErrorDecodable {
public mutating func stopDecoding<T>(_ type: T.Type) where T: RestlerErrorDecodable {
self.decodingErrors.removeAll { $0 == type }
}

open func copy() -> RestlerErrorParserType {
return ErrorParser(decodingErrors: self.decodingErrors)
}

open func parse(_ error: Swift.Error) -> Swift.Error {
public func parse(_ error: Swift.Error) -> Swift.Error {
guard case let .request(_, response) = error as? Restler.Error else { return error }
let errors = decodingErrors.compactMap { $0.init(response: response) }
let errors = self.decodingErrors.compactMap { $0.init(response: response) }
if errors.isEmpty {
return error
} else if let first = errors.first, errors.count == 1 {
Expand Down
11 changes: 7 additions & 4 deletions Sources/Restler/Public/Classes/Request/RequestBuilder.swift
Expand Up @@ -10,10 +10,13 @@ extension Restler {
// MARK: - Initialization
internal init(
dependencies: Dependencies,
header: Restler.Header
header: Restler.Header,
errorParser: RestlerErrorParserType
) {
self.dependencies = dependencies
self.form = Form(header: header)
self.form = Form(
header: header,
errorParser: errorParser)
}
}
}
Expand All @@ -28,12 +31,12 @@ extension Restler.RequestBuilder {
let queryEncoder: RestlerQueryEncoderType
let multipartEncoder: RestlerMultipartEncoderType
let dispatchQueueManager: DispatchQueueManagerType
let errorParser: RestlerErrorParserType
let method: HTTPMethod
}

struct Form {
var header: Restler.Header
var errorParser: RestlerErrorParserType
var query: QueryParametersType?
var body: Data?
var errors: [Restler.Error] = []
Expand All @@ -49,7 +52,7 @@ extension Restler.RequestBuilder: RestlerBasicRequestBuilderType {
}

public func failureDecode<T>(_ type: T.Type) -> Self where T: RestlerErrorDecodable {
self.dependencies.errorParser.decode(type)
self.form.errorParser.decode(type)
return self
}

Expand Down
4 changes: 2 additions & 2 deletions Sources/Restler/Public/Classes/Restler.swift
Expand Up @@ -110,9 +110,9 @@ extension Restler {
queryEncoder: self.queryEncoder,
multipartEncoder: self.multipartEncoder,
dispatchQueueManager: self.dispatchQueueManager,
errorParser: self.errorParser,
method: method),
header: self.header)
header: self.header,
errorParser: self.errorParser)
}

private func url(for endpoint: RestlerEndpointable) -> URL {
Expand Down
Expand Up @@ -3,6 +3,9 @@ import Foundation
/// An object parsing the given error to given types of the RestlerErrorDecodables.
public protocol RestlerErrorParserType {

/// An array of all errors' types that will be tried to decode on request failure.
var decodingErrors: [RestlerErrorDecodable.Type] { get set }

/// Try to decode the error on failure of the data task.
///
/// If the request will end with error, the given error would be decoded if init of the error doesn't return nil.
Expand All @@ -14,17 +17,14 @@ public protocol RestlerErrorParserType {
/// - Parameters:
/// - type: A type for the error to be decoded. It will be added to an array of errors to decode on failed request.
///
func decode<T>(_ type: T.Type) where T: RestlerErrorDecodable
mutating func decode<T>(_ type: T.Type) where T: RestlerErrorDecodable

/// Removed the given error type from the array of error types to decode.
///
/// - Parameters:
/// - type: An error type to remove from decoding errors array.
///
func stopDecoding<T>(_ type: T.Type) where T: RestlerErrorDecodable

/// Creates a copy of the ErrorParser.
func copy() -> RestlerErrorParserType
mutating func stopDecoding<T>(_ type: T.Type) where T: RestlerErrorDecodable

/// Tries to parse the given error into the decodable errors.
///
Expand Down
12 changes: 12 additions & 0 deletions Tests/RestlerTests/Mocks/Public/RestlerErrorParserMock.swift
Expand Up @@ -4,6 +4,9 @@ import Restler
class RestlerErrorParserMock {

// MARK: - RestlerErrorParserType
var decodingErrorsReturnValue: [RestlerErrorDecodable.Type] = []
private(set) var decodingErrorsSetValues: [[RestlerErrorDecodable.Type]] = []

private(set) var decodeParams: [DecodeParams] = []
struct DecodeParams {
let type: Any
Expand All @@ -25,6 +28,15 @@ class RestlerErrorParserMock {

// MARK: - RestlerErrorParserType
extension RestlerErrorParserMock: RestlerErrorParserType {
var decodingErrors: [RestlerErrorDecodable.Type] {
get {
self.decodingErrorsReturnValue
}
set {
self.decodingErrorsSetValues.append(newValue)
}
}

func decode<T>(_ type: T.Type) where T: RestlerErrorDecodable {
self.decodeParams.append(DecodeParams(type: type))
}
Expand Down
19 changes: 2 additions & 17 deletions Tests/RestlerTests/Tests/Unit/ErrorParserTests.swift
Expand Up @@ -38,7 +38,7 @@ extension ErrorParserTests {

func testParse_decodableError_addedByDecode() throws {
//Arrange
let sut = Restler.ErrorParser()
var sut = Restler.ErrorParser()
sut.decode(DecodableErrorMock.self)
let response = Restler.Response(data: nil, response: nil, error: TestError())
//Act
Expand Down Expand Up @@ -69,7 +69,7 @@ extension ErrorParserTests {
extension ErrorParserTests {
func testStopDecoding() {
//Arrange
let sut = Restler.ErrorParser(decodingErrors: [DecodableErrorMock.self, DecodableErrorMock.self])
var sut = Restler.ErrorParser(decodingErrors: [DecodableErrorMock.self, DecodableErrorMock.self])
sut.decode(DecodableErrorMock.self)
let response = Restler.Response(data: nil, response: nil, error: TestError())
let expectedError = Restler.Error.request(type: .unknownError, response: response)
Expand All @@ -80,18 +80,3 @@ extension ErrorParserTests {
XCTAssertEqual(error as? Restler.Error, expectedError)
}
}

// MARK: - copy()
extension ErrorParserTests {
func testCopy() {
//Arrange
let sut = Restler.ErrorParser(decodingErrors: [DecodableErrorMock.self])
let response = Restler.Response(data: nil, response: nil, error: TestError())
//Act
let copy = sut.copy()
copy.stopDecoding(DecodableErrorMock.self)
//Assert
let error = sut.parse(Restler.Error.request(type: .unknownError, response: response))
XCTAssert(error is DecodableErrorMock)
}
}

0 comments on commit 9d2bcca

Please sign in to comment.