@@ -4,155 +4,156 @@ import XCTest
4
4
5
5
// `@MainActor` introduces issues gathering tests on Linux
6
6
#if !os(Linux)
7
- @MainActor
8
- final class ComposableArchitectureTests : XCTestCase {
9
- func testScheduling( ) async {
10
- enum CounterAction : Equatable {
11
- case incrAndSquareLater
12
- case incrNow
13
- case squareNow
14
- }
7
+ @MainActor
8
+ final class ComposableArchitectureTests : XCTestCase {
9
+ func testScheduling( ) async {
10
+ enum CounterAction : Equatable {
11
+ case incrAndSquareLater
12
+ case incrNow
13
+ case squareNow
14
+ }
15
15
16
- let counterReducer = Reducer < Int , CounterAction , DateScheduler > {
17
- state, action, scheduler in
18
- switch action {
19
- case . incrAndSquareLater:
20
- return . merge(
21
- Effect ( value: . incrNow) . deferred ( for: 2 , scheduler: scheduler) ,
22
- Effect ( value: . squareNow) . deferred ( for: 1 , scheduler: scheduler) ,
23
- Effect ( value: . squareNow) . deferred ( for: 2 , scheduler: scheduler)
24
- )
25
- case . incrNow:
26
- state += 1
27
- return . none
28
- case . squareNow:
29
- state *= state
30
- return . none
31
- }
16
+ let counterReducer = Reducer < Int , CounterAction , DateScheduler > {
17
+ state, action, scheduler in
18
+ switch action {
19
+ case . incrAndSquareLater:
20
+ return . merge(
21
+ Effect ( value: . incrNow) . deferred ( for: 2 , scheduler: scheduler) ,
22
+ Effect ( value: . squareNow) . deferred ( for: 1 , scheduler: scheduler) ,
23
+ Effect ( value: . squareNow) . deferred ( for: 2 , scheduler: scheduler)
24
+ )
25
+ case . incrNow:
26
+ state += 1
27
+ return . none
28
+ case . squareNow:
29
+ state *= state
30
+ return . none
32
31
}
33
-
34
- let mainQueue = TestScheduler ( )
35
-
36
- let store = TestStore (
37
- initialState: 2 ,
38
- reducer: counterReducer,
39
- environment: mainQueue
40
- )
41
-
42
- await store. send ( . incrAndSquareLater)
43
- await mainQueue. advance ( by: 1 )
44
- await store. receive ( . squareNow) { $0 = 4 }
45
- await mainQueue. advance ( by: 1 )
46
- await store. receive ( . incrNow) { $0 = 5 }
47
- await store. receive ( . squareNow) { $0 = 25 }
48
-
49
- await store. send ( . incrAndSquareLater)
50
- await mainQueue. advance ( by: 2 )
51
- await store. receive ( . squareNow) { $0 = 625 }
52
- await store. receive ( . incrNow) { $0 = 626 }
53
- await store. receive ( . squareNow) { $0 = 391876 }
54
32
}
55
33
56
- func testSimultaneousWorkOrdering( ) {
57
- let testScheduler = TestScheduler ( )
34
+ let mainQueue = TestScheduler ( )
35
+
36
+ let store = TestStore (
37
+ initialState: 2 ,
38
+ reducer: counterReducer,
39
+ environment: mainQueue
40
+ )
41
+
42
+ await store. send ( . incrAndSquareLater)
43
+ await mainQueue. advance ( by: 1 )
44
+ await store. receive ( . squareNow) { $0 = 4 }
45
+ await mainQueue. advance ( by: 1 )
46
+ await store. receive ( . incrNow) { $0 = 5 }
47
+ await store. receive ( . squareNow) { $0 = 25 }
48
+
49
+ await store. send ( . incrAndSquareLater)
50
+ await mainQueue. advance ( by: 2 )
51
+ await store. receive ( . squareNow) { $0 = 625 }
52
+ await store. receive ( . incrNow) { $0 = 626 }
53
+ await store. receive ( . squareNow) { $0 = 391876 }
54
+ }
58
55
59
- var values : [ Int ] = [ ]
60
- testScheduler. schedule ( after: . seconds( 0 ) , interval: . seconds( 1 ) ) { values. append ( 1 ) }
61
- testScheduler. schedule ( after: . seconds( 0 ) , interval: . seconds( 2 ) ) { values. append ( 42 ) }
56
+ func testSimultaneousWorkOrdering( ) {
57
+ let testScheduler = TestScheduler ( )
62
58
63
- XCTAssertNoDifference ( values, [ ] )
64
- testScheduler. advance ( )
65
- XCTAssertNoDifference ( values, [ 1 , 42 ] )
66
- testScheduler. advance ( by: 2 )
67
- XCTAssertNoDifference ( values, [ 1 , 42 , 1 , 42 , 1 ] )
68
- }
59
+ var values : [ Int ] = [ ]
60
+ testScheduler. schedule ( after: . seconds( 0 ) , interval: . seconds( 1 ) ) { values. append ( 1 ) }
61
+ testScheduler. schedule ( after: . seconds( 0 ) , interval: . seconds( 2 ) ) { values. append ( 42 ) }
69
62
70
- func testLongLivingEffects( ) async {
71
- typealias Environment = (
72
- startEffect: Effect < Void , Never > ,
73
- stopEffect: Effect < Never , Never >
74
- )
63
+ XCTAssertNoDifference ( values, [ ] )
64
+ testScheduler. advance ( )
65
+ XCTAssertNoDifference ( values, [ 1 , 42 ] )
66
+ testScheduler. advance ( by: 2 )
67
+ XCTAssertNoDifference ( values, [ 1 , 42 , 1 , 42 , 1 ] )
68
+ }
75
69
76
- enum Action { case end, incr, start }
77
-
78
- let reducer = Reducer < Int , Action , Environment > { state, action, environment in
79
- switch action {
80
- case . end:
81
- return environment. stopEffect. fireAndForget ( )
82
- case . incr:
83
- state += 1
84
- return . none
85
- case . start:
86
- return environment. startEffect. map { Action . incr }
87
- }
70
+ func testLongLivingEffects( ) async {
71
+ typealias Environment = (
72
+ startEffect: Effect < Void , Never > ,
73
+ stopEffect: Effect < Never , Never >
74
+ )
75
+
76
+ enum Action { case end, incr, start }
77
+
78
+ let reducer = Reducer < Int , Action , Environment > { state, action, environment in
79
+ switch action {
80
+ case . end:
81
+ return environment. stopEffect. fireAndForget ( )
82
+ case . incr:
83
+ state += 1
84
+ return . none
85
+ case . start:
86
+ return environment. startEffect. map { Action . incr }
88
87
}
88
+ }
89
89
90
- let subject = Signal < Void , Never > . pipe ( )
90
+ let subject = Signal < Void , Never > . pipe ( )
91
91
92
- let store = TestStore (
93
- initialState: 0 ,
94
- reducer: reducer,
95
- environment: (
96
- startEffect: subject. output. producer. eraseToEffect ( ) ,
97
- stopEffect: . fireAndForget { subject. input. sendCompleted ( ) }
98
- )
92
+ let store = TestStore (
93
+ initialState: 0 ,
94
+ reducer: reducer,
95
+ environment: (
96
+ startEffect: subject. output. producer. eraseToEffect ( ) ,
97
+ stopEffect: . fireAndForget { subject. input. sendCompleted ( ) }
99
98
)
99
+ )
100
100
101
- await store. send ( . start)
102
- await store. send ( . incr) { $0 = 1 }
103
- subject. input. send ( value: ( ) )
104
- await store. receive ( . incr) { $0 = 2 }
105
- await store. send ( . end)
106
- }
107
-
108
- func testCancellation( ) async {
109
- let mainQueue = TestScheduler ( )
101
+ await store. send ( . start)
102
+ await store. send ( . incr) { $0 = 1 }
103
+ subject. input. send ( value: ( ) )
104
+ await store. receive ( . incr) { $0 = 2 }
105
+ await store. send ( . end)
106
+ }
110
107
111
- enum Action : Equatable {
112
- case cancel
113
- case incr
114
- case response( Int )
115
- }
108
+ func testCancellation( ) async {
109
+ let mainQueue = TestScheduler ( )
116
110
117
- struct Environment {
118
- let fetch : ( Int ) async -> Int
119
- }
111
+ enum Action : Equatable {
112
+ case cancel
113
+ case incr
114
+ case response( Int )
115
+ }
120
116
121
- let reducer = Reducer < Int , Action , Environment > { state, action, environment in
122
- enum CancelID { }
117
+ struct Environment {
118
+ let fetch : ( Int ) async -> Int
119
+ }
123
120
124
- switch action {
125
- case . cancel:
126
- return . cancel( id: CancelID . self)
121
+ let reducer = Reducer < Int , Action , Environment > { state, action, environment in
122
+ enum CancelID { }
127
123
128
- case . incr:
129
- state += 1
130
- return . task { [ state] in
131
- try await mainQueue. sleep ( for: . seconds( 1 ) )
132
- return . response( await environment. fetch ( state) )
133
- }
134
- . cancellable ( id: CancelID . self)
124
+ switch action {
125
+ case . cancel:
126
+ return . cancel( id: CancelID . self)
135
127
136
- case let . response( value) :
137
- state = value
138
- return . none
128
+ case . incr:
129
+ state += 1
130
+ return . task { [ state] in
131
+ try await mainQueue. sleep ( for: . seconds( 1 ) )
132
+ return . response( await environment. fetch ( state) )
139
133
}
134
+ . cancellable ( id: CancelID . self)
135
+
136
+ case let . response( value) :
137
+ state = value
138
+ return . none
140
139
}
140
+ }
141
141
142
- let store = TestStore (
143
- initialState: 0 ,
144
- reducer: reducer,
145
- environment: Environment (
146
- fetch: { value in value * value }
147
- )
142
+ let store = TestStore (
143
+ initialState: 0 ,
144
+ reducer: reducer,
145
+ environment: Environment (
146
+ fetch: { value in value * value }
148
147
)
148
+ )
149
149
150
- await store. send ( . incr) { $0 = 1 }
151
- await mainQueue. advance ( by: . seconds( 1 ) )
152
- await store. receive ( . response( 1 ) )
150
+ await store. send ( . incr) { $0 = 1 }
151
+ await mainQueue. advance ( by: . seconds( 1 ) )
152
+ await store. receive ( . response( 1 ) )
153
153
154
- await store. send ( . incr) { $0 = 2 }
155
- await store. send ( . cancel)
156
- }
154
+ await store. send ( . incr) { $0 = 2 }
155
+ await store. send ( . cancel)
156
+ await store . finish ( )
157
157
}
158
+ }
158
159
#endif
0 commit comments