[#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,
SendFlowEnvironment
>
typealias AnyMultiLineTextFieldReducer = AnyReducer<MultiLineTextFieldReducer.State, MultiLineTextFieldReducer.Action, SendFlowEnvironment>
// MARK: - State
@ -32,7 +33,7 @@ struct SendFlowState: Equatable {
var addMemoState: Bool
var isSendingTransaction = false
var memoState: MultiLineTextFieldState
var memoState: MultiLineTextFieldReducer.State
var route: Route?
var shieldedBalance = WalletBalance.zero
var transactionAddressInputState: TransactionAddressTextFieldReducer.State
@ -83,7 +84,7 @@ struct SendFlowState: Equatable {
enum SendFlowAction: Equatable {
case addMemo(CheckCircleAction)
case memo(MultiLineTextFieldAction)
case memo(MultiLineTextFieldReducer.Action)
case onAppear
case onDisappear
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,
action: /SendFlowAction.memo,
environment: { _ in MultiLineTextFieldEnvironment() }
environment: { $0 }
)
}

View File

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

View File

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

View File

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