Skip to content

Commit 49a25c4

Browse files
committed
Deprecate TestStore.assert (#912)
1 parent 7230ef6 commit 49a25c4

File tree

2 files changed

+180
-198
lines changed

2 files changed

+180
-198
lines changed

Sources/ComposableArchitecture/Internal/Deprecations.swift

Lines changed: 167 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,174 @@
1+
import CasePaths
12
#if canImport(SwiftUI)
2-
import CasePaths
3-
43
import SwiftUI
4+
#endif
5+
import XCTestDynamicOverlay
56

6-
// NB: Deprecated after 0.27.1:
7+
// NB: Deprecated after 0.29.0:
8+
#if DEBUG
9+
extension TestStore where LocalState: Equatable, Action: Equatable {
10+
@available(
11+
*, deprecated, message: "Use 'TestStore.send' and 'TestStore.receive' directly, instead"
12+
)
13+
public func assert(
14+
_ steps: Step...,
15+
file: StaticString = #file,
16+
line: UInt = #line
17+
) {
18+
assert(steps, file: file, line: line)
19+
}
20+
21+
@available(
22+
*, deprecated, message: "Use 'TestStore.send' and 'TestStore.receive' directly, instead"
23+
)
24+
public func assert(
25+
_ steps: [Step],
26+
file: StaticString = #file,
27+
line: UInt = #line
28+
) {
29+
30+
func assert(step: Step) {
31+
switch step.type {
32+
case let .send(action, update):
33+
self.send(action, file: step.file, line: step.line, update)
34+
35+
case let .receive(expectedAction, update):
36+
self.receive(expectedAction, file: step.file, line: step.line, update)
37+
38+
case let .environment(work):
39+
if !self.receivedActions.isEmpty {
40+
var actions = ""
41+
customDump(self.receivedActions.map(\.action), to: &actions)
42+
XCTFail(
43+
"""
44+
Must handle \(self.receivedActions.count) received \
45+
action\(self.receivedActions.count == 1 ? "" : "s") before performing this work: …
46+
47+
Unhandled actions: \(actions)
48+
""",
49+
file: step.file, line: step.line
50+
)
51+
}
52+
do {
53+
try work(&self.environment)
54+
} catch {
55+
XCTFail("Threw error: \(error)", file: step.file, line: step.line)
56+
}
57+
58+
case let .do(work):
59+
if !receivedActions.isEmpty {
60+
var actions = ""
61+
customDump(self.receivedActions.map(\.action), to: &actions)
62+
XCTFail(
63+
"""
64+
Must handle \(self.receivedActions.count) received \
65+
action\(self.receivedActions.count == 1 ? "" : "s") before performing this work: …
66+
67+
Unhandled actions: \(actions)
68+
""",
69+
file: step.file, line: step.line
70+
)
71+
}
72+
do {
73+
try work()
74+
} catch {
75+
XCTFail("Threw error: \(error)", file: step.file, line: step.line)
76+
}
77+
78+
case let .sequence(subSteps):
79+
subSteps.forEach(assert(step:))
80+
}
81+
}
82+
83+
steps.forEach(assert(step:))
84+
85+
self.completed()
86+
}
87+
88+
public struct Step {
89+
fileprivate let type: StepType
90+
fileprivate let file: StaticString
91+
fileprivate let line: UInt
92+
93+
private init(
94+
_ type: StepType,
95+
file: StaticString = #file,
96+
line: UInt = #line
97+
) {
98+
self.type = type
99+
self.file = file
100+
self.line = line
101+
}
102+
103+
@available(*, deprecated, message: "Call 'TestStore.send' directly, instead")
104+
public static func send(
105+
_ action: LocalAction,
106+
file: StaticString = #file,
107+
line: UInt = #line,
108+
_ update: @escaping (inout LocalState) throws -> Void = { _ in }
109+
) -> Step {
110+
Step(.send(action, update), file: file, line: line)
111+
}
112+
113+
@available(*, deprecated, message: "Call 'TestStore.receive' directly, instead")
114+
public static func receive(
115+
_ action: Action,
116+
file: StaticString = #file,
117+
line: UInt = #line,
118+
_ update: @escaping (inout LocalState) throws -> Void = { _ in }
119+
) -> Step {
120+
Step(.receive(action, update), file: file, line: line)
121+
}
122+
123+
@available(*, deprecated, message: "Mutate 'TestStore.environment' directly, instead")
124+
public static func environment(
125+
file: StaticString = #file,
126+
line: UInt = #line,
127+
_ update: @escaping (inout Environment) throws -> Void
128+
) -> Step {
129+
Step(.environment(update), file: file, line: line)
130+
}
7131

132+
@available(*, deprecated, message: "Perform this work directly in your test, instead")
133+
public static func `do`(
134+
file: StaticString = #file,
135+
line: UInt = #line,
136+
_ work: @escaping () throws -> Void
137+
) -> Step {
138+
Step(.do(work), file: file, line: line)
139+
}
140+
141+
@available(*, deprecated, message: "Perform this work directly in your test, instead")
142+
public static func sequence(
143+
_ steps: [Step],
144+
file: StaticString = #file,
145+
line: UInt = #line
146+
) -> Step {
147+
Step(.sequence(steps), file: file, line: line)
148+
}
149+
150+
@available(*, deprecated, message: "Perform this work directly in your test, instead")
151+
public static func sequence(
152+
_ steps: Step...,
153+
file: StaticString = #file,
154+
line: UInt = #line
155+
) -> Step {
156+
Step(.sequence(steps), file: file, line: line)
157+
}
158+
159+
fileprivate indirect enum StepType {
160+
case send(LocalAction, (inout LocalState) throws -> Void)
161+
case receive(Action, (inout LocalState) throws -> Void)
162+
case environment((inout Environment) throws -> Void)
163+
case `do`(() throws -> Void)
164+
case sequence([Step])
165+
}
166+
}
167+
}
168+
#endif
169+
170+
// NB: Deprecated after 0.27.1:
171+
#if canImport(SwiftUI)
8172
extension AlertState.Button {
9173
@available(
10174
*, deprecated,

0 commit comments

Comments
 (0)