OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import "dart:async"; | 5 import "dart:async"; |
6 import "dart:collection"; | 6 import "dart:collection"; |
7 | 7 |
8 import "package:async/result.dart"; | 8 import "package:async/async.dart"; |
9 import "package:stack_trace/stack_trace.dart"; | 9 import "package:stack_trace/stack_trace.dart"; |
10 import "package:test/test.dart"; | 10 import "package:test/test.dart"; |
11 | 11 |
12 void main() { | 12 void main() { |
13 var stack = new Trace.current(); | 13 var stack = new Trace.current(); |
14 | 14 |
15 test("create result value", () { | 15 test("create result value", () { |
16 Result<int> result = new Result<int>.value(42); | 16 Result<int> result = new Result<int>.value(42); |
17 expect(result.isValue, isTrue); | 17 expect(result.isValue, isTrue); |
18 expect(result.isError, isFalse); | 18 expect(result.isError, isFalse); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 Result<bool> result = new Result<bool>.error("BAD"); | 50 Result<bool> result = new Result<bool>.error("BAD"); |
51 expect(result.isValue, isFalse); | 51 expect(result.isValue, isFalse); |
52 expect(result.isError, isTrue); | 52 expect(result.isError, isTrue); |
53 ErrorResult error = result.asError; | 53 ErrorResult error = result.asError; |
54 expect(error.error, equals("BAD")); | 54 expect(error.error, equals("BAD")); |
55 expect(error.stackTrace, isNull); | 55 expect(error.stackTrace, isNull); |
56 }); | 56 }); |
57 | 57 |
58 test("complete with value", () { | 58 test("complete with value", () { |
59 Result<int> result = new ValueResult<int>(42); | 59 Result<int> result = new ValueResult<int>(42); |
60 Completer c = new Completer<int>(); | 60 var c = new Completer<int>(); |
61 c.future.then(expectAsync((int v) { expect(v, equals(42)); }), | 61 c.future.then(expectAsync1((int v) { |
62 onError: (e, s) { fail("Unexpected error"); }); | 62 expect(v, equals(42)); |
| 63 }), onError: (e, s) { |
| 64 fail("Unexpected error"); |
| 65 }); |
63 result.complete(c); | 66 result.complete(c); |
64 }); | 67 }); |
65 | 68 |
66 test("complete with error", () { | 69 test("complete with error", () { |
67 Result<bool> result = new ErrorResult("BAD", stack); | 70 Result<bool> result = new ErrorResult("BAD", stack); |
68 Completer c = new Completer<bool>(); | 71 var c = new Completer<bool>(); |
69 c.future.then((bool v) { fail("Unexpected value $v"); }, | 72 c.future.then((bool v) { |
70 onError: expectAsync((e, s) { | 73 fail("Unexpected value $v"); |
71 expect(e, equals("BAD")); | 74 }, onError: expectAsync2((e, s) { |
72 expect(s, same(stack)); | 75 expect(e, equals("BAD")); |
73 })); | 76 expect(s, same(stack)); |
| 77 })); |
74 result.complete(c); | 78 result.complete(c); |
75 }); | 79 }); |
76 | 80 |
77 test("add sink value", () { | 81 test("add sink value", () { |
78 Result<int> result = new ValueResult<int>(42); | 82 var result = new ValueResult<int>(42); |
79 EventSink<int> sink = new TestSink( | 83 EventSink<int> sink = new TestSink(onData: expectAsync1((v) { |
80 onData: expectAsync((v) { expect(v, equals(42)); }) | 84 expect(v, equals(42)); |
81 ); | 85 })); |
82 result.addTo(sink); | 86 result.addTo(sink); |
83 }); | 87 }); |
84 | 88 |
85 test("add sink error", () { | 89 test("add sink error", () { |
86 Result<bool> result = new ErrorResult("BAD", stack); | 90 Result<bool> result = new ErrorResult("BAD", stack); |
87 EventSink<bool> sink = new TestSink( | 91 EventSink<bool> sink = new TestSink(onError: expectAsync2((e, s) { |
88 onError: expectAsync((e, s) { | 92 expect(e, equals("BAD")); |
89 expect(e, equals("BAD")); | 93 expect(s, same(stack)); |
90 expect(s, same(stack)); | 94 })); |
91 }) | |
92 ); | |
93 result.addTo(sink); | 95 result.addTo(sink); |
94 }); | 96 }); |
95 | 97 |
96 test("value as future", () { | 98 test("value as future", () { |
97 Result<int> result = new ValueResult<int>(42); | 99 Result<int> result = new ValueResult<int>(42); |
98 result.asFuture.then(expectAsync((int v) { expect(v, equals(42)); }), | 100 result.asFuture.then(expectAsync1((int v) { |
99 onError: (e, s) { fail("Unexpected error"); }); | 101 expect(v, equals(42)); |
| 102 }), onError: (e, s) { |
| 103 fail("Unexpected error"); |
| 104 }); |
100 }); | 105 }); |
101 | 106 |
102 test("error as future", () { | 107 test("error as future", () { |
103 Result<bool> result = new ErrorResult("BAD", stack); | 108 Result<bool> result = new ErrorResult("BAD", stack); |
104 result.asFuture.then((bool v) { fail("Unexpected value $v"); }, | 109 result.asFuture.then((bool v) { |
105 onError: expectAsync((e, s) { | 110 fail("Unexpected value $v"); |
106 expect(e, equals("BAD")); | 111 }, onError: expectAsync2((e, s) { |
107 expect(s, same(stack)); | 112 expect(e, equals("BAD")); |
108 })); | 113 expect(s, same(stack)); |
| 114 })); |
109 }); | 115 }); |
110 | 116 |
111 test("capture future value", () { | 117 test("capture future value", () { |
112 Future<int> value = new Future<int>.value(42); | 118 Future<int> value = new Future<int>.value(42); |
113 Result.capture(value).then(expectAsync((Result result) { | 119 Result.capture(value).then(expectAsync1((Result result) { |
114 expect(result.isValue, isTrue); | 120 expect(result.isValue, isTrue); |
115 expect(result.isError, isFalse); | 121 expect(result.isError, isFalse); |
116 ValueResult value = result.asValue; | 122 ValueResult value = result.asValue; |
117 expect(value.value, equals(42)); | 123 expect(value.value, equals(42)); |
118 }), onError: (e, s) { | 124 }), onError: (e, s) { |
119 fail("Unexpected error: $e"); | 125 fail("Unexpected error: $e"); |
120 }); | 126 }); |
121 }); | 127 }); |
122 | 128 |
123 test("capture future error", () { | 129 test("capture future error", () { |
124 Future<bool> value = new Future<bool>.error("BAD", stack); | 130 Future<bool> value = new Future<bool>.error("BAD", stack); |
125 Result.capture(value).then(expectAsync((Result result) { | 131 Result.capture(value).then(expectAsync1((Result result) { |
126 expect(result.isValue, isFalse); | 132 expect(result.isValue, isFalse); |
127 expect(result.isError, isTrue); | 133 expect(result.isError, isTrue); |
128 ErrorResult error = result.asError; | 134 ErrorResult error = result.asError; |
129 expect(error.error, equals("BAD")); | 135 expect(error.error, equals("BAD")); |
130 expect(error.stackTrace, same(stack)); | 136 expect(error.stackTrace, same(stack)); |
131 }), onError: (e, s) { | 137 }), onError: (e, s) { |
132 fail("Unexpected error: $e"); | 138 fail("Unexpected error: $e"); |
133 }); | 139 }); |
134 }); | 140 }); |
135 | 141 |
136 test("release future value", () { | 142 test("release future value", () { |
137 Future<Result<int>> future = | 143 Future<Result<int>> future = |
138 new Future<Result<int>>.value(new Result<int>.value(42)); | 144 new Future<Result<int>>.value(new Result<int>.value(42)); |
139 Result.release(future).then(expectAsync((v) { | 145 Result.release(future).then(expectAsync1((v) { |
140 expect(v, equals(42)); | 146 expect(v, equals(42)); |
141 }), onError: (e, s) { | 147 }), onError: (e, s) { |
142 fail("Unexpected error: $e"); | 148 fail("Unexpected error: $e"); |
143 }); | 149 }); |
144 }); | 150 }); |
145 | 151 |
146 test("release future error", () { | 152 test("release future error", () { |
147 // An error in the result is unwrapped and reified by release. | 153 // An error in the result is unwrapped and reified by release. |
148 Future<Result<bool>> future = | 154 Future<Result<bool>> future = |
149 new Future<Result<bool>>.value(new Result<bool>.error("BAD", stack)); | 155 new Future<Result<bool>>.value(new Result<bool>.error("BAD", stack)); |
150 Result.release(future).then((v) { | 156 Result.release(future).then((v) { |
151 fail("Unexpected value: $v"); | 157 fail("Unexpected value: $v"); |
152 }, onError: expectAsync((e, s) { | 158 }, onError: expectAsync2((e, s) { |
153 expect(e, equals("BAD")); | 159 expect(e, equals("BAD")); |
154 expect(s, same(stack)); | 160 expect(s, same(stack)); |
155 })); | 161 })); |
156 }); | 162 }); |
157 | 163 |
158 test("release future real error", () { | 164 test("release future real error", () { |
159 // An error in the error lane is passed through by release. | 165 // An error in the error lane is passed through by release. |
160 Future<Result<bool>> future = new Future<Result<bool>>.error("BAD", stack); | 166 Future<Result<bool>> future = new Future<Result<bool>>.error("BAD", stack); |
161 Result.release(future).then((v) { | 167 Result.release(future).then((v) { |
162 fail("Unexpected value: $v"); | 168 fail("Unexpected value: $v"); |
163 }, onError: expectAsync((e, s) { | 169 }, onError: expectAsync2((e, s) { |
164 expect(e, equals("BAD")); | 170 expect(e, equals("BAD")); |
165 expect(s, same(stack)); | 171 expect(s, same(stack)); |
166 })); | 172 })); |
167 }); | 173 }); |
168 | 174 |
169 test("capture stream", () { | 175 test("capture stream", () { |
170 StreamController<int> c = new StreamController<int>(); | 176 StreamController<int> c = new StreamController<int>(); |
171 Stream<Result> stream = Result.captureStream(c.stream); | 177 Stream<Result> stream = Result.captureStream(c.stream); |
172 var expectedList = new Queue.from([new Result.value(42), | 178 var expectedList = new Queue.from([ |
173 new Result.error("BAD", stack), | 179 new Result.value(42), |
174 new Result.value(37)]); | 180 new Result.error("BAD", stack), |
| 181 new Result.value(37) |
| 182 ]); |
175 void listener(Result actual) { | 183 void listener(Result actual) { |
176 expect(expectedList.isEmpty, isFalse); | 184 expect(expectedList.isEmpty, isFalse); |
177 expectResult(actual, expectedList.removeFirst()); | 185 expectResult(actual, expectedList.removeFirst()); |
178 } | 186 } |
179 stream.listen(expectAsync(listener, count: 3), | 187 |
180 onError: (e, s) { fail("Unexpected error: $e"); }, | 188 stream.listen(expectAsync1(listener, count: 3), onError: (e, s) { |
181 onDone: expectAsync((){}), | 189 fail("Unexpected error: $e"); |
182 cancelOnError: true); | 190 }, onDone: expectAsync0(() {}), cancelOnError: true); |
183 c.add(42); | 191 c.add(42); |
184 c.addError("BAD", stack); | 192 c.addError("BAD", stack); |
185 c.add(37); | 193 c.add(37); |
186 c.close(); | 194 c.close(); |
187 }); | 195 }); |
188 | 196 |
189 test("release stream", () { | 197 test("release stream", () { |
190 StreamController<Result<int>> c = new StreamController<Result<int>>(); | 198 StreamController<Result<int>> c = new StreamController<Result<int>>(); |
191 Stream<int> stream = Result.releaseStream(c.stream); | 199 Stream<int> stream = Result.releaseStream(c.stream); |
192 List events = [new Result<int>.value(42), | 200 var events = [ |
193 new Result<int>.error("BAD", stack), | 201 new Result<int>.value(42), |
194 new Result<int>.value(37)]; | 202 new Result<int>.error("BAD", stack), |
| 203 new Result<int>.value(37) |
| 204 ]; |
195 // Expect the data events, and an extra error event. | 205 // Expect the data events, and an extra error event. |
196 var expectedList = new Queue.from(events) | 206 var expectedList = new Queue.from(events) |
197 ..add(new Result.error("BAD2", stack)); | 207 ..add(new Result.error("BAD2", stack)); |
198 | 208 |
199 void dataListener(int v) { | 209 void dataListener(int v) { |
200 expect(expectedList.isEmpty, isFalse); | 210 expect(expectedList.isEmpty, isFalse); |
201 Result expected = expectedList.removeFirst(); | 211 Result expected = expectedList.removeFirst(); |
202 expect(expected.isValue, isTrue); | 212 expect(expected.isValue, isTrue); |
203 expect(v, equals(expected.asValue.value)); | 213 expect(v, equals(expected.asValue.value)); |
204 } | 214 } |
205 | 215 |
206 void errorListener(error, StackTrace stackTrace) { | 216 void errorListener(error, StackTrace stackTrace) { |
207 expect(expectedList.isEmpty, isFalse); | 217 expect(expectedList.isEmpty, isFalse); |
208 Result expected = expectedList.removeFirst(); | 218 Result expected = expectedList.removeFirst(); |
209 expect(expected.isError, isTrue); | 219 expect(expected.isError, isTrue); |
210 expect(error, equals(expected.asError.error)); | 220 expect(error, equals(expected.asError.error)); |
211 expect(stackTrace, same(expected.asError.stackTrace)); | 221 expect(stackTrace, same(expected.asError.stackTrace)); |
212 } | 222 } |
213 | 223 |
214 stream.listen(expectAsync(dataListener, count: 2), | 224 stream.listen(expectAsync1(dataListener, count: 2), |
215 onError: expectAsync(errorListener, count: 2), | 225 onError: expectAsync2(errorListener, count: 2), |
216 onDone: expectAsync((){})); | 226 onDone: expectAsync0(() {})); |
217 for (Result<int> result in events) { | 227 for (Result<int> result in events) { |
218 c.add(result); // Result value or error in data line. | 228 c.add(result); // Result value or error in data line. |
219 } | 229 } |
220 c.addError("BAD2", stack); // Error in error line. | 230 c.addError("BAD2", stack); // Error in error line. |
221 c.close(); | 231 c.close(); |
222 }); | 232 }); |
223 | 233 |
224 test("release stream cancel on error", () { | 234 test("release stream cancel on error", () { |
225 StreamController<Result<int>> c = new StreamController<Result<int>>(); | 235 StreamController<Result<int>> c = new StreamController<Result<int>>(); |
226 Stream<int> stream = Result.releaseStream(c.stream); | 236 Stream<int> stream = Result.releaseStream(c.stream); |
227 stream.listen(expectAsync((v) { expect(v, equals(42)); }), | 237 stream.listen(expectAsync1((v) { |
228 onError: expectAsync((e, s) { | 238 expect(v, equals(42)); |
229 expect(e, equals("BAD")); | 239 }), onError: expectAsync2((e, s) { |
230 expect(s, same(stack)); | 240 expect(e, equals("BAD")); |
231 }), | 241 expect(s, same(stack)); |
232 onDone: () { fail("Unexpected done event"); }, | 242 }), onDone: () { |
233 cancelOnError: true); | 243 fail("Unexpected done event"); |
| 244 }, cancelOnError: true); |
234 c.add(new Result.value(42)); | 245 c.add(new Result.value(42)); |
235 c.add(new Result.error("BAD", stack)); | 246 c.add(new Result.error("BAD", stack)); |
236 c.add(new Result.value(37)); | 247 c.add(new Result.value(37)); |
237 c.close(); | 248 c.close(); |
238 }); | 249 }); |
239 | 250 |
240 | |
241 test("flatten error 1", () { | 251 test("flatten error 1", () { |
242 Result<int> error = new Result<int>.error("BAD", stack); | 252 Result<int> error = new Result<int>.error("BAD", stack); |
243 Result<int> flattened = | 253 Result<int> flattened = |
244 Result.flatten(new Result<Result<int>>.error("BAD", stack)); | 254 Result.flatten(new Result<Result<int>>.error("BAD", stack)); |
245 expectResult(flattened, error); | 255 expectResult(flattened, error); |
246 }); | 256 }); |
247 | 257 |
248 test("flatten error 2", () { | 258 test("flatten error 2", () { |
249 Result<int> error = new Result<int>.error("BAD", stack); | 259 Result<int> error = new Result<int>.error("BAD", stack); |
250 Result<Result<int>> result = new Result<Result<int>>.value(error); | 260 Result<Result<int>> result = new Result<Result<int>>.value(error); |
251 Result<int> flattened = Result.flatten(result); | 261 Result<int> flattened = Result.flatten(result); |
252 expectResult(flattened, error); | 262 expectResult(flattened, error); |
253 }); | 263 }); |
254 | 264 |
255 test("flatten value", () { | 265 test("flatten value", () { |
256 Result<Result<int>> result = | 266 Result<Result<int>> result = |
257 new Result<Result<int>>.value(new Result<int>.value(42)); | 267 new Result<Result<int>>.value(new Result<int>.value(42)); |
258 expectResult(Result.flatten(result), new Result<int>.value(42)); | 268 expectResult(Result.flatten(result), new Result<int>.value(42)); |
259 }); | 269 }); |
260 | 270 |
261 test("handle unary", () { | 271 test("handle unary", () { |
262 var result = new Result.error("error", stack); | 272 ErrorResult result = new Result.error("error", stack); |
263 bool called = false; | 273 bool called = false; |
264 result.handle((error) { | 274 result.handle((error) { |
265 called = true; | 275 called = true; |
266 expect(error, "error"); | 276 expect(error, "error"); |
267 }); | 277 }); |
268 expect(called, isTrue); | 278 expect(called, isTrue); |
269 }); | 279 }); |
270 | 280 |
271 test("handle binary", () { | 281 test("handle binary", () { |
272 var result = new Result.error("error", stack); | 282 ErrorResult result = new Result.error("error", stack); |
273 bool called = false; | 283 bool called = false; |
274 result.handle((error, stackTrace) { | 284 result.handle((error, stackTrace) { |
275 called = true; | 285 called = true; |
276 expect(error, "error"); | 286 expect(error, "error"); |
277 expect(stackTrace, same(stack)); | 287 expect(stackTrace, same(stack)); |
278 }); | 288 }); |
279 expect(called, isTrue); | 289 expect(called, isTrue); |
280 }); | 290 }); |
281 | 291 |
282 test("handle unary and binary", () { | 292 test("handle unary and binary", () { |
283 var result = new Result.error("error", stack); | 293 ErrorResult result = new Result.error("error", stack); |
284 bool called = false; | 294 bool called = false; |
285 result.handle((error, [stackTrace]) { | 295 result.handle((error, [stackTrace]) { |
286 called = true; | 296 called = true; |
287 expect(error, "error"); | 297 expect(error, "error"); |
288 expect(stackTrace, same(stack)); | 298 expect(stackTrace, same(stack)); |
289 }); | 299 }); |
290 expect(called, isTrue); | 300 expect(called, isTrue); |
291 }); | 301 }); |
292 | 302 |
293 test("handle neither unary nor binary", () { | 303 test("handle neither unary nor binary", () { |
294 var result = new Result.error("error", stack); | 304 ErrorResult result = new Result.error("error", stack); |
295 expect(() => result.handle(() => fail("unreachable")), | 305 expect(() => result.handle(() => fail("unreachable")), throws); |
296 throws); | 306 expect(() => result.handle((a, b, c) => fail("unreachable")), throws); |
297 expect(() => result.handle((a, b, c) => fail("unreachable")), | 307 expect(() => result.handle((a, b, {c}) => fail("unreachable")), throws); |
298 throws); | 308 expect(() => result.handle((a, {b}) => fail("unreachable")), throws); |
299 expect(() => result.handle((a, b, {c}) => fail("unreachable")), | 309 expect(() => result.handle(({a, b}) => fail("unreachable")), throws); |
300 throws); | 310 expect(() => result.handle(({a}) => fail("unreachable")), throws); |
301 expect(() => result.handle((a, {b}) => fail("unreachable")), | |
302 throws); | |
303 expect(() => result.handle(({a, b}) => fail("unreachable")), | |
304 throws); | |
305 expect(() => result.handle(({a}) => fail("unreachable")), | |
306 throws); | |
307 }); | 311 }); |
308 } | 312 } |
309 | 313 |
310 void expectResult(Result actual, Result expected) { | 314 void expectResult(Result actual, Result expected) { |
311 expect(actual.isValue, equals(expected.isValue)); | 315 expect(actual.isValue, equals(expected.isValue)); |
312 expect(actual.isError, equals(expected.isError)); | 316 expect(actual.isError, equals(expected.isError)); |
313 if (actual.isValue) { | 317 if (actual.isValue) { |
314 expect(actual.asValue.value, equals(expected.asValue.value)); | 318 expect(actual.asValue.value, equals(expected.asValue.value)); |
315 } else { | 319 } else { |
316 expect(actual.asError.error, equals(expected.asError.error)); | 320 expect(actual.asError.error, equals(expected.asError.error)); |
317 expect(actual.asError.stackTrace, same(expected.asError.stackTrace)); | 321 expect(actual.asError.stackTrace, same(expected.asError.stackTrace)); |
318 } | 322 } |
319 } | 323 } |
320 | 324 |
321 class TestSink<T> implements EventSink<T> { | 325 class TestSink<T> implements EventSink<T> { |
322 final Function onData; | 326 final Function onData; |
323 final Function onError; | 327 final Function onError; |
324 final Function onDone; | 328 final Function onDone; |
325 | 329 |
326 TestSink({void this.onData(T data) : _nullData, | 330 TestSink( |
327 void this.onError(e, StackTrace s) : _nullError, | 331 {void this.onData(T data): _nullData, |
328 void this.onDone() : _nullDone }); | 332 void this.onError(e, StackTrace s): _nullError, |
| 333 void this.onDone(): _nullDone}); |
329 | 334 |
330 void add(T value) { onData(value); } | 335 void add(T value) { |
331 void addError(error, [StackTrace stack]) { onError(error, stack); } | 336 onData(value); |
332 void close() { onDone(); } | 337 } |
333 | 338 |
334 static void _nullData(value) { fail("Unexpected sink add: $value"); } | 339 void addError(error, [StackTrace stack]) { |
| 340 onError(error, stack); |
| 341 } |
| 342 |
| 343 void close() { |
| 344 onDone(); |
| 345 } |
| 346 |
| 347 static void _nullData(value) { |
| 348 fail("Unexpected sink add: $value"); |
| 349 } |
| 350 |
335 static void _nullError(e, StackTrace s) { | 351 static void _nullError(e, StackTrace s) { |
336 fail("Unexpected sink addError: $e"); | 352 fail("Unexpected sink addError: $e"); |
337 } | 353 } |
338 static void _nullDone() { fail("Unepxected sink close"); } | 354 |
| 355 static void _nullDone() { |
| 356 fail("Unepxected sink close"); |
| 357 } |
339 } | 358 } |
OLD | NEW |