Skip to content

Commit bd6c1fc

Browse files
authored
Bring back _printChanges queue. (#2519)
* Bring back _printChanges queue. * fixes * make test a little stronger
1 parent 20089ee commit bd6c1fc

File tree

2 files changed

+89
-7
lines changed

2 files changed

+89
-7
lines changed

Sources/ComposableArchitecture/Reducer/Reducers/DebugReducer.swift

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import Combine
2+
import Dispatch
3+
14
extension Reducer {
25
#if swift(>=5.8)
36
/// Enhances a reducer with debug logging of received actions and state mutations for the given
@@ -26,13 +29,19 @@ extension Reducer {
2629
#endif
2730
}
2831

32+
private let printQueue = DispatchQueue(label: "co.pointfree.swift-composable-architecture.printer")
33+
2934
public struct _ReducerPrinter<State, Action> {
3035
private let _printChange: (_ receivedAction: Action, _ oldState: State, _ newState: State) -> Void
36+
@usableFromInline
37+
let queue: DispatchQueue
3138

3239
public init(
33-
printChange: @escaping (_ receivedAction: Action, _ oldState: State, _ newState: State) -> Void
40+
printChange: @escaping (_ receivedAction: Action, _ oldState: State, _ newState: State) -> Void,
41+
queue: DispatchQueue? = nil
3442
) {
3543
self._printChange = printChange
44+
self.queue = queue ?? printQueue
3645
}
3746

3847
public func printChange(receivedAction: Action, oldState: State, newState: State) {
@@ -81,8 +90,13 @@ public struct _PrintChangesReducer<Base: Reducer>: Reducer {
8190
let oldState = state
8291
let effects = self.base.reduce(into: &state, action: action)
8392
return effects.merge(
84-
with: .run { [newState = state] _ in
85-
printer.printChange(receivedAction: action, oldState: oldState, newState: newState)
93+
with: .publisher { [newState = state, queue = printer.queue] in
94+
Deferred<Empty<Action, Never>> {
95+
queue.async {
96+
printer.printChange(receivedAction: action, oldState: oldState, newState: newState)
97+
}
98+
return Empty()
99+
}
86100
}
87101
)
88102
}

Tests/ComposableArchitectureTests/DebugTests.swift

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@
9898
}
9999

100100
@MainActor
101-
func testDebugReducer() async {
102-
struct DebuggedReducer: Reducer {
101+
func testDebugReducer() async throws {
102+
struct Feature: Reducer {
103103
typealias State = Int
104104
typealias Action = Bool
105105
func reduce(into state: inout Int, action: Bool) -> Effect<Bool> {
@@ -108,8 +108,76 @@
108108
}
109109
}
110110

111-
let store = TestStore(initialState: 0) { DebuggedReducer()._printChanges() }
112-
await store.send(true) { $0 = 1 }
111+
let logs = LockIsolated<String>("")
112+
let printer = _ReducerPrinter<Feature.State, Feature.Action>(
113+
printChange: { action, oldState, newState in
114+
logs.withValue { _ = dump(action, to: &$0) }
115+
}
116+
)
117+
118+
let store = Store(initialState: 0) { Feature()._printChanges(printer) }
119+
store.send(true)
120+
try await Task.sleep(nanoseconds: 300_000_000)
121+
XCTAssertNoDifference(
122+
logs.value,
123+
"""
124+
- true
125+
126+
"""
127+
)
128+
}
129+
130+
func testDebugReducer_Order() {
131+
struct Feature: Reducer {
132+
typealias State = Int
133+
typealias Action = Bool
134+
func reduce(into state: inout Int, action: Bool) -> Effect<Bool> {
135+
state += action ? 1 : -1
136+
return .run { _ in await Task.yield() }
137+
}
138+
}
139+
140+
let logs = LockIsolated<String>("")
141+
let printer = _ReducerPrinter<Feature.State, Feature.Action>(
142+
printChange: { action, oldState, newState in
143+
logs.withValue { _ = dump(action, to: &$0) }
144+
}
145+
)
146+
147+
let store = Store(initialState: 0) {
148+
Feature()
149+
._printChanges(printer)
150+
._printChanges(printer)
151+
._printChanges(printer)
152+
._printChanges(printer)
153+
}
154+
store.send(true)
155+
store.send(false)
156+
store.send(true)
157+
store.send(false)
158+
_ = XCTWaiter.wait(for: [self.expectation(description: "wait")], timeout: 0.3)
159+
XCTAssertNoDifference(
160+
logs.value,
161+
"""
162+
- true
163+
- true
164+
- true
165+
- true
166+
- false
167+
- false
168+
- false
169+
- false
170+
- true
171+
- true
172+
- true
173+
- true
174+
- false
175+
- false
176+
- false
177+
- false
178+
179+
"""
180+
)
113181
}
114182
}
115183
#endif

0 commit comments

Comments
 (0)