@@ -12,9 +12,10 @@ import XCTest
1212
1313class MultipleErrorTypesTests : _TestCase
1414{
15- enum MyEnum
15+ enum MyEnum : Printable
1616 {
1717 case Default
18+ var description : String { return " MyEnumDefault " }
1819 }
1920
2021 struct Dummy { }
@@ -25,7 +26,7 @@ class MultipleErrorTypesTests: _TestCase
2526 var flow = [ Int] ( )
2627
2728 // delayed task + counting flow 1 & 2
28- func _task1( #success : Bool) -> Task1
29+ func _task1( #ok : Bool) -> Task1
2930 {
3031 return Task1 { progress, fulfill, reject, configure in
3132 println ( " [task1] start " )
@@ -35,14 +36,14 @@ class MultipleErrorTypesTests: _TestCase
3536 println ( " [task1] end " )
3637 self . flow += [ 2 ]
3738
38- success ? fulfill ( " OK " ) : reject ( " NG " )
39+ ok ? fulfill ( " OK " ) : reject ( " NG " )
3940 }
4041 return
4142 }
4243 }
4344
4445 // delayed task + counting flow 4 & 5
45- func _task2( #success : Bool) -> Task2
46+ func _task2( #ok : Bool) -> Task2
4647 {
4748 return Task2 { progress, fulfill, reject, configure in
4849 println ( " [task2] start " )
@@ -52,7 +53,7 @@ class MultipleErrorTypesTests: _TestCase
5253 println ( " [task2] end " )
5354 self . flow += [ 5 ]
5455
55- success ? fulfill ( . Default) : reject ( . Default)
56+ ok ? fulfill ( . Default) : reject ( . Default)
5657 }
5758 return
5859 }
@@ -62,13 +63,13 @@ class MultipleErrorTypesTests: _TestCase
6263 {
6364 var expect = self . expectationWithDescription ( __FUNCTION__)
6465
65- self . _task1 ( success : true )
66+ self . _task1 ( ok : true )
6667 . then { value, errorInfo -> Task2 in
6768
6869 println ( " task1.then " )
6970 self . flow += [ 3 ]
7071
71- return self . _task2 ( success : true )
72+ return self . _task2 ( ok : true )
7273
7374 }
7475 . then { value, errorInfo -> Void in
@@ -88,13 +89,13 @@ class MultipleErrorTypesTests: _TestCase
8889 {
8990 var expect = self . expectationWithDescription ( __FUNCTION__)
9091
91- self . _task1 ( success : true )
92+ self . _task1 ( ok : true )
9293 . success { value -> Task2 in
9394
9495 println ( " task1.success " )
9596 self . flow += [ 3 ]
9697
97- return self . _task2 ( success : true )
98+ return self . _task2 ( ok : true )
9899
99100 }
100101 . success { value -> Void in
@@ -110,11 +111,89 @@ class MultipleErrorTypesTests: _TestCase
110111 self . wait ( )
111112 }
112113
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+
113192 func testMultipleErrorTypes_failure( )
114193 {
115194 var expect = self . expectationWithDescription ( __FUNCTION__)
116195
117- self . _task1 ( success : false )
196+ self . _task1 ( ok : false )
118197 . failure { errorInfo -> Task < Dummy , String /* must be task1's value type to recover */, Dummy > in
119198
120199 println ( " task1.failure " )
@@ -125,7 +204,7 @@ class MultipleErrorTypesTests: _TestCase
125204 // Returning `Task2` won't work since same Value type as `task1` is required inside `task1.failure()`,
126205 // so use `then()` to promote `Task2` to `Task<..., Task1.Value, ...>`.
127206 //
128- return self . _task2 ( success : false ) . then { value, errorInfo in
207+ return self . _task2 ( ok : false ) . then { value, errorInfo in
129208 return Task < Dummy , String , Dummy > ( error: Dummy ( ) ) // error task
130209 }
131210 }
0 commit comments