@@ -12,9 +12,10 @@ import XCTest
12
12
13
13
class MultipleErrorTypesTests : _TestCase
14
14
{
15
- enum MyEnum
15
+ enum MyEnum : Printable
16
16
{
17
17
case Default
18
+ var description : String { return " MyEnumDefault " }
18
19
}
19
20
20
21
struct Dummy { }
@@ -25,7 +26,7 @@ class MultipleErrorTypesTests: _TestCase
25
26
var flow = [ Int] ( )
26
27
27
28
// delayed task + counting flow 1 & 2
28
- func _task1( #success : Bool) -> Task1
29
+ func _task1( #ok : Bool) -> Task1
29
30
{
30
31
return Task1 { progress, fulfill, reject, configure in
31
32
println ( " [task1] start " )
@@ -35,14 +36,14 @@ class MultipleErrorTypesTests: _TestCase
35
36
println ( " [task1] end " )
36
37
self . flow += [ 2 ]
37
38
38
- success ? fulfill ( " OK " ) : reject ( " NG " )
39
+ ok ? fulfill ( " OK " ) : reject ( " NG " )
39
40
}
40
41
return
41
42
}
42
43
}
43
44
44
45
// delayed task + counting flow 4 & 5
45
- func _task2( #success : Bool) -> Task2
46
+ func _task2( #ok : Bool) -> Task2
46
47
{
47
48
return Task2 { progress, fulfill, reject, configure in
48
49
println ( " [task2] start " )
@@ -52,7 +53,7 @@ class MultipleErrorTypesTests: _TestCase
52
53
println ( " [task2] end " )
53
54
self . flow += [ 5 ]
54
55
55
- success ? fulfill ( . Default) : reject ( . Default)
56
+ ok ? fulfill ( . Default) : reject ( . Default)
56
57
}
57
58
return
58
59
}
@@ -62,13 +63,13 @@ class MultipleErrorTypesTests: _TestCase
62
63
{
63
64
var expect = self . expectationWithDescription ( __FUNCTION__)
64
65
65
- self . _task1 ( success : true )
66
+ self . _task1 ( ok : true )
66
67
. then { value, errorInfo -> Task2 in
67
68
68
69
println ( " task1.then " )
69
70
self . flow += [ 3 ]
70
71
71
- return self . _task2 ( success : true )
72
+ return self . _task2 ( ok : true )
72
73
73
74
}
74
75
. then { value, errorInfo -> Void in
@@ -88,13 +89,13 @@ class MultipleErrorTypesTests: _TestCase
88
89
{
89
90
var expect = self . expectationWithDescription ( __FUNCTION__)
90
91
91
- self . _task1 ( success : true )
92
+ self . _task1 ( ok : true )
92
93
. success { value -> Task2 in
93
94
94
95
println ( " task1.success " )
95
96
self . flow += [ 3 ]
96
97
97
- return self . _task2 ( success : true )
98
+ return self . _task2 ( ok : true )
98
99
99
100
}
100
101
. success { value -> Void in
@@ -110,11 +111,89 @@ class MultipleErrorTypesTests: _TestCase
110
111
self . wait ( )
111
112
}
112
113
114
+ func testMultipleErrorTypes_success_differentErrorType( )
115
+ {
116
+ var expect = self . expectationWithDescription ( __FUNCTION__)
117
+
118
+ self . _task1 ( ok: true )
119
+ . success { value -> Task2 in
120
+
121
+ println ( " task1.success " )
122
+ self . flow += [ 3 ]
123
+
124
+ //
125
+ // NOTE:
126
+ // If Task1 and Task2 have different Error types,
127
+ // returning `self._task2(ok: false)` inside `self._task1.success()` will fail error conversion
128
+ // (Task2.Error -> Task1.Error).
129
+ //
130
+ return self . _task2 ( ok: false ) // inner rejection with different Error type
131
+
132
+ }
133
+ . then { value, errorInfo -> Void in
134
+
135
+ println ( " task1.success.success (task2 should end at this point) " )
136
+ self . flow += [ 6 ]
137
+
138
+ XCTAssertEqual ( self . flow, Array ( 1 ... 6 ) , " Tasks should flow in order from 1 to 6. " )
139
+
140
+ XCTAssertTrue ( value == nil )
141
+ XCTAssertTrue ( errorInfo != nil )
142
+ XCTAssertTrue ( errorInfo!. error == nil , " Though `errorInfo` will still be non-nil, `errorInfo!.error` will become as `nil` if Task1 and Task2 have different Error types. " )
143
+ XCTAssertTrue ( errorInfo!. isCancelled == false )
144
+
145
+ expect. fulfill ( )
146
+
147
+ }
148
+
149
+ self . wait ( )
150
+ }
151
+
152
+ func testMultipleErrorTypes_success_differentErrorType_conversion( )
153
+ {
154
+ var expect = self . expectationWithDescription ( __FUNCTION__)
155
+
156
+ self . _task1 ( ok: true )
157
+ . success { value -> Task < Void , MyEnum , String > in
158
+
159
+ println ( " task1.success " )
160
+ self . flow += [ 3 ]
161
+
162
+ //
163
+ // NOTE:
164
+ // Since returning `self._task2(ok: false)` inside `self._task1.success()` will fail error conversion
165
+ // (Task2.Error -> Task1.Error) as seen in above test case,
166
+ // it is **user's responsibility** to add conversion logic to maintain same Error type throughout task-flow.
167
+ //
168
+ return self . _task2 ( ok: false )
169
+ . failure { Task < Void , MyEnum , String > ( error: " Mapping errorInfo= \( $0. error!) to String " ) } // error-conversion
170
+
171
+ }
172
+ . then { value, errorInfo -> Void in
173
+
174
+ println ( " task1.success.success (task2 should end at this point) " )
175
+ self . flow += [ 6 ]
176
+
177
+ XCTAssertEqual ( self . flow, Array ( 1 ... 6 ) , " Tasks should flow in order from 1 to 6. " )
178
+
179
+ XCTAssertTrue ( value == nil )
180
+ XCTAssertTrue ( errorInfo != nil )
181
+ XCTAssertEqual ( errorInfo!. error!, " Mapping errorInfo=MyEnumDefault to String " ,
182
+ " Now `self._task2()`'s error is catched by this scope by adding manual error-conversion logic by user side. " )
183
+ XCTAssertTrue ( errorInfo!. isCancelled == false )
184
+
185
+ expect. fulfill ( )
186
+
187
+ }
188
+
189
+ self . wait ( )
190
+ }
191
+
113
192
func testMultipleErrorTypes_failure( )
114
193
{
115
194
var expect = self . expectationWithDescription ( __FUNCTION__)
116
195
117
- self . _task1 ( success : false )
196
+ self . _task1 ( ok : false )
118
197
. failure { errorInfo -> Task < Dummy , String /* must be task1's value type to recover */, Dummy > in
119
198
120
199
println ( " task1.failure " )
@@ -125,7 +204,7 @@ class MultipleErrorTypesTests: _TestCase
125
204
// Returning `Task2` won't work since same Value type as `task1` is required inside `task1.failure()`,
126
205
// so use `then()` to promote `Task2` to `Task<..., Task1.Value, ...>`.
127
206
//
128
- return self . _task2 ( success : false ) . then { value, errorInfo in
207
+ return self . _task2 ( ok : false ) . then { value, errorInfo in
129
208
return Task < Dummy , String , Dummy > ( error: Dummy ( ) ) // error task
130
209
}
131
210
}
0 commit comments