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 library error_group_test; | 5 library error_group_test; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 | 8 |
9 import 'package:unittest/unittest.dart'; | 9 import 'package:unittest/unittest.dart'; |
10 | 10 |
(...skipping 10 matching lines...) Expand all Loading... |
21 // listeners. | 21 // listeners. |
22 | 22 |
23 main() { | 23 main() { |
24 group('with no futures or streams', () { | 24 group('with no futures or streams', () { |
25 setUp(() { | 25 setUp(() { |
26 errorGroup = new ErrorGroup(); | 26 errorGroup = new ErrorGroup(); |
27 }); | 27 }); |
28 | 28 |
29 test('should pass signaled errors to .done', () { | 29 test('should pass signaled errors to .done', () { |
30 expect(errorGroup.done, throwsFormatException); | 30 expect(errorGroup.done, throwsFormatException); |
31 errorGroup.signalError(new AsyncError(new FormatException())); | 31 errorGroup.signalError(new FormatException()); |
32 }); | 32 }); |
33 | 33 |
34 test("shouldn't allow additional futures or streams once an error has been " | 34 test("shouldn't allow additional futures or streams once an error has been " |
35 "signaled", () { | 35 "signaled", () { |
36 expect(errorGroup.done, throwsFormatException); | 36 expect(errorGroup.done, throwsFormatException); |
37 errorGroup.signalError(new AsyncError(new FormatException())); | 37 errorGroup.signalError(new FormatException()); |
38 | 38 |
39 expect(() => errorGroup.registerFuture(new Future.immediate(null)), | 39 expect(() => errorGroup.registerFuture(new Future.immediate(null)), |
40 throwsStateError); | 40 throwsStateError); |
41 expect(() => errorGroup.registerStream(new StreamController().stream), | 41 expect(() => errorGroup.registerStream(new StreamController().stream), |
42 throwsStateError); | 42 throwsStateError); |
43 }); | 43 }); |
44 }); | 44 }); |
45 | 45 |
46 group('with a single future', () { | 46 group('with a single future', () { |
47 Completer completer; | 47 Completer completer; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 'if it has a listener', () { | 80 'if it has a listener', () { |
81 expect(future, throwsFormatException); | 81 expect(future, throwsFormatException); |
82 expect(errorGroup.done, throwsFormatException); | 82 expect(errorGroup.done, throwsFormatException); |
83 completer.completeError(new FormatException()); | 83 completer.completeError(new FormatException()); |
84 }); | 84 }); |
85 | 85 |
86 test('should pass a signaled exception to the future if it has a listener ' | 86 test('should pass a signaled exception to the future if it has a listener ' |
87 'and should ignore a subsequent value from that future', () { | 87 'and should ignore a subsequent value from that future', () { |
88 expect(future, throwsFormatException); | 88 expect(future, throwsFormatException); |
89 // errorGroup shouldn't top-level the exception | 89 // errorGroup shouldn't top-level the exception |
90 errorGroup.signalError(new AsyncError(new FormatException())); | 90 errorGroup.signalError(new FormatException()); |
91 completer.complete('value'); | 91 completer.complete('value'); |
92 }); | 92 }); |
93 | 93 |
94 test('should pass a signaled exception to the future if it has a listener ' | 94 test('should pass a signaled exception to the future if it has a listener ' |
95 'and should ignore a subsequent exception from that future', () { | 95 'and should ignore a subsequent exception from that future', () { |
96 expect(future, throwsFormatException); | 96 expect(future, throwsFormatException); |
97 // errorGroup shouldn't top-level the exception | 97 // errorGroup shouldn't top-level the exception |
98 errorGroup.signalError(new AsyncError(new FormatException())); | 98 errorGroup.signalError(new FormatException()); |
99 completer.completeError(new ArgumentError()); | 99 completer.completeError(new ArgumentError()); |
100 }); | 100 }); |
101 | 101 |
102 test('should notify the error group of a signaled exception even if the ' | 102 test('should notify the error group of a signaled exception even if the ' |
103 'future has a listener', () { | 103 'future has a listener', () { |
104 expect(future, throwsFormatException); | 104 expect(future, throwsFormatException); |
105 expect(errorGroup.done, throwsFormatException); | 105 expect(errorGroup.done, throwsFormatException); |
106 errorGroup.signalError(new AsyncError(new FormatException())); | 106 errorGroup.signalError(new FormatException()); |
107 }); | 107 }); |
108 | 108 |
109 test("should complete .done if the future receives a value even if the " | 109 test("should complete .done if the future receives a value even if the " |
110 "future doesn't have a listener", () { | 110 "future doesn't have a listener", () { |
111 expect(errorGroup.done, completes); | 111 expect(errorGroup.done, completes); |
112 completer.complete('value'); | 112 completer.complete('value'); |
113 | 113 |
114 // A listener added afterwards should receive the value | 114 // A listener added afterwards should receive the value |
115 expect(errorGroup.done.then((_) => future), | 115 expect(errorGroup.done.then((_) => future), |
116 completion(equals('value'))); | 116 completion(equals('value'))); |
117 }); | 117 }); |
118 | 118 |
119 test("should pipe an exception from the future to .done if the future " | 119 test("should pipe an exception from the future to .done if the future " |
120 "doesn't have a listener", () { | 120 "doesn't have a listener", () { |
121 expect(errorGroup.done, throwsFormatException); | 121 expect(errorGroup.done, throwsFormatException); |
122 completer.completeError(new FormatException()); | 122 completer.completeError(new FormatException()); |
123 | 123 |
124 // A listener added afterwards should receive the exception | 124 // A listener added afterwards should receive the exception |
125 expect(errorGroup.done.catchError((_) { | 125 expect(errorGroup.done.catchError((_) { |
126 expect(future, throwsFormatException); | 126 expect(future, throwsFormatException); |
127 }), completes); | 127 }), completes); |
128 }); | 128 }); |
129 | 129 |
130 test("should pass a signaled exception to .done if the future doesn't have " | 130 test("should pass a signaled exception to .done if the future doesn't have " |
131 "a listener", | 131 "a listener", |
132 () { | 132 () { |
133 expect(errorGroup.done, throwsFormatException); | 133 expect(errorGroup.done, throwsFormatException); |
134 errorGroup.signalError(new AsyncError(new FormatException())); | 134 errorGroup.signalError(new FormatException()); |
135 | 135 |
136 // A listener added afterwards should receive the exception | 136 // A listener added afterwards should receive the exception |
137 expect(errorGroup.done.catchError((_) { | 137 expect(errorGroup.done.catchError((_) { |
138 completer.complete('value'); // should be ignored | 138 completer.complete('value'); // should be ignored |
139 expect(future, throwsFormatException); | 139 expect(future, throwsFormatException); |
140 }), completes); | 140 }), completes); |
141 }); | 141 }); |
142 }); | 142 }); |
143 | 143 |
144 group('with multiple futures', () { | 144 group('with multiple futures', () { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 }), completes); | 185 }), completes); |
186 }); | 186 }); |
187 | 187 |
188 test("shouldn't throw a top-level exception if an error is signaled after " | 188 test("shouldn't throw a top-level exception if an error is signaled after " |
189 "one listened future completes", () { | 189 "one listened future completes", () { |
190 expect(future1, completion(equals('value'))); | 190 expect(future1, completion(equals('value'))); |
191 completer1.complete('value'); | 191 completer1.complete('value'); |
192 | 192 |
193 expect(future1.then((_) { | 193 expect(future1.then((_) { |
194 // shouldn't cause a top-level exception | 194 // shouldn't cause a top-level exception |
195 errorGroup.signalError(new AsyncError(new FormatException())); | 195 errorGroup.signalError(new FormatException()); |
196 }), completes); | 196 }), completes); |
197 }); | 197 }); |
198 }); | 198 }); |
199 | 199 |
200 group('with a single stream', () { | 200 group('with a single stream', () { |
201 StreamController controller; | 201 StreamController controller; |
202 Stream stream; | 202 Stream stream; |
203 | 203 |
204 setUp(() { | 204 setUp(() { |
205 errorGroup = new ErrorGroup(); | 205 errorGroup = new ErrorGroup(); |
206 controller = new StreamController.broadcast(); | 206 controller = new StreamController.broadcast(); |
207 stream = errorGroup.registerStream(controller.stream); | 207 stream = errorGroup.registerStream(controller.stream); |
208 }); | 208 }); |
209 | 209 |
210 test('should pass through values from the stream', () { | 210 test('should pass through values from the stream', () { |
211 expect(stream.elementAt(0), completion(equals(1))); | 211 expect(stream.elementAt(0), completion(equals(1))); |
212 expect(stream.elementAt(1), completion(equals(2))); | 212 expect(stream.elementAt(1), completion(equals(2))); |
213 expect(errorGroup.done, completes); | 213 expect(errorGroup.done, completes); |
214 | 214 |
215 controller..add(1)..add(2)..close(); | 215 controller..add(1)..add(2)..close(); |
216 }); | 216 }); |
217 | 217 |
218 test('should pass through an error from the stream if it has a ' | 218 test('should pass through an error from the stream if it has a ' |
219 'listener', () { | 219 'listener', () { |
220 expect(stream.first, throwsFormatException); | 220 expect(stream.first, throwsFormatException); |
221 // errorGroup shouldn't top-level the exception | 221 // errorGroup shouldn't top-level the exception |
222 controller.addError(new AsyncError(new FormatException())); | 222 controller.addError(new FormatException()); |
223 }); | 223 }); |
224 | 224 |
225 test('should notify the error group of an exception from the stream even ' | 225 test('should notify the error group of an exception from the stream even ' |
226 'if it has a listener', () { | 226 'if it has a listener', () { |
227 expect(stream.first, throwsFormatException); | 227 expect(stream.first, throwsFormatException); |
228 expect(errorGroup.done, throwsFormatException); | 228 expect(errorGroup.done, throwsFormatException); |
229 controller.addError(new AsyncError(new FormatException())); | 229 controller.addError(new FormatException()); |
230 }); | 230 }); |
231 | 231 |
232 test('should pass a signaled exception to the stream if it has a listener ' | 232 test('should pass a signaled exception to the stream if it has a listener ' |
233 'and should unsubscribe that stream', () { | 233 'and should unsubscribe that stream', () { |
234 expect(stream.first, throwsFormatException); | 234 expect(stream.first, throwsFormatException); |
235 // errorGroup shouldn't top-level the exception | 235 // errorGroup shouldn't top-level the exception |
236 errorGroup.signalError(new AsyncError(new FormatException())); | 236 errorGroup.signalError(new FormatException()); |
237 | 237 |
238 expect(stream.first.catchError((_) { | 238 expect(stream.first.catchError((_) { |
239 controller.add('value'); | 239 controller.add('value'); |
240 return stream.isEmpty; | 240 return stream.isEmpty; |
241 }), completion(isTrue)); | 241 }), completion(isTrue)); |
242 }); | 242 }); |
243 | 243 |
244 test('should notify the error group of a signaled exception even if the ' | 244 test('should notify the error group of a signaled exception even if the ' |
245 'stream has a listener', () { | 245 'stream has a listener', () { |
246 expect(stream.first, throwsFormatException); | 246 expect(stream.first, throwsFormatException); |
247 expect(errorGroup.done, throwsFormatException); | 247 expect(errorGroup.done, throwsFormatException); |
248 errorGroup.signalError(new AsyncError(new FormatException())); | 248 errorGroup.signalError(new FormatException()); |
249 }); | 249 }); |
250 | 250 |
251 test("should complete .done when the stream is done even if the stream " | 251 test("should complete .done when the stream is done even if the stream " |
252 "doesn't have a listener", () { | 252 "doesn't have a listener", () { |
253 expect(errorGroup.done, completes); | 253 expect(errorGroup.done, completes); |
254 controller.add('value'); | 254 controller.add('value'); |
255 controller.close(); | 255 controller.close(); |
256 | 256 |
257 // A listener added afterwards should see an empty stream, since it's not | 257 // A listener added afterwards should see an empty stream, since it's not |
258 // single-subscription | 258 // single-subscription |
259 expect(errorGroup.done.then((_) => stream.toList()), | 259 expect(errorGroup.done.then((_) => stream.toList()), |
260 completion(isEmpty)); | 260 completion(isEmpty)); |
261 }); | 261 }); |
262 | 262 |
263 test("should pipe an exception from the stream to .done if the stream " | 263 test("should pipe an exception from the stream to .done if the stream " |
264 "doesn't have a listener", () { | 264 "doesn't have a listener", () { |
265 expect(errorGroup.done, throwsFormatException); | 265 expect(errorGroup.done, throwsFormatException); |
266 controller.addError(new AsyncError(new FormatException())); | 266 controller.addError(new FormatException()); |
267 | 267 |
268 // A listener added afterwards should see an empty stream, since it's not | 268 // A listener added afterwards should see an empty stream, since it's not |
269 // single-subscription | 269 // single-subscription |
270 expect(errorGroup.done.catchError((_) { | 270 expect(errorGroup.done.catchError((_) { |
271 controller.add('value'); // should be ignored | 271 controller.add('value'); // should be ignored |
272 return stream.toList(); | 272 return stream.toList(); |
273 }), completion(isEmpty)); | 273 }), completion(isEmpty)); |
274 }); | 274 }); |
275 | 275 |
276 test("should pass a signaled exception to .done if the stream doesn't " | 276 test("should pass a signaled exception to .done if the stream doesn't " |
277 "have a listener", | 277 "have a listener", |
278 () { | 278 () { |
279 expect(errorGroup.done, throwsFormatException); | 279 expect(errorGroup.done, throwsFormatException); |
280 errorGroup.signalError(new AsyncError(new FormatException())); | 280 errorGroup.signalError(new FormatException()); |
281 | 281 |
282 // A listener added afterwards should receive the exception | 282 // A listener added afterwards should receive the exception |
283 expect(errorGroup.done.catchError((_) { | 283 expect(errorGroup.done.catchError((_) { |
284 controller.add('value'); // should be ignored | 284 controller.add('value'); // should be ignored |
285 return stream.toList(); | 285 return stream.toList(); |
286 }), completion(isEmpty)); | 286 }), completion(isEmpty)); |
287 }); | 287 }); |
288 }); | 288 }); |
289 | 289 |
290 group('with a single single-subscription stream', () { | 290 group('with a single single-subscription stream', () { |
(...skipping 13 matching lines...) Expand all Loading... |
304 controller.close(); | 304 controller.close(); |
305 | 305 |
306 // A listener added afterwards should receive the value | 306 // A listener added afterwards should receive the value |
307 expect(errorGroup.done.then((_) => stream.toList()), | 307 expect(errorGroup.done.then((_) => stream.toList()), |
308 completion(equals(['value']))); | 308 completion(equals(['value']))); |
309 }); | 309 }); |
310 | 310 |
311 test("should pipe an exception from the stream to .done if the stream " | 311 test("should pipe an exception from the stream to .done if the stream " |
312 "doesn't have a listener", () { | 312 "doesn't have a listener", () { |
313 expect(errorGroup.done, throwsFormatException); | 313 expect(errorGroup.done, throwsFormatException); |
314 controller.addError(new AsyncError(new FormatException())); | 314 controller.addError(new FormatException()); |
315 | 315 |
316 // A listener added afterwards should receive the exception | 316 // A listener added afterwards should receive the exception |
317 expect(errorGroup.done.catchError((_) { | 317 expect(errorGroup.done.catchError((_) { |
318 controller.add('value'); // should be ignored | 318 controller.add('value'); // should be ignored |
319 expect(stream.first, throwsFormatException); | 319 expect(stream.first, throwsFormatException); |
320 }), completes); | 320 }), completes); |
321 }); | 321 }); |
322 | 322 |
323 test("should pass a signaled exception to .done if the stream doesn't " | 323 test("should pass a signaled exception to .done if the stream doesn't " |
324 "have a listener", | 324 "have a listener", |
325 () { | 325 () { |
326 expect(errorGroup.done, throwsFormatException); | 326 expect(errorGroup.done, throwsFormatException); |
327 errorGroup.signalError(new AsyncError(new FormatException())); | 327 errorGroup.signalError(new FormatException()); |
328 | 328 |
329 // A listener added afterwards should receive the exception | 329 // A listener added afterwards should receive the exception |
330 expect(errorGroup.done.catchError((_) { | 330 expect(errorGroup.done.catchError((_) { |
331 controller.add('value'); // should be ignored | 331 controller.add('value'); // should be ignored |
332 expect(stream.first, throwsFormatException); | 332 expect(stream.first, throwsFormatException); |
333 }), completes); | 333 }), completes); |
334 }); | 334 }); |
335 }); | 335 }); |
336 | 336 |
337 group('with multiple streams', () { | 337 group('with multiple streams', () { |
338 StreamController controller1; | 338 StreamController controller1; |
339 StreamController controller2; | 339 StreamController controller2; |
340 Stream stream1; | 340 Stream stream1; |
341 Stream stream2; | 341 Stream stream2; |
342 | 342 |
343 setUp(() { | 343 setUp(() { |
344 errorGroup = new ErrorGroup(); | 344 errorGroup = new ErrorGroup(); |
345 controller1 = new StreamController.broadcast(); | 345 controller1 = new StreamController.broadcast(); |
346 controller2 = new StreamController.broadcast(); | 346 controller2 = new StreamController.broadcast(); |
347 stream1 = errorGroup.registerStream(controller1.stream); | 347 stream1 = errorGroup.registerStream(controller1.stream); |
348 stream2 = errorGroup.registerStream(controller2.stream); | 348 stream2 = errorGroup.registerStream(controller2.stream); |
349 }); | 349 }); |
350 | 350 |
351 test("should pipe exceptions from one stream to the other and to .done", | 351 test("should pipe exceptions from one stream to the other and to .done", |
352 () { | 352 () { |
353 expect(stream1.first, throwsFormatException); | 353 expect(stream1.first, throwsFormatException); |
354 expect(stream2.first, throwsFormatException); | 354 expect(stream2.first, throwsFormatException); |
355 expect(errorGroup.done, throwsFormatException); | 355 expect(errorGroup.done, throwsFormatException); |
356 | 356 |
357 controller1.addError(new AsyncError(new FormatException())); | 357 controller1.addError(new FormatException()); |
358 }); | 358 }); |
359 | 359 |
360 test("each future should be able to emit values independently", () { | 360 test("each future should be able to emit values independently", () { |
361 expect(stream1.toList(), completion(equals(['value1.1', 'value1.2']))); | 361 expect(stream1.toList(), completion(equals(['value1.1', 'value1.2']))); |
362 expect(stream2.toList(), completion(equals(['value2.1', 'value2.2']))); | 362 expect(stream2.toList(), completion(equals(['value2.1', 'value2.2']))); |
363 expect(errorGroup.done, completes); | 363 expect(errorGroup.done, completes); |
364 | 364 |
365 controller1..add('value1.1')..add('value1.2')..close(); | 365 controller1..add('value1.1')..add('value1.2')..close(); |
366 controller2..add('value2.1')..add('value2.2')..close(); | 366 controller2..add('value2.1')..add('value2.2')..close(); |
367 }); | 367 }); |
368 | 368 |
369 test("shouldn't throw a top-level exception if a stream receives an error " | 369 test("shouldn't throw a top-level exception if a stream receives an error " |
370 "after the other listened stream completes", () { | 370 "after the other listened stream completes", () { |
371 expect(stream1.toList(), completion(equals(['value1', 'value2']))); | 371 expect(stream1.toList(), completion(equals(['value1', 'value2']))); |
372 controller1..add('value1')..add('value2')..close(); | 372 controller1..add('value1')..add('value2')..close(); |
373 | 373 |
374 expect(stream1.toList().then((_) { | 374 expect(stream1.toList().then((_) { |
375 // shouldn't cause a top-level exception | 375 // shouldn't cause a top-level exception |
376 controller2.addError(new AsyncError(new FormatException())); | 376 controller2.addError(new FormatException()); |
377 }), completes); | 377 }), completes); |
378 }); | 378 }); |
379 | 379 |
380 test("shouldn't throw a top-level exception if an error is signaled after " | 380 test("shouldn't throw a top-level exception if an error is signaled after " |
381 "one listened stream completes", () { | 381 "one listened stream completes", () { |
382 expect(stream1.toList(), completion(equals(['value1', 'value2']))); | 382 expect(stream1.toList(), completion(equals(['value1', 'value2']))); |
383 controller1..add('value1')..add('value2')..close(); | 383 controller1..add('value1')..add('value2')..close(); |
384 | 384 |
385 expect(stream1.toList().then((_) { | 385 expect(stream1.toList().then((_) { |
386 // shouldn't cause a top-level exception | 386 // shouldn't cause a top-level exception |
387 errorGroup.signalError(new AsyncError(new FormatException())); | 387 errorGroup.signalError(new FormatException()); |
388 }), completes); | 388 }), completes); |
389 }); | 389 }); |
390 }); | 390 }); |
391 | 391 |
392 group('with a stream and a future', () { | 392 group('with a stream and a future', () { |
393 StreamController controller; | 393 StreamController controller; |
394 Stream stream; | 394 Stream stream; |
395 Completer completer; | 395 Completer completer; |
396 Future future; | 396 Future future; |
397 | 397 |
398 setUp(() { | 398 setUp(() { |
399 errorGroup = new ErrorGroup(); | 399 errorGroup = new ErrorGroup(); |
400 controller = new StreamController.broadcast(); | 400 controller = new StreamController.broadcast(); |
401 stream = errorGroup.registerStream(controller.stream); | 401 stream = errorGroup.registerStream(controller.stream); |
402 completer = new Completer(); | 402 completer = new Completer(); |
403 future = errorGroup.registerFuture(completer.future); | 403 future = errorGroup.registerFuture(completer.future); |
404 }); | 404 }); |
405 | 405 |
406 test("should pipe exceptions from the stream to the future", () { | 406 test("should pipe exceptions from the stream to the future", () { |
407 expect(stream.first, throwsFormatException); | 407 expect(stream.first, throwsFormatException); |
408 expect(future, throwsFormatException); | 408 expect(future, throwsFormatException); |
409 expect(errorGroup.done, throwsFormatException); | 409 expect(errorGroup.done, throwsFormatException); |
410 | 410 |
411 controller.addError(new AsyncError(new FormatException())); | 411 controller.addError(new FormatException()); |
412 }); | 412 }); |
413 | 413 |
414 test("should pipe exceptions from the future to the stream", () { | 414 test("should pipe exceptions from the future to the stream", () { |
415 expect(stream.first, throwsFormatException); | 415 expect(stream.first, throwsFormatException); |
416 expect(future, throwsFormatException); | 416 expect(future, throwsFormatException); |
417 expect(errorGroup.done, throwsFormatException); | 417 expect(errorGroup.done, throwsFormatException); |
418 | 418 |
419 completer.completeError(new FormatException()); | 419 completer.completeError(new FormatException()); |
420 }); | 420 }); |
421 | 421 |
422 test("the stream and the future should be able to complete/emit values " | 422 test("the stream and the future should be able to complete/emit values " |
423 "independently", () { | 423 "independently", () { |
424 expect(stream.toList(), completion(equals(['value1.1', 'value1.2']))); | 424 expect(stream.toList(), completion(equals(['value1.1', 'value1.2']))); |
425 expect(future, completion(equals('value2.0'))); | 425 expect(future, completion(equals('value2.0'))); |
426 expect(errorGroup.done, completes); | 426 expect(errorGroup.done, completes); |
427 | 427 |
428 controller..add('value1.1')..add('value1.2')..close(); | 428 controller..add('value1.1')..add('value1.2')..close(); |
429 completer.complete('value2.0'); | 429 completer.complete('value2.0'); |
430 }); | 430 }); |
431 | 431 |
432 test("shouldn't throw a top-level exception if the stream receives an error
" | 432 test("shouldn't throw a top-level exception if the stream receives an error
" |
433 "after the listened future completes", () { | 433 "after the listened future completes", () { |
434 expect(future, completion(equals('value'))); | 434 expect(future, completion(equals('value'))); |
435 completer.complete('value'); | 435 completer.complete('value'); |
436 | 436 |
437 expect(future.then((_) { | 437 expect(future.then((_) { |
438 // shouldn't cause a top-level exception | 438 // shouldn't cause a top-level exception |
439 controller.addError(new AsyncError(new FormatException())); | 439 controller.addError(new FormatException()); |
440 }), completes); | 440 }), completes); |
441 }); | 441 }); |
442 | 442 |
443 test("shouldn't throw a top-level exception if the future receives an " | 443 test("shouldn't throw a top-level exception if the future receives an " |
444 "error after the listened stream completes", () { | 444 "error after the listened stream completes", () { |
445 expect(stream.toList(), completion(equals(['value1', 'value2']))); | 445 expect(stream.toList(), completion(equals(['value1', 'value2']))); |
446 controller..add('value1')..add('value2')..close(); | 446 controller..add('value1')..add('value2')..close(); |
447 | 447 |
448 expect(stream.toList().then((_) { | 448 expect(stream.toList().then((_) { |
449 // shouldn't cause a top-level exception | 449 // shouldn't cause a top-level exception |
450 completer.completeError(new FormatException()); | 450 completer.completeError(new FormatException()); |
451 }), completes); | 451 }), completes); |
452 }); | 452 }); |
453 }); | 453 }); |
454 } | 454 } |
OLD | NEW |