From 5b6ce6a132c26fc4b4530a3cd70e7dadb7818520 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Fri, 21 Oct 2022 11:31:40 +0200 Subject: [PATCH] Migrate WelcomeFeature to ReducerProtocol --- .../WelcomeFeature/WelcomeComponent.swift | 64 ++++++++++++++ .../WelcomeFeature/WelcomeFeature.swift | 83 ------------------- .../Sources/WelcomeFeature/WelcomeView.swift | 11 ++- ...ests.swift => WelcomeComponentTests.swift} | 30 +++---- 4 files changed, 82 insertions(+), 106 deletions(-) create mode 100644 Examples/xx-messenger/Sources/WelcomeFeature/WelcomeComponent.swift delete mode 100644 Examples/xx-messenger/Sources/WelcomeFeature/WelcomeFeature.swift rename Examples/xx-messenger/Tests/WelcomeFeatureTests/{WelcomeFeatureTests.swift => WelcomeComponentTests.swift} (60%) diff --git a/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeComponent.swift b/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeComponent.swift new file mode 100644 index 00000000..55af6703 --- /dev/null +++ b/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeComponent.swift @@ -0,0 +1,64 @@ +import ComposableArchitecture +import SwiftUI +import XXMessengerClient + +public struct WelcomeComponent: ReducerProtocol { + public struct State: Equatable { + public init( + isCreatingCMix: Bool = false, + failure: String? = nil + ) { + self.isCreatingAccount = isCreatingCMix + self.failure = failure + } + + public var isCreatingAccount: Bool + public var failure: String? + } + + public enum Action: Equatable { + case newAccountTapped + case restoreTapped + case finished + case failed(String) + } + + public init() {} + + @Dependency(\.app.messenger) var messenger: Messenger + @Dependency(\.app.mainQueue) var mainQueue: AnySchedulerOf<DispatchQueue> + @Dependency(\.app.bgQueue) var bgQueue: AnySchedulerOf<DispatchQueue> + + public func reduce(into state: inout State, action: Action) -> EffectTask<Action> { + switch action { + case .newAccountTapped: + state.isCreatingAccount = true + state.failure = nil + return .future { fulfill in + do { + try messenger.create() + fulfill(.success(.finished)) + } + catch { + fulfill(.success(.failed(error.localizedDescription))) + } + } + .subscribe(on: bgQueue) + .receive(on: mainQueue) + .eraseToEffect() + + case .restoreTapped: + return .none + + case .finished: + state.isCreatingAccount = false + state.failure = nil + return .none + + case .failed(let failure): + state.isCreatingAccount = false + state.failure = failure + return .none + } + } +} diff --git a/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeFeature.swift b/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeFeature.swift deleted file mode 100644 index 66e9ef1b..00000000 --- a/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeFeature.swift +++ /dev/null @@ -1,83 +0,0 @@ -import ComposableArchitecture -import SwiftUI -import XXMessengerClient - -public struct WelcomeState: Equatable { - public init( - isCreatingCMix: Bool = false, - failure: String? = nil - ) { - self.isCreatingAccount = isCreatingCMix - self.failure = failure - } - - public var isCreatingAccount: Bool - public var failure: String? -} - -public enum WelcomeAction: Equatable { - case newAccountTapped - case restoreTapped - case finished - case failed(String) -} - -public struct WelcomeEnvironment { - public init( - messenger: Messenger, - mainQueue: AnySchedulerOf<DispatchQueue>, - bgQueue: AnySchedulerOf<DispatchQueue> - ) { - self.messenger = messenger - self.mainQueue = mainQueue - self.bgQueue = bgQueue - } - - public var messenger: Messenger - public var mainQueue: AnySchedulerOf<DispatchQueue> - public var bgQueue: AnySchedulerOf<DispatchQueue> -} - -#if DEBUG -extension WelcomeEnvironment { - public static let unimplemented = WelcomeEnvironment( - messenger: .unimplemented, - mainQueue: .unimplemented, - bgQueue: .unimplemented - ) -} -#endif - -public let welcomeReducer = Reducer<WelcomeState, WelcomeAction, WelcomeEnvironment> -{ state, action, env in - switch action { - case .newAccountTapped: - state.isCreatingAccount = true - state.failure = nil - return .future { fulfill in - do { - try env.messenger.create() - fulfill(.success(.finished)) - } - catch { - fulfill(.success(.failed(error.localizedDescription))) - } - } - .subscribe(on: env.bgQueue) - .receive(on: env.mainQueue) - .eraseToEffect() - - case .restoreTapped: - return .none - - case .finished: - state.isCreatingAccount = false - state.failure = nil - return .none - - case .failed(let failure): - state.isCreatingAccount = false - state.failure = failure - return .none - } -} diff --git a/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeView.swift b/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeView.swift index 64396fe1..0b4597e1 100644 --- a/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeView.swift +++ b/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeView.swift @@ -3,14 +3,14 @@ import ComposableArchitecture import SwiftUI public struct WelcomeView: View { - public init(store: Store<WelcomeState, WelcomeAction>) { + public init(store: StoreOf<WelcomeComponent>) { self.store = store } - let store: Store<WelcomeState, WelcomeAction> + let store: StoreOf<WelcomeComponent> struct ViewState: Equatable { - init(_ state: WelcomeState) { + init(_ state: WelcomeComponent.State) { isCreatingAccount = state.isCreatingAccount failure = state.failure } @@ -69,9 +69,8 @@ public struct WelcomeView: View { public struct WelcomeView_Previews: PreviewProvider { public static var previews: some View { WelcomeView(store: Store( - initialState: WelcomeState(), - reducer: .empty, - environment: () + initialState: WelcomeComponent.State(), + reducer: EmptyReducer() )) } } diff --git a/Examples/xx-messenger/Tests/WelcomeFeatureTests/WelcomeFeatureTests.swift b/Examples/xx-messenger/Tests/WelcomeFeatureTests/WelcomeComponentTests.swift similarity index 60% rename from Examples/xx-messenger/Tests/WelcomeFeatureTests/WelcomeFeatureTests.swift rename to Examples/xx-messenger/Tests/WelcomeFeatureTests/WelcomeComponentTests.swift index c6f23b7a..4d2391d3 100644 --- a/Examples/xx-messenger/Tests/WelcomeFeatureTests/WelcomeFeatureTests.swift +++ b/Examples/xx-messenger/Tests/WelcomeFeatureTests/WelcomeComponentTests.swift @@ -2,8 +2,7 @@ import ComposableArchitecture import XCTest @testable import WelcomeFeature -@MainActor -final class WelcomeFeatureTests: XCTestCase { +final class WelcomeComponentTests: XCTestCase { func testNewAccountTapped() { let mainQueue = DispatchQueue.test let bgQueue = DispatchQueue.test @@ -11,14 +10,13 @@ final class WelcomeFeatureTests: XCTestCase { var didCreateMessenger = 0 let store = TestStore( - initialState: WelcomeState(), - reducer: welcomeReducer, - environment: .unimplemented + initialState: WelcomeComponent.State(), + reducer: WelcomeComponent() ) - store.environment.mainQueue = mainQueue.eraseToAnyScheduler() - store.environment.bgQueue = bgQueue.eraseToAnyScheduler() - store.environment.messenger.create.run = { didCreateMessenger += 1 } + store.dependencies.app.mainQueue = mainQueue.eraseToAnyScheduler() + store.dependencies.app.bgQueue = bgQueue.eraseToAnyScheduler() + store.dependencies.app.messenger.create.run = { didCreateMessenger += 1 } store.send(.newAccountTapped) { $0.isCreatingAccount = true @@ -44,14 +42,13 @@ final class WelcomeFeatureTests: XCTestCase { let bgQueue = DispatchQueue.test let store = TestStore( - initialState: WelcomeState(), - reducer: welcomeReducer, - environment: .unimplemented + initialState: WelcomeComponent.State(), + reducer: WelcomeComponent() ) - store.environment.mainQueue = mainQueue.eraseToAnyScheduler() - store.environment.bgQueue = bgQueue.eraseToAnyScheduler() - store.environment.messenger.create.run = { throw failure } + store.dependencies.app.mainQueue = mainQueue.eraseToAnyScheduler() + store.dependencies.app.bgQueue = bgQueue.eraseToAnyScheduler() + store.dependencies.app.messenger.create.run = { throw failure } store.send(.newAccountTapped) { $0.isCreatingAccount = true @@ -69,9 +66,8 @@ final class WelcomeFeatureTests: XCTestCase { func testRestore() { let store = TestStore( - initialState: WelcomeState(), - reducer: welcomeReducer, - environment: .unimplemented + initialState: WelcomeComponent.State(), + reducer: WelcomeComponent() ) store.send(.restoreTapped) -- GitLab