Skip to content

Commit fac9ff6

Browse files
committed
[Test] Add more examples for different Error type handling.
1 parent dd698b9 commit fac9ff6

File tree

1 file changed

+90
-11
lines changed

1 file changed

+90
-11
lines changed

SwiftTaskTests/MultipleErrorTypesTests.swift

Lines changed: 90 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ import XCTest
1212

1313
class 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

Comments
 (0)