| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 async_start_test; | 5 library async_start_test; |
| 6 | 6 |
| 7 import "package:unittest/unittest.dart"; | 7 import "package:unittest/unittest.dart"; |
| 8 import "dart:async"; | 8 import "dart:async"; |
| 9 | 9 |
| 10 main() { | 10 main() { |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 return expectList(f(), [0, 1, 2]); | 136 return expectList(f(), [0, 1, 2]); |
| 137 }); | 137 }); |
| 138 | 138 |
| 139 test("labeled", () { | 139 test("labeled", () { |
| 140 f() async* { | 140 f() async* { |
| 141 label1: yield 0; | 141 label1: yield 0; |
| 142 } | 142 } |
| 143 return expectList(f(), [0]); | 143 return expectList(f(), [0]); |
| 144 }); | 144 }); |
| 145 | 145 |
| 146 // VM issue 2238 | |
| 147 test("labeled 2", () { /// 01: ok | |
| 148 f() async* { /// 01: continued | |
| 149 label1: label2: yield 0; /// 01: continued | |
| 150 } /// 01: continued | |
| 151 return expectList(f(), [0]); /// 01: continued | |
| 152 }); /// 01: continued | |
| 153 | |
| 154 test("for-loop", () { | 146 test("for-loop", () { |
| 155 f() async* { | 147 f() async* { |
| 156 for (int i = 0; i < 3; i++) yield i; | 148 for (int i = 0; i < 3; i++) yield i; |
| 157 } | 149 } |
| 158 return expectList(f(), [0, 1, 2]); | 150 return expectList(f(), [0, 1, 2]); |
| 159 }); | 151 }); |
| 160 | 152 |
| 161 test("for-in-loop", () { | 153 test("for-in-loop", () { |
| 162 f() async* { | 154 f() async* { |
| 163 for (var i in [0, 1, 2]) yield i; | 155 for (var i in [0, 1, 2]) yield i; |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 test("before end", () { | 568 test("before end", () { |
| 577 return expectList(f().take(2), [1, 2]); | 569 return expectList(f().take(2), [1, 2]); |
| 578 }); | 570 }); |
| 579 test("early", () { | 571 test("early", () { |
| 580 return expectList(f().take(1), [1]); | 572 return expectList(f().take(1), [1]); |
| 581 }); | 573 }); |
| 582 test("at start", () { | 574 test("at start", () { |
| 583 return expectList(f().take(0), []); | 575 return expectList(f().take(0), []); |
| 584 }); | 576 }); |
| 585 }); | 577 }); |
| 586 | |
| 587 // Crashes dart2js. | |
| 588 // test("regression-fugl/fisk", () { | |
| 589 // var res = []; | |
| 590 // fisk() async* { | |
| 591 // res.add("+fisk"); | |
| 592 // try { | |
| 593 // for (int i = 0; i < 2; i++) { | |
| 594 // yield await new Future.microtask(() => i); | |
| 595 // } | |
| 596 // } finally { | |
| 597 // res.add("-fisk"); | |
| 598 // } | |
| 599 // } | |
| 600 | |
| 601 // fugl(int count) async { | |
| 602 // res.add("fisk $count"); | |
| 603 // try { | |
| 604 // await for(int i in fisk().take(count)) res.add(i); | |
| 605 // } finally { | |
| 606 // res.add("done"); | |
| 607 // } | |
| 608 // } | |
| 609 | |
| 610 // return fugl(3).whenComplete(() => fugl(2)) | |
| 611 // .whenComplete(() => fugl(1)) | |
| 612 // .whenComplete(() { | |
| 613 // expect(res, ["fisk 3", "+fisk", 0, 1, "-fisk", "done", | |
| 614 // "fisk 2", "+fisk", 0, 1, "-fisk", "done", | |
| 615 // "fisk 1", "+fisk", 0, "done", "-fisk", ]); | |
| 616 // }); | |
| 617 // }); | |
| 618 | |
| 619 }); | 578 }); |
| 620 | 579 |
| 621 group("pausing", () { | 580 group("pausing", () { |
| 622 test("pauses execution at yield for at least a microtask", () { | 581 test("pauses execution at yield for at least a microtask", () { |
| 623 var list = []; | 582 var list = []; |
| 624 f() async* { | 583 f() async* { |
| 625 list.add(1); | 584 list.add(1); |
| 626 yield 2; | 585 yield 2; |
| 627 list.add(3); | 586 list.add(3); |
| 628 yield 4; | 587 yield 4; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 696 sub.cancel(); | 655 sub.cancel(); |
| 697 done.complete(); | 656 done.complete(); |
| 698 } | 657 } |
| 699 }, onDone: () { | 658 }, onDone: () { |
| 700 fail("Unexpected done!"); | 659 fail("Unexpected done!"); |
| 701 }); | 660 }); |
| 702 return done.future.whenComplete(() { | 661 return done.future.whenComplete(() { |
| 703 expect(list.length == 18 || list.length == 19, isTrue); | 662 expect(list.length == 18 || list.length == 19, isTrue); |
| 704 }); | 663 }); |
| 705 }); | 664 }); |
| 706 | |
| 707 test("canceling while paused at yield", () { /// 02: ok | |
| 708 var list = []; /// 02: contin
ued | |
| 709 var sync = new Sync(); /// 02: contin
ued | |
| 710 f() async* { /// 02: contin
ued | |
| 711 list.add("*1"); /// 02: contin
ued | |
| 712 yield 1; /// 02: contin
ued | |
| 713 await sync.wait(); /// 02: contin
ued | |
| 714 sync.release(); /// 02: contin
ued | |
| 715 list.add("*2"); /// 02: contin
ued | |
| 716 yield 2; /// 02: contin
ued | |
| 717 list.add("*3"); /// 02: contin
ued | |
| 718 }; /// 02: contin
ued | |
| 719 var stream = f(); /// 02: contin
ued | |
| 720 var sub = stream.listen(list.add); /// 02: contin
ued | |
| 721 return sync.wait().whenComplete(() { /// 02: contin
ued | |
| 722 expect(list, equals(["*1", 1])); /// 02: contin
ued | |
| 723 sub.pause(); /// 02: contin
ued | |
| 724 return sync.wait(); /// 02: contin
ued | |
| 725 }).whenComplete(() { /// 02: contin
ued | |
| 726 expect(list, equals(["*1", 1, "*2"])); /// 02: contin
ued | |
| 727 sub.cancel(); /// 02: contin
ued | |
| 728 return new Future.delayed(MS * 200, () { /// 02: contin
ued | |
| 729 // Should not have yielded 2 or added *3 while paused. /// 02: contin
ued | |
| 730 expect(list, equals(["*1", 1, "*2"])); /// 02: contin
ued | |
| 731 }); /// 02: contin
ued | |
| 732 }); /// 02: contin
ued | |
| 733 }); /// 02: contin
ued | |
| 734 }); | 665 }); |
| 735 | 666 |
| 736 group("await for", () { | 667 group("await for", () { |
| 737 mkStream(int n) async* { | 668 mkStream(int n) async* { |
| 738 for (int i = 0; i < n; i++) yield i; | 669 for (int i = 0; i < n; i++) yield i; |
| 739 } | 670 } |
| 740 | 671 |
| 741 test("simple stream", () { | 672 test("simple stream", () { |
| 742 f(s) async { | 673 f(s) async { |
| 743 var r = 0; | 674 var r = 0; |
| 744 await for(var v in s) r += v; | 675 await for(var v in s) r += v; |
| 745 return r; | 676 return r; |
| 746 } | 677 } |
| 747 return f(mkStream(5)).then((v) { | 678 return f(mkStream(5)).then((v) { |
| 748 expect(v, equals(10)); | 679 expect(v, equals(10)); |
| 749 }); | 680 }); |
| 750 }); | 681 }); |
| 751 | 682 |
| 752 test("simple stream, await", () { | 683 test("simple stream, await", () { |
| 753 f(s) async { | 684 f(s) async { |
| 754 var r = 0; | 685 var r = 0; |
| 755 await for(var v in s) r += await new Future.microtask(() => v); | 686 await for(var v in s) r += await new Future.microtask(() => v); |
| 756 return r; | 687 return r; |
| 757 } | 688 } |
| 758 return f(mkStream(5)).then((v) { | 689 return f(mkStream(5)).then((v) { |
| 759 expect(v, equals(10)); | 690 expect(v, equals(10)); |
| 760 }); | 691 }); |
| 761 }); | 692 }); |
| 762 | 693 |
| 763 test("simple stream - take", () { /// 03: ok | |
| 764 f(s) async { /// 03: continued | |
| 765 var r = 0; /// 03: continued | |
| 766 await for(var v in s.take(5)) r += v; /// 03: continued | |
| 767 return r; /// 03: continued | |
| 768 } /// 03: continued | |
| 769 return f(mkStream(10)).then((v) { /// 03: continued | |
| 770 expect(v, equals(10)); /// 03: continued | |
| 771 }); /// 03: continued | |
| 772 }); /// 03: continued | |
| 773 | |
| 774 test("simple stream reyield", () { | 694 test("simple stream reyield", () { |
| 775 f(s) async* { | 695 f(s) async* { |
| 776 var r = 0; | 696 var r = 0; |
| 777 await for(var v in s) yield r += v; | 697 await for(var v in s) yield r += v; |
| 778 } | 698 } |
| 779 return expectList(f(mkStream(5)), [0, 1, 3, 6, 10]); | 699 return expectList(f(mkStream(5)), [0, 1, 3, 6, 10]); |
| 780 }); | 700 }); |
| 781 | 701 |
| 782 test("simple stream, await, reyield", () { | 702 test("simple stream, await, reyield", () { |
| 783 f(s) async* { | 703 f(s) async* { |
| 784 var r = 0; | 704 var r = 0; |
| 785 await for(var v in s) yield r += await new Future.microtask(() => v); | 705 await for(var v in s) yield r += await new Future.microtask(() => v); |
| 786 } | 706 } |
| 787 return expectList(f(mkStream(5)), [0, 1, 3, 6, 10]); | 707 return expectList(f(mkStream(5)), [0, 1, 3, 6, 10]); |
| 788 }); | 708 }); |
| 789 | 709 |
| 790 test("simple stream - take, reyield", () { /// 04: ok | |
| 791 f(s) async* { /// 04: continued | |
| 792 var r = 0; /// 04: continued | |
| 793 await for(var v in s.take(5)) yield r += v; /// 04: continued | |
| 794 } /// 04: continued | |
| 795 return expectList(f(mkStream(10)), [0, 1, 3, 6, 10]); /// 04: continued | |
| 796 }); /// 04: continued | |
| 797 | |
| 798 test("nested", () { | 710 test("nested", () { |
| 799 f() async { | 711 f() async { |
| 800 var r = 0; | 712 var r = 0; |
| 801 await for (var i in mkStream(5)) { | 713 await for (var i in mkStream(5)) { |
| 802 await for (var j in mkStream(3)) { | 714 await for (var j in mkStream(3)) { |
| 803 r += i * j; | 715 r += i * j; |
| 804 } | 716 } |
| 805 } | 717 } |
| 806 return r; | 718 return r; |
| 807 } | 719 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 833 await for (var j in mkStream(3)) { | 745 await for (var j in mkStream(3)) { |
| 834 r += await new Future.microtask(() => ai * j); | 746 r += await new Future.microtask(() => ai * j); |
| 835 } | 747 } |
| 836 } | 748 } |
| 837 return r; | 749 return r; |
| 838 } | 750 } |
| 839 return f().then((v) { | 751 return f().then((v) { |
| 840 expect(v, equals((1 + 2 + 3 + 4) * (1 + 2))); | 752 expect(v, equals((1 + 2 + 3 + 4) * (1 + 2))); |
| 841 }); | 753 }); |
| 842 }); | 754 }); |
| 843 | |
| 844 test("await pauses loop", () { /// 05: ok | |
| 845 var sc; /// 05: con
tinued | |
| 846 var i = 0; /// 05: con
tinued | |
| 847 void send() { /// 05: con
tinued | |
| 848 if (i == 5) { /// 05: con
tinued | |
| 849 sc.close(); /// 05: con
tinued | |
| 850 } else { /// 05: con
tinued | |
| 851 sc.add(i++); /// 05: con
tinued | |
| 852 } /// 05: con
tinued | |
| 853 } /// 05: con
tinued | |
| 854 sc = new StreamController(onListen: send, onResume: send); /// 05: con
tinued | |
| 855 f(s) async { /// 05: con
tinued | |
| 856 var r = 0; /// 05: con
tinued | |
| 857 await for (var i in s) { /// 05: con
tinued | |
| 858 r += await new Future.delayed(MS * 10, () => i); /// 05: con
tinued | |
| 859 } /// 05: con
tinued | |
| 860 return r; /// 05: con
tinued | |
| 861 } /// 05: con
tinued | |
| 862 return f(sc.stream).then((v) { /// 05: con
tinued | |
| 863 expect(v, equals(10)); /// 05: con
tinued | |
| 864 }); /// 05: con
tinued | |
| 865 }); /// 05: con
tinued | |
| 866 }); | 755 }); |
| 867 } | 756 } |
| 868 | 757 |
| 869 // Obscuring identity function. | 758 // Obscuring identity function. |
| 870 id(x) { | 759 id(x) { |
| 871 try { | 760 try { |
| 872 if (x != null) throw x; | 761 if (x != null) throw x; |
| 873 } catch (e) { | 762 } catch (e) { |
| 874 return e; | 763 return e; |
| 875 } | 764 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 887 var getErrors = new StreamTransformer.fromHandlers( | 776 var getErrors = new StreamTransformer.fromHandlers( |
| 888 handleData:(data, sink) { fail("Unexpected value"); }, | 777 handleData:(data, sink) { fail("Unexpected value"); }, |
| 889 handleError: (e, s, sink) { sink.add(e); }, | 778 handleError: (e, s, sink) { sink.add(e); }, |
| 890 handleDone: (sink) { sink.close(); }); | 779 handleDone: (sink) { sink.close(); }); |
| 891 | 780 |
| 892 class NotAStream { | 781 class NotAStream { |
| 893 listen(oData, {onError, onDone, cancelOnError}) { | 782 listen(oData, {onError, onDone, cancelOnError}) { |
| 894 fail("Not implementing Stream."); | 783 fail("Not implementing Stream."); |
| 895 } | 784 } |
| 896 } | 785 } |
| 897 | |
| 898 /** | |
| 899 * Allows two asynchronous executions to synchronize. | |
| 900 * | |
| 901 * Calling [wait] and waiting for the returned future to complete will | |
| 902 * wait for the other executions to call [wait] again. At that point, | |
| 903 * the waiting execution is allowed to continue (the returned future completes), | |
| 904 * and the more resent call to [wait] is now the waiting execution. | |
| 905 */ | |
| 906 class Sync { | |
| 907 Completer _completer = null; | |
| 908 // Release whoever is currently waiting and start waiting yourself. | |
| 909 Future wait([v]) { | |
| 910 if (_completer != null) _completer.complete(v); | |
| 911 _completer = new Completer(); | |
| 912 return _completer.future; | |
| 913 } | |
| 914 | |
| 915 // Release whoever is currently waiting. | |
| 916 void release([v]) { | |
| 917 if (_completer != null) { | |
| 918 _completer.complete(v); | |
| 919 _completer = null; | |
| 920 } | |
| 921 } | |
| 922 } | |
| OLD | NEW |