From 6d8016da7726878a0131540c6c6a7f060a69fcad Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Fri, 21 Oct 2022 10:46:35 +0200 Subject: [PATCH] Migrate ContactLookupFeature to ReducerProtocol --- .../ContactLookupComponent.swift | 62 ++++++++++++++ .../ContactLookupFeature.swift | 83 ------------------- .../ContactLookupView.swift | 11 ++- ...wift => ContactLookupComponentTests.swift} | 24 +++--- 4 files changed, 78 insertions(+), 102 deletions(-) create mode 100644 Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupComponent.swift delete mode 100644 Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupFeature.swift rename Examples/xx-messenger/Tests/ContactLookupFeatureTests/{ContactLookupFeatureTests.swift => ContactLookupComponentTests.swift} (60%) diff --git a/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupComponent.swift b/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupComponent.swift new file mode 100644 index 00000000..b581f3f0 --- /dev/null +++ b/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupComponent.swift @@ -0,0 +1,62 @@ +import ComposableArchitecture +import Foundation +import XCTestDynamicOverlay +import XXClient +import XXMessengerClient + +public struct ContactLookupComponent: ReducerProtocol { + public struct State: Equatable { + public init( + id: Data, + isLookingUp: Bool = false, + failure: String? = nil + ) { + self.id = id + self.isLookingUp = isLookingUp + self.failure = failure + } + + public var id: Data + public var isLookingUp: Bool + public var failure: String? + } + + public enum Action: Equatable { + case lookupTapped + case didLookup(XXClient.Contact) + case didFail(NSError) + } + + @Dependency(\.appDependencies.messenger) var messenger + @Dependency(\.appDependencies.mainQueue) var mainQueue + @Dependency(\.appDependencies.bgQueue) var bgQueue + + public func reduce(into state: inout State, action: Action) -> EffectTask<Action> { + switch action { + case .lookupTapped: + state.isLookingUp = true + state.failure = nil + return Effect.result { [state] in + do { + let contact = try messenger.lookupContact(id: state.id) + return .success(.didLookup(contact)) + } catch { + return .success(.didFail(error as NSError)) + } + } + .subscribe(on: bgQueue) + .receive(on: mainQueue) + .eraseToEffect() + + case .didLookup(_): + state.isLookingUp = false + state.failure = nil + return .none + + case .didFail(let error): + state.isLookingUp = false + state.failure = error.localizedDescription + return .none + } + } +} diff --git a/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupFeature.swift b/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupFeature.swift deleted file mode 100644 index 0b6f92dd..00000000 --- a/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupFeature.swift +++ /dev/null @@ -1,83 +0,0 @@ -import ComposableArchitecture -import Foundation -import XCTestDynamicOverlay -import XXClient -import XXMessengerClient - -public struct ContactLookupState: Equatable { - public init( - id: Data, - isLookingUp: Bool = false, - failure: String? = nil - ) { - self.id = id - self.isLookingUp = isLookingUp - self.failure = failure - } - - public var id: Data - public var isLookingUp: Bool - public var failure: String? -} - -public enum ContactLookupAction: Equatable { - case lookupTapped - case didLookup(XXClient.Contact) - case didFail(NSError) -} - -public struct ContactLookupEnvironment { - 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 ContactLookupEnvironment { - public static let unimplemented = ContactLookupEnvironment( - messenger: .unimplemented, - mainQueue: .unimplemented, - bgQueue: .unimplemented - ) -} -#endif - -public let contactLookupReducer = Reducer<ContactLookupState, ContactLookupAction, ContactLookupEnvironment> -{ state, action, env in - switch action { - case .lookupTapped: - state.isLookingUp = true - state.failure = nil - return Effect.result { [state] in - do { - let contact = try env.messenger.lookupContact(id: state.id) - return .success(.didLookup(contact)) - } catch { - return .success(.didFail(error as NSError)) - } - } - .subscribe(on: env.bgQueue) - .receive(on: env.mainQueue) - .eraseToEffect() - - case .didLookup(_): - state.isLookingUp = false - state.failure = nil - return .none - - case .didFail(let error): - state.isLookingUp = false - state.failure = error.localizedDescription - return .none - } -} diff --git a/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupView.swift b/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupView.swift index 6ce83eda..c4850fab 100644 --- a/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupView.swift +++ b/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupView.swift @@ -3,14 +3,14 @@ import ComposableArchitecture import SwiftUI public struct ContactLookupView: View { - public init(store: Store<ContactLookupState, ContactLookupAction>) { + public init(store: StoreOf<ContactLookupComponent>) { self.store = store } - let store: Store<ContactLookupState, ContactLookupAction> + let store: StoreOf<ContactLookupComponent> struct ViewState: Equatable { - init(state: ContactLookupState) { + init(state: ContactLookupComponent.State) { id = state.id isLookingUp = state.isLookingUp failure = state.failure @@ -64,11 +64,10 @@ public struct ContactLookupView_Previews: PreviewProvider { public static var previews: some View { NavigationView { ContactLookupView(store: Store( - initialState: ContactLookupState( + initialState: ContactLookupComponent.State( id: "1234".data(using: .utf8)! ), - reducer: .empty, - environment: () + reducer: EmptyReducer() )) } } diff --git a/Examples/xx-messenger/Tests/ContactLookupFeatureTests/ContactLookupFeatureTests.swift b/Examples/xx-messenger/Tests/ContactLookupFeatureTests/ContactLookupComponentTests.swift similarity index 60% rename from Examples/xx-messenger/Tests/ContactLookupFeatureTests/ContactLookupFeatureTests.swift rename to Examples/xx-messenger/Tests/ContactLookupFeatureTests/ContactLookupComponentTests.swift index 76dde8d0..dcbb3622 100644 --- a/Examples/xx-messenger/Tests/ContactLookupFeatureTests/ContactLookupFeatureTests.swift +++ b/Examples/xx-messenger/Tests/ContactLookupFeatureTests/ContactLookupComponentTests.swift @@ -3,20 +3,19 @@ import XCTest import XXClient @testable import ContactLookupFeature -final class ContactLookupFeatureTests: XCTestCase { +final class ContactLookupComponentTests: XCTestCase { func testLookup() { let id: Data = "1234".data(using: .utf8)! var didLookupId: [Data] = [] let lookedUpContact = Contact.unimplemented("123data".data(using: .utf8)!) let store = TestStore( - initialState: ContactLookupState(id: id), - reducer: contactLookupReducer, - environment: .unimplemented + initialState: ContactLookupComponent.State(id: id), + reducer: ContactLookupComponent() ) - store.environment.mainQueue = .immediate - store.environment.bgQueue = .immediate - store.environment.messenger.lookupContact.run = { id in + store.dependencies.appDependencies.mainQueue = .immediate + store.dependencies.appDependencies.bgQueue = .immediate + store.dependencies.appDependencies.messenger.lookupContact.run = { id in didLookupId.append(id) return lookedUpContact } @@ -39,13 +38,12 @@ final class ContactLookupFeatureTests: XCTestCase { let failure = NSError(domain: "test", code: 0) let store = TestStore( - initialState: ContactLookupState(id: id), - reducer: contactLookupReducer, - environment: .unimplemented + initialState: ContactLookupComponent.State(id: id), + reducer: ContactLookupComponent() ) - store.environment.mainQueue = .immediate - store.environment.bgQueue = .immediate - store.environment.messenger.lookupContact.run = { _ in throw failure } + store.dependencies.appDependencies.mainQueue = .immediate + store.dependencies.appDependencies.bgQueue = .immediate + store.dependencies.appDependencies.messenger.lookupContact.run = { _ in throw failure } store.send(.lookupTapped) { $0.isLookingUp = true -- GitLab