| 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 13 matching lines...) Expand all  Loading... | 
|   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 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( | 
|   35         "signaled", () { |   35         "shouldn't allow additional futures or streams once an error has been " | 
 |   36             "signaled", | 
 |   37         () { | 
|   36       expect(errorGroup.done, throwsFormatException); |   38       expect(errorGroup.done, throwsFormatException); | 
|   37       errorGroup.signalError(new FormatException()); |   39       errorGroup.signalError(new FormatException()); | 
|   38  |   40  | 
|   39       expect(() => errorGroup.registerFuture(new Future.value()), |   41       expect( | 
 |   42           () => errorGroup.registerFuture(new Future.value()), | 
|   40           throwsStateError); |   43           throwsStateError); | 
|   41       expect(() => errorGroup.registerStream( |   44       expect( | 
|   42           new StreamController(sync: true).stream), |   45           () => errorGroup.registerStream(new StreamController(sync: true).strea
     m), | 
|   43           throwsStateError); |   46           throwsStateError); | 
|   44     }); |   47     }); | 
|   45   }); |   48   }); | 
|   46  |   49  | 
|   47   group('with a single future', () { |   50   group('with a single future', () { | 
|   48     Completer completer; |   51     Completer completer; | 
|   49     Future future; |   52     Future future; | 
|   50  |   53  | 
|   51     setUp(() { |   54     setUp(() { | 
|   52       errorGroup = new ErrorGroup(); |   55       errorGroup = new ErrorGroup(); | 
|   53       completer = new Completer(); |   56       completer = new Completer(); | 
|   54       future = errorGroup.registerFuture(completer.future); |   57       future = errorGroup.registerFuture(completer.future); | 
|   55     }); |   58     }); | 
|   56  |   59  | 
|   57     test('should pass through a value from the future', () { |   60     test('should pass through a value from the future', () { | 
|   58       expect(future, completion(equals('value'))); |   61       expect(future, completion(equals('value'))); | 
|   59       expect(errorGroup.done, completes); |   62       expect(errorGroup.done, completes); | 
|   60       completer.complete('value'); |   63       completer.complete('value'); | 
|   61     }); |   64     }); | 
|   62  |   65  | 
|   63     test("shouldn't allow additional futures or streams once .done has " |   66     test( | 
|   64         "been called", () { |   67         "shouldn't allow additional futures or streams once .done has " "been ca
     lled", | 
 |   68         () { | 
|   65       completer.complete('value'); |   69       completer.complete('value'); | 
|   66  |   70  | 
|   67       expect(completer.future |   71       expect( | 
|   68                  .then((_) => errorGroup.registerFuture(new Future.value())), |   72           completer.future.then((_) => errorGroup.registerFuture(new Future.valu
     e())), | 
|   69              throwsStateError); |   73           throwsStateError); | 
|   70       expect(completer.future |   74       expect( | 
|   71                  .then((_) => errorGroup.registerStream( |   75           completer.future.then( | 
|   72                      new StreamController(sync: true).stream)), |   76               (_) => errorGroup.registerStream(new StreamController(sync: true).
     stream)), | 
|   73             throwsStateError); |   77           throwsStateError); | 
|   74     }); |   78     }); | 
|   75  |   79  | 
|   76     test('should pass through an exception from the future if it has a ' |   80     test( | 
|   77         'listener', () { |   81         'should pass through an exception from the future if it has a ' 'listene
     r', | 
 |   82         () { | 
|   78       expect(future, throwsFormatException); |   83       expect(future, throwsFormatException); | 
|   79       // errorGroup shouldn't top-level the exception |   84       // errorGroup shouldn't top-level the exception | 
|   80       completer.completeError(new FormatException()); |   85       completer.completeError(new FormatException()); | 
|   81     }); |   86     }); | 
|   82  |   87  | 
|   83     test('should notify the error group of an exception from the future even ' |   88     test( | 
|   84         'if it has a listener', () { |   89         'should notify the error group of an exception from the future even ' | 
 |   90             'if it has a listener', | 
 |   91         () { | 
|   85       expect(future, throwsFormatException); |   92       expect(future, throwsFormatException); | 
|   86       expect(errorGroup.done, throwsFormatException); |   93       expect(errorGroup.done, throwsFormatException); | 
|   87       completer.completeError(new FormatException()); |   94       completer.completeError(new FormatException()); | 
|   88     }); |   95     }); | 
|   89  |   96  | 
|   90     test('should pass a signaled exception to the future if it has a listener ' |   97     test( | 
|   91         'and should ignore a subsequent value from that future', () { |   98         'should pass a signaled exception to the future if it has a listener ' | 
 |   99             'and should ignore a subsequent value from that future', | 
 |  100         () { | 
|   92       expect(future, throwsFormatException); |  101       expect(future, throwsFormatException); | 
|   93       // errorGroup shouldn't top-level the exception |  102       // errorGroup shouldn't top-level the exception | 
|   94       errorGroup.signalError(new FormatException()); |  103       errorGroup.signalError(new FormatException()); | 
|   95       completer.complete('value'); |  104       completer.complete('value'); | 
|   96     }); |  105     }); | 
|   97  |  106  | 
|   98     test('should pass a signaled exception to the future if it has a listener ' |  107     test( | 
|   99         'and should ignore a subsequent exception from that future', () { |  108         'should pass a signaled exception to the future if it has a listener ' | 
 |  109             'and should ignore a subsequent exception from that future', | 
 |  110         () { | 
|  100       expect(future, throwsFormatException); |  111       expect(future, throwsFormatException); | 
|  101       // errorGroup shouldn't top-level the exception |  112       // errorGroup shouldn't top-level the exception | 
|  102       errorGroup.signalError(new FormatException()); |  113       errorGroup.signalError(new FormatException()); | 
|  103       completer.completeError(new ArgumentError()); |  114       completer.completeError(new ArgumentError()); | 
|  104     }); |  115     }); | 
|  105  |  116  | 
|  106     test('should notify the error group of a signaled exception even if the ' |  117     test( | 
|  107         'future has a listener', () { |  118         'should notify the error group of a signaled exception even if the ' | 
 |  119             'future has a listener', | 
 |  120         () { | 
|  108       expect(future, throwsFormatException); |  121       expect(future, throwsFormatException); | 
|  109       expect(errorGroup.done, throwsFormatException); |  122       expect(errorGroup.done, throwsFormatException); | 
|  110       errorGroup.signalError(new FormatException()); |  123       errorGroup.signalError(new FormatException()); | 
|  111     }); |  124     }); | 
|  112  |  125  | 
|  113     test("should complete .done if the future receives a value even if the " |  126     test( | 
|  114         "future doesn't have a listener", () { |  127         "should complete .done if the future receives a value even if the " | 
 |  128             "future doesn't have a listener", | 
 |  129         () { | 
|  115       expect(errorGroup.done, completes); |  130       expect(errorGroup.done, completes); | 
|  116       completer.complete('value'); |  131       completer.complete('value'); | 
|  117  |  132  | 
|  118       // A listener added afterwards should receive the value |  133       // A listener added afterwards should receive the value | 
|  119       expect(errorGroup.done.then((_) => future), |  134       expect(errorGroup.done.then((_) => future), completion(equals('value'))); | 
|  120           completion(equals('value'))); |  | 
|  121     }); |  135     }); | 
|  122  |  136  | 
|  123     test("should pipe an exception from the future to .done if the future " |  137     test( | 
|  124         "doesn't have a listener", () { |  138         "should pipe an exception from the future to .done if the future " | 
 |  139             "doesn't have a listener", | 
 |  140         () { | 
|  125       expect(errorGroup.done, throwsFormatException); |  141       expect(errorGroup.done, throwsFormatException); | 
|  126       completer.completeError(new FormatException()); |  142       completer.completeError(new FormatException()); | 
|  127  |  143  | 
|  128       // A listener added afterwards should receive the exception |  144       // A listener added afterwards should receive the exception | 
|  129       expect(errorGroup.done.catchError((_) { |  145       expect(errorGroup.done.catchError((_) { | 
|  130         expect(future, throwsFormatException); |  146         expect(future, throwsFormatException); | 
|  131       }), completes); |  147       }), completes); | 
|  132     }); |  148     }); | 
|  133  |  149  | 
|  134     test("should pass a signaled exception to .done if the future doesn't have " |  150     test( | 
|  135         "a listener", |  151         "should pass a signaled exception to .done if the future doesn't have " | 
 |  152             "a listener", | 
|  136         () { |  153         () { | 
|  137       expect(errorGroup.done, throwsFormatException); |  154       expect(errorGroup.done, throwsFormatException); | 
|  138       errorGroup.signalError(new FormatException()); |  155       errorGroup.signalError(new FormatException()); | 
|  139  |  156  | 
|  140       // A listener added afterwards should receive the exception |  157       // A listener added afterwards should receive the exception | 
|  141       expect(errorGroup.done.catchError((_) { |  158       expect(errorGroup.done.catchError((_) { | 
|  142         completer.complete('value'); // should be ignored |  159         completer.complete('value'); // should be ignored | 
|  143         expect(future, throwsFormatException); |  160         expect(future, throwsFormatException); | 
|  144       }), completes); |  161       }), completes); | 
|  145     }); |  162     }); | 
|  146   }); |  163   }); | 
|  147  |  164  | 
|  148   group('with multiple futures', () { |  165   group('with multiple futures', () { | 
|  149     Completer completer1; |  166     Completer completer1; | 
|  150     Completer completer2; |  167     Completer completer2; | 
|  151     Future future1; |  168     Future future1; | 
|  152     Future future2; |  169     Future future2; | 
|  153  |  170  | 
|  154     setUp(() { |  171     setUp(() { | 
|  155       errorGroup = new ErrorGroup(); |  172       errorGroup = new ErrorGroup(); | 
|  156       completer1 = new Completer(); |  173       completer1 = new Completer(); | 
|  157       completer2 = new Completer(); |  174       completer2 = new Completer(); | 
|  158       future1 = errorGroup.registerFuture(completer1.future); |  175       future1 = errorGroup.registerFuture(completer1.future); | 
|  159       future2 = errorGroup.registerFuture(completer2.future); |  176       future2 = errorGroup.registerFuture(completer2.future); | 
|  160     }); |  177     }); | 
|  161  |  178  | 
|  162     test("should pipe exceptions from one future to the other and to " |  179     test( | 
|  163         ".complete", () { |  180         "should pipe exceptions from one future to the other and to " ".complete
     ", | 
 |  181         () { | 
|  164       expect(future1, throwsFormatException); |  182       expect(future1, throwsFormatException); | 
|  165       expect(future2, throwsFormatException); |  183       expect(future2, throwsFormatException); | 
|  166       expect(errorGroup.done, throwsFormatException); |  184       expect(errorGroup.done, throwsFormatException); | 
|  167  |  185  | 
|  168       completer1.completeError(new FormatException()); |  186       completer1.completeError(new FormatException()); | 
|  169     }); |  187     }); | 
|  170  |  188  | 
|  171     test("each future should be able to complete with a value " |  189     test( | 
|  172         "independently", () { |  190         "each future should be able to complete with a value " "independently", | 
 |  191         () { | 
|  173       expect(future1, completion(equals('value1'))); |  192       expect(future1, completion(equals('value1'))); | 
|  174       expect(future2, completion(equals('value2'))); |  193       expect(future2, completion(equals('value2'))); | 
|  175       expect(errorGroup.done, completes); |  194       expect(errorGroup.done, completes); | 
|  176  |  195  | 
|  177       completer1.complete('value1'); |  196       completer1.complete('value1'); | 
|  178       completer2.complete('value2'); |  197       completer2.complete('value2'); | 
|  179     }); |  198     }); | 
|  180  |  199  | 
|  181     test("shouldn't throw a top-level exception if a future receives an error " |  200     test( | 
|  182         "after the other listened future completes", () { |  201         "shouldn't throw a top-level exception if a future receives an error " | 
 |  202             "after the other listened future completes", | 
 |  203         () { | 
|  183       expect(future1, completion(equals('value'))); |  204       expect(future1, completion(equals('value'))); | 
|  184       completer1.complete('value'); |  205       completer1.complete('value'); | 
|  185  |  206  | 
|  186       expect(future1.then((_) { |  207       expect(future1.then((_) { | 
|  187         // shouldn't cause a top-level exception |  208         // shouldn't cause a top-level exception | 
|  188         completer2.completeError(new FormatException()); |  209         completer2.completeError(new FormatException()); | 
|  189       }), completes); |  210       }), completes); | 
|  190     }); |  211     }); | 
|  191  |  212  | 
|  192     test("shouldn't throw a top-level exception if an error is signaled after " |  213     test( | 
|  193         "one listened future completes", () { |  214         "shouldn't throw a top-level exception if an error is signaled after " | 
 |  215             "one listened future completes", | 
 |  216         () { | 
|  194       expect(future1, completion(equals('value'))); |  217       expect(future1, completion(equals('value'))); | 
|  195       completer1.complete('value'); |  218       completer1.complete('value'); | 
|  196  |  219  | 
|  197       expect(future1.then((_) { |  220       expect(future1.then((_) { | 
|  198         // shouldn't cause a top-level exception |  221         // shouldn't cause a top-level exception | 
|  199         errorGroup.signalError(new FormatException()); |  222         errorGroup.signalError(new FormatException()); | 
|  200       }), completes); |  223       }), completes); | 
|  201     }); |  224     }); | 
|  202   }); |  225   }); | 
|  203  |  226  | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|  217         expect(hasNext, isTrue); |  240         expect(hasNext, isTrue); | 
|  218         expect(iter.current, equals(1)); |  241         expect(iter.current, equals(1)); | 
|  219         iter.moveNext().then((hasNext) { |  242         iter.moveNext().then((hasNext) { | 
|  220           expect(hasNext, isTrue); |  243           expect(hasNext, isTrue); | 
|  221           expect(iter.current, equals(2)); |  244           expect(iter.current, equals(2)); | 
|  222           expect(iter.moveNext(), completion(isFalse)); |  245           expect(iter.moveNext(), completion(isFalse)); | 
|  223         }); |  246         }); | 
|  224       }); |  247       }); | 
|  225       expect(errorGroup.done, completes); |  248       expect(errorGroup.done, completes); | 
|  226  |  249  | 
|  227       controller..add(1)..add(2)..close(); |  250       controller | 
 |  251           ..add(1) | 
 |  252           ..add(2) | 
 |  253           ..close(); | 
|  228     }); |  254     }); | 
|  229  |  255  | 
|  230     test('should pass through an error from the stream if it has a ' |  256     test( | 
|  231         'listener', () { |  257         'should pass through an error from the stream if it has a ' 'listener', | 
 |  258         () { | 
|  232       expect(stream.first, throwsFormatException); |  259       expect(stream.first, throwsFormatException); | 
|  233       // errorGroup shouldn't top-level the exception |  260       // errorGroup shouldn't top-level the exception | 
|  234       controller.addError(new FormatException()); |  261       controller.addError(new FormatException()); | 
|  235     }); |  262     }); | 
|  236  |  263  | 
|  237     test('should notify the error group of an exception from the stream even ' |  264     test( | 
|  238         'if it has a listener', () { |  265         'should notify the error group of an exception from the stream even ' | 
 |  266             'if it has a listener', | 
 |  267         () { | 
|  239       expect(stream.first, throwsFormatException); |  268       expect(stream.first, throwsFormatException); | 
|  240       expect(errorGroup.done, throwsFormatException); |  269       expect(errorGroup.done, throwsFormatException); | 
|  241       controller.addError(new FormatException()); |  270       controller.addError(new FormatException()); | 
|  242     }); |  271     }); | 
|  243  |  272  | 
|  244     test('should pass a signaled exception to the stream if it has a listener ' |  273     test( | 
|  245          'and should unsubscribe that stream', () { |  274         'should pass a signaled exception to the stream if it has a listener ' | 
 |  275             'and should unsubscribe that stream', | 
 |  276         () { | 
|  246       // errorGroup shouldn't top-level the exception |  277       // errorGroup shouldn't top-level the exception | 
|  247       expect(stream.first, throwsFormatException); |  278       expect(stream.first, throwsFormatException); | 
|  248       errorGroup.signalError(new FormatException()); |  279       errorGroup.signalError(new FormatException()); | 
|  249  |  280  | 
|  250       expect(newFuture(() { |  281       expect(newFuture(() { | 
|  251         controller.add('value'); |  282         controller.add('value'); | 
|  252       }), completes); |  283       }), completes); | 
|  253     }); |  284     }); | 
|  254  |  285  | 
|  255     test('should notify the error group of a signaled exception even if the ' |  286     test( | 
|  256         'stream has a listener', () { |  287         'should notify the error group of a signaled exception even if the ' | 
 |  288             'stream has a listener', | 
 |  289         () { | 
|  257       expect(stream.first, throwsFormatException); |  290       expect(stream.first, throwsFormatException); | 
|  258       expect(errorGroup.done, throwsFormatException); |  291       expect(errorGroup.done, throwsFormatException); | 
|  259       errorGroup.signalError(new FormatException()); |  292       errorGroup.signalError(new FormatException()); | 
|  260     }); |  293     }); | 
|  261  |  294  | 
|  262     test("should see one value and complete .done when the stream is done even " |  295     test( | 
|  263          "if the stream doesn't have a listener", () { |  296         "should see one value and complete .done when the stream is done even " | 
 |  297             "if the stream doesn't have a listener", | 
 |  298         () { | 
|  264       expect(errorGroup.done, completes); |  299       expect(errorGroup.done, completes); | 
|  265       controller.add('value'); |  300       controller.add('value'); | 
|  266       controller.close(); |  301       controller.close(); | 
|  267  |  302  | 
|  268       // Now that broadcast controllers have been removed a listener should |  303       // Now that broadcast controllers have been removed a listener should | 
|  269       // see the value that has been put into the controller. |  304       // see the value that has been put into the controller. | 
|  270       expect(errorGroup.done.then((_) => stream.toList()), |  305       expect( | 
 |  306           errorGroup.done.then((_) => stream.toList()), | 
|  271           completion(equals(['value']))); |  307           completion(equals(['value']))); | 
|  272     }); |  308     }); | 
|  273  |  309  | 
|  274   }); |  310   }); | 
|  275  |  311  | 
|  276   group('with a single single-subscription stream', () { |  312   group('with a single single-subscription stream', () { | 
|  277     StreamController controller; |  313     StreamController controller; | 
|  278     Stream stream; |  314     Stream stream; | 
|  279  |  315  | 
|  280     setUp(() { |  316     setUp(() { | 
|  281       errorGroup = new ErrorGroup(); |  317       errorGroup = new ErrorGroup(); | 
|  282       controller = new StreamController(sync: true); |  318       controller = new StreamController(sync: true); | 
|  283       stream = errorGroup.registerStream(controller.stream); |  319       stream = errorGroup.registerStream(controller.stream); | 
|  284     }); |  320     }); | 
|  285  |  321  | 
|  286     test("should complete .done when the stream is done even if the stream " |  322     test( | 
|  287         "doesn't have a listener", () { |  323         "should complete .done when the stream is done even if the stream " | 
 |  324             "doesn't have a listener", | 
 |  325         () { | 
|  288       expect(errorGroup.done, completes); |  326       expect(errorGroup.done, completes); | 
|  289       controller.add('value'); |  327       controller.add('value'); | 
|  290       controller.close(); |  328       controller.close(); | 
|  291  |  329  | 
|  292       // A listener added afterwards should receive the value |  330       // A listener added afterwards should receive the value | 
|  293       expect(errorGroup.done.then((_) => stream.toList()), |  331       expect( | 
 |  332           errorGroup.done.then((_) => stream.toList()), | 
|  294           completion(equals(['value']))); |  333           completion(equals(['value']))); | 
|  295     }); |  334     }); | 
|  296  |  335  | 
|  297     test("should pipe an exception from the stream to .done if the stream " |  336     test( | 
|  298         "doesn't have a listener", () { |  337         "should pipe an exception from the stream to .done if the stream " | 
 |  338             "doesn't have a listener", | 
 |  339         () { | 
|  299       expect(errorGroup.done, throwsFormatException); |  340       expect(errorGroup.done, throwsFormatException); | 
|  300       controller.addError(new FormatException()); |  341       controller.addError(new FormatException()); | 
|  301  |  342  | 
|  302       // A listener added afterwards should receive the exception |  343       // A listener added afterwards should receive the exception | 
|  303       expect(errorGroup.done.catchError((_) { |  344       expect(errorGroup.done.catchError((_) { | 
|  304         controller.add('value'); // should be ignored |  345         controller.add('value'); // should be ignored | 
|  305         expect(stream.first, throwsFormatException); |  346         expect(stream.first, throwsFormatException); | 
|  306       }), completes); |  347       }), completes); | 
|  307     }); |  348     }); | 
|  308  |  349  | 
|  309     test("should pass a signaled exception to .done if the stream doesn't " |  350     test( | 
|  310         "have a listener", |  351         "should pass a signaled exception to .done if the stream doesn't " | 
 |  352             "have a listener", | 
|  311         () { |  353         () { | 
|  312       expect(errorGroup.done, throwsFormatException); |  354       expect(errorGroup.done, throwsFormatException); | 
|  313       errorGroup.signalError(new FormatException()); |  355       errorGroup.signalError(new FormatException()); | 
|  314  |  356  | 
|  315       // A listener added afterwards should receive the exception |  357       // A listener added afterwards should receive the exception | 
|  316       expect(errorGroup.done.catchError((_) { |  358       expect(errorGroup.done.catchError((_) { | 
|  317         controller.add('value'); // should be ignored |  359         controller.add('value'); // should be ignored | 
|  318         expect(stream.first, throwsFormatException); |  360         expect(stream.first, throwsFormatException); | 
|  319       }), completes); |  361       }), completes); | 
|  320     }); |  362     }); | 
|  321   }); |  363   }); | 
|  322  |  364  | 
|  323   group('with multiple streams', () { |  365   group('with multiple streams', () { | 
|  324     StreamController controller1; |  366     StreamController controller1; | 
|  325     StreamController controller2; |  367     StreamController controller2; | 
|  326     Stream stream1; |  368     Stream stream1; | 
|  327     Stream stream2; |  369     Stream stream2; | 
|  328  |  370  | 
|  329     setUp(() { |  371     setUp(() { | 
|  330       errorGroup = new ErrorGroup(); |  372       errorGroup = new ErrorGroup(); | 
|  331       controller1 = new StreamController.broadcast(sync: true); |  373       controller1 = new StreamController.broadcast(sync: true); | 
|  332       controller2 = new StreamController.broadcast(sync: true); |  374       controller2 = new StreamController.broadcast(sync: true); | 
|  333       stream1 = errorGroup.registerStream(controller1.stream); |  375       stream1 = errorGroup.registerStream(controller1.stream); | 
|  334       stream2 = errorGroup.registerStream(controller2.stream); |  376       stream2 = errorGroup.registerStream(controller2.stream); | 
|  335     }); |  377     }); | 
|  336  |  378  | 
|  337     test("should pipe exceptions from one stream to the other and to .done", |  379     test( | 
 |  380         "should pipe exceptions from one stream to the other and to .done", | 
|  338         () { |  381         () { | 
|  339       expect(stream1.first, throwsFormatException); |  382       expect(stream1.first, throwsFormatException); | 
|  340       expect(stream2.first, throwsFormatException); |  383       expect(stream2.first, throwsFormatException); | 
|  341       expect(errorGroup.done, throwsFormatException); |  384       expect(errorGroup.done, throwsFormatException); | 
|  342  |  385  | 
|  343       controller1.addError(new FormatException()); |  386       controller1.addError(new FormatException()); | 
|  344     }); |  387     }); | 
|  345  |  388  | 
|  346     test("each future should be able to emit values independently", () { |  389     test("each future should be able to emit values independently", () { | 
|  347       expect(stream1.toList(), completion(equals(['value1.1', 'value1.2']))); |  390       expect(stream1.toList(), completion(equals(['value1.1', 'value1.2']))); | 
|  348       expect(stream2.toList(), completion(equals(['value2.1', 'value2.2']))); |  391       expect(stream2.toList(), completion(equals(['value2.1', 'value2.2']))); | 
|  349       expect(errorGroup.done, completes); |  392       expect(errorGroup.done, completes); | 
|  350  |  393  | 
|  351       controller1..add('value1.1')..add('value1.2')..close(); |  394       controller1 | 
|  352       controller2..add('value2.1')..add('value2.2')..close(); |  395           ..add('value1.1') | 
 |  396           ..add('value1.2') | 
 |  397           ..close(); | 
 |  398       controller2 | 
 |  399           ..add('value2.1') | 
 |  400           ..add('value2.2') | 
 |  401           ..close(); | 
|  353     }); |  402     }); | 
|  354  |  403  | 
|  355     test("shouldn't throw a top-level exception if a stream receives an error " |  404     test( | 
|  356         "after the other listened stream completes", () { |  405         "shouldn't throw a top-level exception if a stream receives an error " | 
 |  406             "after the other listened stream completes", | 
 |  407         () { | 
|  357       var signal = new Completer(); |  408       var signal = new Completer(); | 
|  358       expect(stream1.toList().whenComplete(signal.complete), |  409       expect( | 
|  359              completion(equals(['value1', 'value2']))); |  410           stream1.toList().whenComplete(signal.complete), | 
|  360       controller1..add('value1')..add('value2')..close(); |  411           completion(equals(['value1', 'value2']))); | 
 |  412       controller1 | 
 |  413           ..add('value1') | 
 |  414           ..add('value2') | 
 |  415           ..close(); | 
|  361  |  416  | 
|  362       expect(signal.future.then((_) { |  417       expect(signal.future.then((_) { | 
|  363         // shouldn't cause a top-level exception |  418         // shouldn't cause a top-level exception | 
|  364         controller2.addError(new FormatException()); |  419         controller2.addError(new FormatException()); | 
|  365       }), completes); |  420       }), completes); | 
|  366     }); |  421     }); | 
|  367  |  422  | 
|  368     test("shouldn't throw a top-level exception if an error is signaled after " |  423     test( | 
|  369         "one listened stream completes", () { |  424         "shouldn't throw a top-level exception if an error is signaled after " | 
 |  425             "one listened stream completes", | 
 |  426         () { | 
|  370       var signal = new Completer(); |  427       var signal = new Completer(); | 
|  371       expect(stream1.toList().whenComplete(signal.complete), |  428       expect( | 
|  372              completion(equals(['value1', 'value2']))); |  429           stream1.toList().whenComplete(signal.complete), | 
|  373       controller1..add('value1')..add('value2')..close(); |  430           completion(equals(['value1', 'value2']))); | 
 |  431       controller1 | 
 |  432           ..add('value1') | 
 |  433           ..add('value2') | 
 |  434           ..close(); | 
|  374  |  435  | 
|  375       expect(signal.future.then((_) { |  436       expect(signal.future.then((_) { | 
|  376         // shouldn't cause a top-level exception |  437         // shouldn't cause a top-level exception | 
|  377         errorGroup.signalError(new FormatException()); |  438         errorGroup.signalError(new FormatException()); | 
|  378       }), completes); |  439       }), completes); | 
|  379     }); |  440     }); | 
|  380   }); |  441   }); | 
|  381  |  442  | 
|  382   group('with a stream and a future', () { |  443   group('with a stream and a future', () { | 
|  383     StreamController controller; |  444     StreamController controller; | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
|  402     }); |  463     }); | 
|  403  |  464  | 
|  404     test("should pipe exceptions from the future to the stream", () { |  465     test("should pipe exceptions from the future to the stream", () { | 
|  405       expect(stream.first, throwsFormatException); |  466       expect(stream.first, throwsFormatException); | 
|  406       expect(future, throwsFormatException); |  467       expect(future, throwsFormatException); | 
|  407       expect(errorGroup.done, throwsFormatException); |  468       expect(errorGroup.done, throwsFormatException); | 
|  408  |  469  | 
|  409       completer.completeError(new FormatException()); |  470       completer.completeError(new FormatException()); | 
|  410     }); |  471     }); | 
|  411  |  472  | 
|  412     test("the stream and the future should be able to complete/emit values " |  473     test( | 
|  413         "independently", () { |  474         "the stream and the future should be able to complete/emit values " | 
 |  475             "independently", | 
 |  476         () { | 
|  414       expect(stream.toList(), completion(equals(['value1.1', 'value1.2']))); |  477       expect(stream.toList(), completion(equals(['value1.1', 'value1.2']))); | 
|  415       expect(future, completion(equals('value2.0'))); |  478       expect(future, completion(equals('value2.0'))); | 
|  416       expect(errorGroup.done, completes); |  479       expect(errorGroup.done, completes); | 
|  417  |  480  | 
|  418       controller..add('value1.1')..add('value1.2')..close(); |  481       controller | 
 |  482           ..add('value1.1') | 
 |  483           ..add('value1.2') | 
 |  484           ..close(); | 
|  419       completer.complete('value2.0'); |  485       completer.complete('value2.0'); | 
|  420     }); |  486     }); | 
|  421  |  487  | 
|  422     test("shouldn't throw a top-level exception if the stream receives an error 
     " |  488     test( | 
|  423         "after the listened future completes", () { |  489         "shouldn't throw a top-level exception if the stream receives an error " | 
 |  490             "after the listened future completes", | 
 |  491         () { | 
|  424       expect(future, completion(equals('value'))); |  492       expect(future, completion(equals('value'))); | 
|  425       completer.complete('value'); |  493       completer.complete('value'); | 
|  426  |  494  | 
|  427       expect(future.then((_) { |  495       expect(future.then((_) { | 
|  428         // shouldn't cause a top-level exception |  496         // shouldn't cause a top-level exception | 
|  429         controller.addError(new FormatException()); |  497         controller.addError(new FormatException()); | 
|  430       }), completes); |  498       }), completes); | 
|  431     }); |  499     }); | 
|  432  |  500  | 
|  433     test("shouldn't throw a top-level exception if the future receives an " |  501     test( | 
|  434         "error after the listened stream completes", () { |  502         "shouldn't throw a top-level exception if the future receives an " | 
 |  503             "error after the listened stream completes", | 
 |  504         () { | 
|  435       var signal = new Completer(); |  505       var signal = new Completer(); | 
|  436       expect(stream.toList().whenComplete(signal.complete), |  506       expect( | 
|  437              completion(equals(['value1', 'value2']))); |  507           stream.toList().whenComplete(signal.complete), | 
|  438       controller..add('value1')..add('value2')..close(); |  508           completion(equals(['value1', 'value2']))); | 
 |  509       controller | 
 |  510           ..add('value1') | 
 |  511           ..add('value2') | 
 |  512           ..close(); | 
|  439  |  513  | 
|  440       expect(signal.future.then((_) { |  514       expect(signal.future.then((_) { | 
|  441         // shouldn't cause a top-level exception |  515         // shouldn't cause a top-level exception | 
|  442         completer.completeError(new FormatException()); |  516         completer.completeError(new FormatException()); | 
|  443       }), completes); |  517       }), completes); | 
|  444     }); |  518     }); | 
|  445   }); |  519   }); | 
|  446 } |  520 } | 
| OLD | NEW |