Skip to content

Commit 0dc3bb3

Browse files
Buffered Actions Failing Test (#662)
* Adds a failing test demonstrating #661 * Don't write to state till `isSending` is false * Update StoreTests.swift * Update StoreTests.swift Co-authored-by: Stephen Celis <[email protected]> Co-authored-by: Stephen Celis <[email protected]>
1 parent 9fd9ce8 commit 0dc3bb3

File tree

2 files changed

+71
-2
lines changed

2 files changed

+71
-2
lines changed

Sources/ComposableArchitecture/Store.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,9 +346,9 @@ public final class Store<State, Action> {
346346
)
347347
localStore.parentDisposable = self.$state.producer.startWithValues {
348348
[weak localStore] state in
349-
guard let localStore = localStore else { return }
349+
guard let localStore = localStore else { return }
350350
localStore.state = extractLocalState(state) ?? localStore.state
351-
}
351+
}
352352
return localStore
353353
}
354354
}

Tests/ComposableArchitectureTests/StoreTests.swift

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,4 +449,73 @@ final class StoreTests: XCTestCase {
449449

450450
XCTAssertEqual(emissions, [0, 3])
451451
}
452+
453+
func testBufferedActionProcessing() {
454+
struct ChildState: Equatable {
455+
var count: Int?
456+
}
457+
458+
let childReducer = Reducer<ChildState, Int?, Void> { state, action, _ in
459+
state.count = action
460+
return .none
461+
}
462+
463+
struct ParentState: Equatable {
464+
var count: Int?
465+
var child: ChildState?
466+
}
467+
468+
enum ParentAction: Equatable {
469+
case button
470+
case child(Int?)
471+
}
472+
473+
var handledActions: [ParentAction] = []
474+
let parentReducer = Reducer.combine([
475+
childReducer
476+
.optional()
477+
.pullback(
478+
state: \.child,
479+
action: /ParentAction.child,
480+
environment: {}
481+
),
482+
Reducer<ParentState, ParentAction, Void> { state, action, _ in
483+
handledActions.append(action)
484+
485+
switch action {
486+
case .button:
487+
state.child = .init(count: nil)
488+
return .none
489+
490+
case .child(let childCount):
491+
state.count = childCount
492+
return .none
493+
}
494+
},
495+
])
496+
497+
let parentStore = Store(
498+
initialState: .init(),
499+
reducer: parentReducer,
500+
environment: ()
501+
)
502+
503+
parentStore
504+
.scope(
505+
state: \.child,
506+
action: ParentAction.child
507+
)
508+
.ifLet { childStore in
509+
ViewStore(childStore).send(2)
510+
}
511+
.store(in: &cancellables)
512+
513+
XCTAssertEqual(handledActions, [])
514+
515+
parentStore.send(.button)
516+
XCTAssertEqual(handledActions, [
517+
.button,
518+
.child(2)
519+
])
520+
}
452521
}

0 commit comments

Comments
 (0)