Skip to content

Commit a1e454c

Browse files
Depend on ConcurrencyExtras (#2301)
* wip * wip * wip Fixes #1902. * wip * wip * wip * wip * fix * added test for subscribe/receive --------- Co-authored-by: Brandon Williams <[email protected]>
1 parent 2dafe44 commit a1e454c

25 files changed

+1229
-1243
lines changed

ComposableArchitecture.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 19 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Examples/CaseStudies/SwiftUICaseStudiesTests/01-GettingStarted-AnimationsTests.swift

Lines changed: 40 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,62 @@
11
import Clocks
22
import ComposableArchitecture
3-
@_spi(Concurrency) import Dependencies
43
import XCTest
54

65
@testable import SwiftUICaseStudies
76

87
@MainActor
98
final class AnimationTests: XCTestCase {
109
func testRainbow() async {
11-
await withMainSerialExecutor {
12-
let clock = TestClock()
13-
14-
let store = TestStore(initialState: Animations.State()) {
15-
Animations()
16-
} withDependencies: {
17-
$0.continuousClock = clock
18-
}
10+
let clock = TestClock()
1911

20-
await store.send(.rainbowButtonTapped)
21-
await store.receive(.setColor(.red)) {
22-
$0.circleColor = .red
23-
}
12+
let store = TestStore(initialState: Animations.State()) {
13+
Animations()
14+
} withDependencies: {
15+
$0.continuousClock = clock
16+
}
17+
store.useMainSerialExecutor = true
2418

25-
await clock.advance(by: .seconds(1))
26-
await store.receive(.setColor(.blue)) {
27-
$0.circleColor = .blue
28-
}
19+
await store.send(.rainbowButtonTapped)
20+
await store.receive(.setColor(.red)) {
21+
$0.circleColor = .red
22+
}
2923

30-
await clock.advance(by: .seconds(1))
31-
await store.receive(.setColor(.green)) {
32-
$0.circleColor = .green
33-
}
24+
await clock.advance(by: .seconds(1))
25+
await store.receive(.setColor(.blue)) {
26+
$0.circleColor = .blue
27+
}
3428

35-
await clock.advance(by: .seconds(1))
36-
await store.receive(.setColor(.orange)) {
37-
$0.circleColor = .orange
38-
}
29+
await clock.advance(by: .seconds(1))
30+
await store.receive(.setColor(.green)) {
31+
$0.circleColor = .green
32+
}
3933

40-
await clock.advance(by: .seconds(1))
41-
await store.receive(.setColor(.pink)) {
42-
$0.circleColor = .pink
43-
}
34+
await clock.advance(by: .seconds(1))
35+
await store.receive(.setColor(.orange)) {
36+
$0.circleColor = .orange
37+
}
4438

45-
await clock.advance(by: .seconds(1))
46-
await store.receive(.setColor(.purple)) {
47-
$0.circleColor = .purple
48-
}
39+
await clock.advance(by: .seconds(1))
40+
await store.receive(.setColor(.pink)) {
41+
$0.circleColor = .pink
42+
}
4943

50-
await clock.advance(by: .seconds(1))
51-
await store.receive(.setColor(.yellow)) {
52-
$0.circleColor = .yellow
53-
}
44+
await clock.advance(by: .seconds(1))
45+
await store.receive(.setColor(.purple)) {
46+
$0.circleColor = .purple
47+
}
5448

55-
await clock.advance(by: .seconds(1))
56-
await store.receive(.setColor(.black)) {
57-
$0.circleColor = .black
58-
}
49+
await clock.advance(by: .seconds(1))
50+
await store.receive(.setColor(.yellow)) {
51+
$0.circleColor = .yellow
52+
}
5953

60-
await clock.run()
54+
await clock.advance(by: .seconds(1))
55+
await store.receive(.setColor(.black)) {
56+
$0.circleColor = .black
6157
}
58+
59+
await clock.run()
6260
}
6361

6462
func testReset() async {

Examples/CaseStudies/SwiftUICaseStudiesTests/02-Effects-CancellationTests.swift

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import ComposableArchitecture
2-
@_spi(Concurrency) import Dependencies
32
import XCTest
43

54
@testable import SwiftUICaseStudies
@@ -54,11 +53,9 @@ final class EffectsCancellationTests: XCTestCase {
5453
let store = TestStore(initialState: EffectsCancellation.State()) {
5554
EffectsCancellation()
5655
} withDependencies: {
57-
$0.factClient.fetch = {
58-
try await Task.sleep(nanoseconds: NSEC_PER_SEC)
59-
return "\($0) is a good number Brent"
60-
}
56+
$0.factClient.fetch = { _ in try await Task.never() }
6157
}
58+
store.useMainSerialExecutor = true
6259

6360
await store.send(.factButtonTapped) {
6461
$0.isFactRequestInFlight = true
@@ -69,20 +66,19 @@ final class EffectsCancellationTests: XCTestCase {
6966
}
7067

7168
func testTrivia_PlusMinusButtonsCancelsRequest() async {
72-
await withMainSerialExecutor {
73-
let store = TestStore(initialState: EffectsCancellation.State()) {
74-
EffectsCancellation()
75-
} withDependencies: {
76-
$0.factClient.fetch = { _ in try await Task.never() }
77-
}
69+
let store = TestStore(initialState: EffectsCancellation.State()) {
70+
EffectsCancellation()
71+
} withDependencies: {
72+
$0.factClient.fetch = { _ in try await Task.never() }
73+
}
74+
store.useMainSerialExecutor = true
7875

79-
await store.send(.factButtonTapped) {
80-
$0.isFactRequestInFlight = true
81-
}
82-
await store.send(.stepperChanged(1)) {
83-
$0.count = 1
84-
$0.isFactRequestInFlight = false
85-
}
76+
await store.send(.factButtonTapped) {
77+
$0.isFactRequestInFlight = true
78+
}
79+
await store.send(.stepperChanged(1)) {
80+
$0.count = 1
81+
$0.isFactRequestInFlight = false
8682
}
8783
}
8884
}

Examples/Standups/StandupsTests/AppFeatureTests.swift

Lines changed: 50 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import ComposableArchitecture
2-
@_spi(Concurrency) import Dependencies
32
import XCTest
43

54
@testable import Standups
@@ -17,6 +16,7 @@ final class AppFeatureTests: XCTestCase {
1716
initialData: try! JSONEncoder().encode([standup])
1817
)
1918
}
19+
store.useMainSerialExecutor = true
2020

2121
await store.send(.path(.push(id: 0, state: .detail(StandupDetail.State(standup: standup))))) {
2222
$0.path[id: 0] = .detail(StandupDetail.State(standup: standup))
@@ -72,7 +72,7 @@ final class AppFeatureTests: XCTestCase {
7272
.path(
7373
.element(
7474
id: 0,
75-
action: .detail(.destination(.presented(.edit(.binding(.set(\.$standup, standup))))))
75+
action: .detail(.destination(.presented(.edit(.set(\.$standup, standup)))))
7676
)
7777
)
7878
) {
@@ -102,60 +102,59 @@ final class AppFeatureTests: XCTestCase {
102102
}
103103

104104
func testRecording() async {
105-
await withMainSerialExecutor {
106-
let speechResult = SpeechRecognitionResult(
107-
bestTranscription: Transcription(formattedString: "I completed the project"),
108-
isFinal: true
109-
)
110-
let standup = Standup(
111-
id: Standup.ID(),
112-
attendees: [
113-
Attendee(id: Attendee.ID()),
114-
Attendee(id: Attendee.ID()),
115-
Attendee(id: Attendee.ID()),
116-
],
117-
duration: .seconds(6)
118-
)
105+
let speechResult = SpeechRecognitionResult(
106+
bestTranscription: Transcription(formattedString: "I completed the project"),
107+
isFinal: true
108+
)
109+
let standup = Standup(
110+
id: Standup.ID(),
111+
attendees: [
112+
Attendee(id: Attendee.ID()),
113+
Attendee(id: Attendee.ID()),
114+
Attendee(id: Attendee.ID()),
115+
],
116+
duration: .seconds(6)
117+
)
119118

120-
let store = TestStore(
121-
initialState: AppFeature.State(
122-
path: StackState([
123-
.detail(StandupDetail.State(standup: standup)),
124-
.record(RecordMeeting.State(standup: standup)),
125-
])
126-
)
127-
) {
128-
AppFeature()
129-
} withDependencies: {
130-
$0.dataManager = .mock(initialData: try! JSONEncoder().encode([standup]))
131-
$0.date.now = Date(timeIntervalSince1970: 1_234_567_890)
132-
$0.continuousClock = ImmediateClock()
133-
$0.speechClient.authorizationStatus = { .authorized }
134-
$0.speechClient.startTask = { _ in
135-
AsyncThrowingStream { continuation in
136-
continuation.yield(speechResult)
137-
continuation.finish()
138-
}
119+
let store = TestStore(
120+
initialState: AppFeature.State(
121+
path: StackState([
122+
.detail(StandupDetail.State(standup: standup)),
123+
.record(RecordMeeting.State(standup: standup)),
124+
])
125+
)
126+
) {
127+
AppFeature()
128+
} withDependencies: {
129+
$0.dataManager = .mock(initialData: try! JSONEncoder().encode([standup]))
130+
$0.date.now = Date(timeIntervalSince1970: 1_234_567_890)
131+
$0.continuousClock = ImmediateClock()
132+
$0.speechClient.authorizationStatus = { .authorized }
133+
$0.speechClient.startTask = { _ in
134+
AsyncThrowingStream { continuation in
135+
continuation.yield(speechResult)
136+
continuation.finish()
139137
}
140-
$0.uuid = .incrementing
141138
}
142-
store.exhaustivity = .off
139+
$0.uuid = .incrementing
140+
}
141+
store.exhaustivity = .off
142+
store.useMainSerialExecutor = true
143143

144-
await store.send(.path(.element(id: 1, action: .record(.onTask))))
145-
await store.receive(
146-
.path(
147-
.element(id: 1, action: .record(.delegate(.save(transcript: "I completed the project"))))
144+
await store.send(.path(.element(id: 1, action: .record(.onTask))))
145+
await store.receive(
146+
.path(
147+
.element(id: 1, action: .record(.delegate(.save(transcript: "I completed the project"))))
148+
)
149+
) {
150+
$0.path.pop(to: 0)
151+
$0.path[id: 0, case: /AppFeature.Path.State.detail]?.standup.meetings = [
152+
Meeting(
153+
id: Meeting.ID(UUID(0)),
154+
date: Date(timeIntervalSince1970: 1_234_567_890),
155+
transcript: "I completed the project"
148156
)
149-
) {
150-
$0.path.pop(to: 0)
151-
$0.path[id: 0, case: /AppFeature.Path.State.detail]?.standup.meetings = [
152-
Meeting(
153-
id: Meeting.ID(UUID(0)),
154-
date: Date(timeIntervalSince1970: 1_234_567_890),
155-
transcript: "I completed the project"
156-
)
157-
]
158-
}
157+
]
159158
}
160159
}
161160
}

0 commit comments

Comments
 (0)