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