From 938bcb8324f859fa429cf597b8c4bd4521050ade Mon Sep 17 00:00:00 2001 From: Andhika Setiadi Date: Mon, 14 Aug 2023 12:28:30 +0700 Subject: [PATCH 1/4] add new init on TestStore to support init reducer with environment --- .../TestSupport/TestStore.swift | 91 +++++++++++-------- 1 file changed, 51 insertions(+), 40 deletions(-) diff --git a/Sources/RxComposableArchitecture/TestSupport/TestStore.swift b/Sources/RxComposableArchitecture/TestSupport/TestStore.swift index 50af393..6f4ab6a 100644 --- a/Sources/RxComposableArchitecture/TestSupport/TestStore.swift +++ b/Sources/RxComposableArchitecture/TestSupport/TestStore.swift @@ -487,46 +487,12 @@ public final class TestStore( + initialState: @autoclosure () -> State, + environment: Environment, + reducer prepareReducer: @escaping (Environment) -> R, + file: StaticString = #file, + line: UInt = #line + ) + where + R.State == State, + R.Action == Action, + State == ScopedState, + State: Equatable, + Action == ScopedAction + { + let environment = TaskBox(wrappedValue: environment) + let reducer = TestReducer( + Reduce( + internal: { state, action in + prepareReducer(environment.wrappedValue).reduce(into: &state, action: action) + } + ), + initialState: initialState() + ) + self._environment = environment + self.file = file + self.fromScopedAction = { $0 } + self.line = line + self.reducer = reducer + self.timeout = 100 * NSEC_PER_MSEC + self.toScopedState = { $0 } + self.failingWhenNothingChange = true + self.useNewScope = true + + self.store = Store( + initialState: initialState(), + reducer: reducer, + useNewScope: useNewScope + ) + } + @available( iOS, deprecated: 9999, From 4285723e208509fb9351453c9d2c214e4a6b1912 Mon Sep 17 00:00:00 2001 From: Andhika Setiadi Date: Fri, 18 Aug 2023 00:17:11 +0700 Subject: [PATCH 2/4] add Unit Test --- .../EnvironmentReducerProtocolTests.swift | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 Tests/RxComposableArchitectureTests/EnvironmentReducerProtocolTests.swift diff --git a/Tests/RxComposableArchitectureTests/EnvironmentReducerProtocolTests.swift b/Tests/RxComposableArchitectureTests/EnvironmentReducerProtocolTests.swift new file mode 100644 index 0000000..f9e2ee8 --- /dev/null +++ b/Tests/RxComposableArchitectureTests/EnvironmentReducerProtocolTests.swift @@ -0,0 +1,87 @@ +// +// EnvironmentReducerProtocolTests.swift +// +// +// Created by andhika.setiadi on 17/08/23. +// + +import XCTest +@testable import RxComposableArchitecture +@testable import XCTestDynamicOverlay + +internal final class EnvironmentReducerProtocolTests: XCTestCase { + + internal func testEnvironmentReducerProtocol_getSuccess() { + struct Authenticator: ReducerProtocol { + typealias State = String + typealias Action = Void + + internal var authenticatorService: AuthenticatorService + + func reduce(into state: inout String, action: Void) -> Effect { + switch authenticatorService.getAuthResult() { + case let .success(successMessage): + state = successMessage + case let .failure(failureData): + state = failureData.message + } + return .none + } + } + + let testStore = TestStore( + initialState: "", + environment: AuthenticatorService.mock, + reducer: Authenticator.init(authenticatorService:) + ) + + testStore.environment.getAuthResult = { + .success("success") + } + + testStore.send(()) { + $0 = "success" + } + + testStore.environment.getAuthResult = { + .failure(Failure(message: "Failed")) + } + + testStore.send(()) { + $0 = "Failed" + } + } +} + +private struct Failure: Error { + let message: String +} + +private struct AuthenticatorService { + var getAuthResult: () -> Result + + static var live: AuthenticatorService { + return AuthenticatorService( + getAuthResult: { + let isSuccess = Bool.random() + + if isSuccess { + return Result.success("Success Login") + } + + return Result.failure(Failure(message: "Failed Login")) + } + ) + } + + static var mock: AuthenticatorService { + return AuthenticatorService( + getAuthResult: unimplemented( + "Unimplemented getAuthResult", + placeholder: .failure( + Failure(message: "Need Mock") + ) + ) + ) + } +} From ddd610537c164608f8a517908f0fff1b2acffd10 Mon Sep 17 00:00:00 2001 From: Andhika Setiadi Date: Fri, 18 Aug 2023 00:19:04 +0700 Subject: [PATCH 3/4] improve docs --- Sources/RxComposableArchitecture/TestSupport/TestStore.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/RxComposableArchitecture/TestSupport/TestStore.swift b/Sources/RxComposableArchitecture/TestSupport/TestStore.swift index 6f4ab6a..8280a21 100644 --- a/Sources/RxComposableArchitecture/TestSupport/TestStore.swift +++ b/Sources/RxComposableArchitecture/TestSupport/TestStore.swift @@ -665,7 +665,7 @@ public final class TestStore Date: Fri, 18 Aug 2023 00:23:07 +0700 Subject: [PATCH 4/4] improve test --- .../EnvironmentReducerProtocolTests.swift | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/Tests/RxComposableArchitectureTests/EnvironmentReducerProtocolTests.swift b/Tests/RxComposableArchitectureTests/EnvironmentReducerProtocolTests.swift index f9e2ee8..516a6b7 100644 --- a/Tests/RxComposableArchitectureTests/EnvironmentReducerProtocolTests.swift +++ b/Tests/RxComposableArchitectureTests/EnvironmentReducerProtocolTests.swift @@ -60,20 +60,6 @@ private struct Failure: Error { private struct AuthenticatorService { var getAuthResult: () -> Result - static var live: AuthenticatorService { - return AuthenticatorService( - getAuthResult: { - let isSuccess = Bool.random() - - if isSuccess { - return Result.success("Success Login") - } - - return Result.failure(Failure(message: "Failed Login")) - } - ) - } - static var mock: AuthenticatorService { return AuthenticatorService( getAuthResult: unimplemented(