[#464] Migrate MultilineTextField to ReducerProtocol (#476)

- MultilineTextField migrated to ReducerProtocol
- unit and snapshot tests fixed
This commit is contained in:
Lukas Korba 2022-11-07 11:58:56 +01:00 committed by GitHub
parent 445e443a37
commit be558f00be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 76 additions and 97 deletions

View File

@ -18,6 +18,7 @@ typealias AnyTransactionAddressTextFieldReducer = AnyReducer<
TransactionAddressTextFieldReducer.Action, TransactionAddressTextFieldReducer.Action,
SendFlowEnvironment SendFlowEnvironment
> >
typealias AnyMultiLineTextFieldReducer = AnyReducer<MultiLineTextFieldReducer.State, MultiLineTextFieldReducer.Action, SendFlowEnvironment>
// MARK: - State // MARK: - State
@ -32,7 +33,7 @@ struct SendFlowState: Equatable {
var addMemoState: Bool var addMemoState: Bool
var isSendingTransaction = false var isSendingTransaction = false
var memoState: MultiLineTextFieldState var memoState: MultiLineTextFieldReducer.State
var route: Route? var route: Route?
var shieldedBalance = WalletBalance.zero var shieldedBalance = WalletBalance.zero
var transactionAddressInputState: TransactionAddressTextFieldReducer.State var transactionAddressInputState: TransactionAddressTextFieldReducer.State
@ -83,7 +84,7 @@ struct SendFlowState: Equatable {
enum SendFlowAction: Equatable { enum SendFlowAction: Equatable {
case addMemo(CheckCircleAction) case addMemo(CheckCircleAction)
case memo(MultiLineTextFieldAction) case memo(MultiLineTextFieldReducer.Action)
case onAppear case onAppear
case onDisappear case onDisappear
case sendConfirmationPressed case sendConfirmationPressed
@ -247,10 +248,13 @@ extension SendFlowReducer {
} }
) )
private static let memoReducer: SendFlowReducer = MultiLineTextFieldReducer.default.pullback( private static let memoReducer: SendFlowReducer = AnyMultiLineTextFieldReducer { _ in
MultiLineTextFieldReducer()
}
.pullback(
state: \SendFlowState.memoState, state: \SendFlowState.memoState,
action: /SendFlowAction.memo, action: /SendFlowAction.memo,
environment: { _ in MultiLineTextFieldEnvironment() } environment: { $0 }
) )
} }

View File

@ -8,69 +8,54 @@
import Foundation import Foundation
import ComposableArchitecture import ComposableArchitecture
typealias MultiLineTextFieldReducer = Reducer<MultiLineTextFieldState, MultiLineTextFieldAction, MultiLineTextFieldEnvironment> typealias MultiLineTextFieldStore = Store<MultiLineTextFieldReducer.State, MultiLineTextFieldReducer.Action>
typealias MultiLineTextFieldStore = Store<MultiLineTextFieldState, MultiLineTextFieldAction>
typealias MultiLineTextFieldViewStore = ViewStore<MultiLineTextFieldState, MultiLineTextFieldAction>
// MARK: - State struct MultiLineTextFieldReducer: ReducerProtocol {
struct State: Equatable {
struct MultiLineTextFieldState: Equatable { /// default 0, no char limit
/// default 0, no char limit var charLimit = 0
var charLimit = 0 @BindableState var text = ""
@BindableState var text = ""
var isCharLimited: Bool {
var isCharLimited: Bool { charLimit > 0
charLimit > 0 }
}
var textLength: Int {
var textLength: Int { text.count
text.count }
}
var isValid: Bool {
var isValid: Bool { charLimit > 0
charLimit > 0 ? textLength <= charLimit
? textLength <= charLimit : true
: true }
}
var charLimitText: String {
var charLimitText: String { charLimit > 0
charLimit > 0 ? isValid
? isValid ? "\(textLength)/\(charLimit)"
? "\(textLength)/\(charLimit)" : "char limit exceeded \(textLength)/\(charLimit)"
: "char limit exceeded \(textLength)/\(charLimit)" : ""
: "" }
} }
}
enum Action: Equatable, BindableAction {
// MARK: - Action case binding(BindingAction<MultiLineTextFieldReducer.State>)
}
enum MultiLineTextFieldAction: Equatable, BindableAction {
case binding(BindingAction<MultiLineTextFieldState>) var body: some ReducerProtocol<State, Action> {
} BindingReducer()
// MARK: - Environment Reduce { _, action in
switch action {
struct MultiLineTextFieldEnvironment { } case .binding(\.$text):
return .none
extension MultiLineTextFieldEnvironment {
static let live = MultiLineTextFieldEnvironment() case .binding:
return .none
static let mock = MultiLineTextFieldEnvironment() }
}
// MARK: - Reducer
extension MultiLineTextFieldReducer {
static let `default` = MultiLineTextFieldReducer { _, action, _ in
switch action {
case .binding(\.$text):
return .none
case .binding:
return .none
} }
} }
.binding()
} }
// MARK: - Store // MARK: - Store
@ -78,16 +63,15 @@ extension MultiLineTextFieldReducer {
extension MultiLineTextFieldStore { extension MultiLineTextFieldStore {
static let placeholder = MultiLineTextFieldStore( static let placeholder = MultiLineTextFieldStore(
initialState: .placeholder, initialState: .placeholder,
reducer: .default, reducer: MultiLineTextFieldReducer()
environment: MultiLineTextFieldEnvironment()
) )
} }
// MARK: - Placeholders // MARK: - Placeholders
extension MultiLineTextFieldState { extension MultiLineTextFieldReducer.State {
static let placeholder: MultiLineTextFieldState = { static let placeholder: MultiLineTextFieldReducer.State = {
var state = MultiLineTextFieldState() var state = MultiLineTextFieldReducer.State()
state.text = "test" state.text = "test"
return state return state
}() }()

View File

@ -12,9 +12,8 @@ import ComposableArchitecture
class MultiLineTextFieldTests: XCTestCase { class MultiLineTextFieldTests: XCTestCase {
func testIsCharLimited() throws { func testIsCharLimited() throws {
let store = TestStore( let store = TestStore(
initialState: MultiLineTextFieldState(charLimit: 1), initialState: MultiLineTextFieldReducer.State(charLimit: 1),
reducer: MultiLineTextFieldReducer.default, reducer: MultiLineTextFieldReducer()
environment: MultiLineTextFieldEnvironment()
) )
store.send(.binding(.set(\.$text, "test"))) { state in store.send(.binding(.set(\.$text, "test"))) { state in
@ -28,9 +27,8 @@ class MultiLineTextFieldTests: XCTestCase {
func testIsNotCharLimited() throws { func testIsNotCharLimited() throws {
let store = TestStore( let store = TestStore(
initialState: MultiLineTextFieldState(), initialState: MultiLineTextFieldReducer.State(),
reducer: MultiLineTextFieldReducer.default, reducer: MultiLineTextFieldReducer()
environment: MultiLineTextFieldEnvironment()
) )
store.send(.binding(.set(\.$text, "test"))) { state in store.send(.binding(.set(\.$text, "test"))) { state in
@ -44,9 +42,8 @@ class MultiLineTextFieldTests: XCTestCase {
func testTextLength() throws { func testTextLength() throws {
let store = TestStore( let store = TestStore(
initialState: MultiLineTextFieldState(), initialState: MultiLineTextFieldReducer.State(),
reducer: MultiLineTextFieldReducer.default, reducer: MultiLineTextFieldReducer()
environment: MultiLineTextFieldEnvironment()
) )
store.send(.binding(.set(\.$text, "test"))) { state in store.send(.binding(.set(\.$text, "test"))) { state in
@ -61,9 +58,8 @@ class MultiLineTextFieldTests: XCTestCase {
func testIsValid_CharLimit() throws { func testIsValid_CharLimit() throws {
let store = TestStore( let store = TestStore(
initialState: MultiLineTextFieldState(charLimit: 4), initialState: MultiLineTextFieldReducer.State(charLimit: 4),
reducer: MultiLineTextFieldReducer.default, reducer: MultiLineTextFieldReducer()
environment: MultiLineTextFieldEnvironment()
) )
store.send(.binding(.set(\.$text, "test"))) { state in store.send(.binding(.set(\.$text, "test"))) { state in
@ -77,9 +73,8 @@ class MultiLineTextFieldTests: XCTestCase {
func testIsValid_NoCharLimit() throws { func testIsValid_NoCharLimit() throws {
let store = TestStore( let store = TestStore(
initialState: MultiLineTextFieldState(), initialState: MultiLineTextFieldReducer.State(),
reducer: MultiLineTextFieldReducer.default, reducer: MultiLineTextFieldReducer()
environment: MultiLineTextFieldEnvironment()
) )
store.send(.binding(.set(\.$text, "test"))) { state in store.send(.binding(.set(\.$text, "test"))) { state in
@ -93,9 +88,8 @@ class MultiLineTextFieldTests: XCTestCase {
func testIsInvalid() throws { func testIsInvalid() throws {
let store = TestStore( let store = TestStore(
initialState: MultiLineTextFieldState(charLimit: 3), initialState: MultiLineTextFieldReducer.State(charLimit: 3),
reducer: MultiLineTextFieldReducer.default, reducer: MultiLineTextFieldReducer()
environment: MultiLineTextFieldEnvironment()
) )
store.send(.binding(.set(\.$text, "test"))) { state in store.send(.binding(.set(\.$text, "test"))) { state in
@ -109,9 +103,8 @@ class MultiLineTextFieldTests: XCTestCase {
func testCharLimitText_NoCharLimit() throws { func testCharLimitText_NoCharLimit() throws {
let store = TestStore( let store = TestStore(
initialState: MultiLineTextFieldState(), initialState: MultiLineTextFieldReducer.State(),
reducer: MultiLineTextFieldReducer.default, reducer: MultiLineTextFieldReducer()
environment: MultiLineTextFieldEnvironment()
) )
store.send(.binding(.set(\.$text, "test"))) { state in store.send(.binding(.set(\.$text, "test"))) { state in
@ -126,9 +119,8 @@ class MultiLineTextFieldTests: XCTestCase {
func testCharLimitText_CharLimit_LessCharacters() throws { func testCharLimitText_CharLimit_LessCharacters() throws {
let store = TestStore( let store = TestStore(
initialState: MultiLineTextFieldState(charLimit: 5), initialState: MultiLineTextFieldReducer.State(charLimit: 5),
reducer: MultiLineTextFieldReducer.default, reducer: MultiLineTextFieldReducer()
environment: MultiLineTextFieldEnvironment()
) )
store.send(.binding(.set(\.$text, "test"))) { state in store.send(.binding(.set(\.$text, "test"))) { state in
@ -143,9 +135,8 @@ class MultiLineTextFieldTests: XCTestCase {
func testCharLimitText_CharLimit_Exceeded() throws { func testCharLimitText_CharLimit_Exceeded() throws {
let store = TestStore( let store = TestStore(
initialState: MultiLineTextFieldState(charLimit: 3), initialState: MultiLineTextFieldReducer.State(charLimit: 3),
reducer: MultiLineTextFieldReducer.default, reducer: MultiLineTextFieldReducer()
environment: MultiLineTextFieldEnvironment()
) )
store.send(.binding(.set(\.$text, "test"))) { state in store.send(.binding(.set(\.$text, "test"))) { state in

View File

@ -618,7 +618,7 @@ class SendTests: XCTestCase {
func testInvalidForm_ExceededMemoCharLimit() throws { func testInvalidForm_ExceededMemoCharLimit() throws {
let sendState = SendFlowState( let sendState = SendFlowState(
addMemoState: true, addMemoState: true,
memoState: MultiLineTextFieldState(charLimit: 3), memoState: MultiLineTextFieldReducer.State(charLimit: 3),
shieldedBalance: WalletBalance(verified: Zatoshi(1), total: Zatoshi(1)), shieldedBalance: WalletBalance(verified: Zatoshi(1), total: Zatoshi(1)),
transactionAddressInputState: transactionAddressInputState:
TransactionAddressTextFieldReducer.State( TransactionAddressTextFieldReducer.State(