Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: test/stream_transformers_test.dart

Issue 1648963002: Add reactive-inspired stream transformers: Base URL: https://github.com/dart-lang/async@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
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.
4
5 // Test stream transformers.
6 import "dart:async";
7
8 import "package:async/async.dart";
9 import "package:test/test.dart";
10
11 var strings = const [
nweiz 2016/01/29 22:19:45 I find it a lot easier to read tests when they inc
Lasse Reichstein Nielsen 2016/02/25 16:18:10 Done.
12 "a",
13 "ab",
14 "b",
15 "abel",
16 "abe",
17 "bell",
18 "able",
19 "abba",
20 "lea"
21 ];
22
23 Stream<String> get stringStream async* {
24 for (var string in strings) {
25 yield string;
26 }
27 }
28
29 Stream get emptyStream async* {}
30
31 Stream repeatStream(int count, value) async* {
32 for (var i = 0; i < count; i++) {
33 yield value;
34 }
35 }
36
37 // Just some valid stack trace.
38 var stack = StackTrace.current;
nweiz 2016/01/29 22:19:45 It would be nice to avoid the tests depending on 1
Lasse Reichstein Nielsen 2016/02/25 16:18:11 I believe 1.14 has a stable release now.
39
40 Stream<String> stringErrorStream(int errorAfter) async* {
41 for (int i = 0; i < strings.length; i++) {
42 yield strings[i];
43 if (i == errorAfter) {
44 // Emit error, but continue afterwards.
45 yield* new Future.error("BAD", stack).asStream();
46 }
47 }
48 }
49
50 Stream intStream(int count, [int start = 0]) async* {
51 for (int i = 0; i < count; i++) {
52 yield start++;
53 }
54 }
55
56 Stream timerStream(int count, Duration interval) async* {
57 for (int i = 0; i < count; i++) {
58 await new Future.delayed(interval);
59 yield i;
60 }
61 }
62
63 void main() {
64 group("groupBy", () {
nweiz 2016/01/29 22:19:45 Test the value() function as well. Test what happe
Lasse Reichstein Nielsen 2016/02/25 16:18:10 Done.
65 test("splits", () async {
66 var grouped =
67 stringStream.transform(new GroupBy<int, String>((x) => x.length));
68 var byLength = {};
69 await for (Group<int,String> group in grouped) {
70 byLength[group.key] = group.values.toList();
71 }
72 expect(byLength.keys.toList(), [1, 2, 4, 3]);
73 expect(byLength[1], completion(["a", "b"]));
74 expect(byLength[2], completion(["ab"]));
75 expect(byLength[3], completion(["abe", "lea"]));
76 expect(byLength[4], completion(["abel", "bell", "able", "abba"]));
77 });
78
79 test("empty", () async {
floitsch 2016/01/29 19:05:03 group + test should give a sentence.
Lasse Reichstein Nielsen 2016/02/25 16:18:11 No groups any longer.
80 var grouped =
81 emptyStream.transform(new GroupBy<int, String>((x) => x.length));
82 var byLength = {};
83 await for (Group<int,String> group in grouped) {
nweiz 2016/01/29 22:19:45 It would be cleaner to just write expect(grouped.t
Lasse Reichstein Nielsen 2016/02/25 16:18:11 Done.
84 byLength[group.key] = group.values.toList();
85 }
86 expect(byLength, isEmpty);
87 });
88
89 test("single group", () async {
90 var grouped =
91 repeatStream(5, "x").transform(new GroupBy<int, String>((x) => x.length ));
floitsch 2016/01/29 19:05:03 long line.
Lasse Reichstein Nielsen 2016/02/25 16:18:10 Done.
92 var byLength = {};
93 await for (Group<int,String> group in grouped) {
94 byLength[group.key] = group.values.toList();
95 }
96 expect(byLength.keys, [1]);
97 expect(byLength[1], completion(["x", "x", "x", "x", "x"]));
98 });
99
100 test("with error", () async {
101 var grouped = stringErrorStream(3).
102 transform(new GroupBy<int, String>((x) => x.length));
103 var byLength = {};
104 bool caught = false;
105 try {
106 await for (Group<int,String> group in grouped) {
107 byLength[group.key] = group.values.toList();
108 }
109 } catch (e) {
110 expect(e, "BAD");
111 caught = true;
112 }
nweiz 2016/01/29 22:19:45 It seems strange, for this and other transformers,
Lasse Reichstein Nielsen 2016/02/01 12:43:21 It is a problem that our async*/await for primitiv
nweiz 2016/02/02 02:29:13 I'm pretty skeptical of this. There are still plen
Lasse Reichstein Nielsen 2016/02/25 16:18:10 Reasonable. I'll try rewriting it to accept errors
113 expect(caught, isTrue);
114 expect(byLength.keys.toList(), [1, 2, 4]);
115 expect(byLength[1], completion(["a", "b"]));
116 expect(byLength[2], completion(["ab"]));
117 expect(byLength[4], completion(["abel"]));
118 });
119 });
120
121 group("Scan", () {
122 test("adds", () {
123 var scanned = intStream(5, 2)
124 .transform(new Scan<int, int>(0, (a, v) => a + v));
125 expect(scanned.toList(), completion([2, 5, 9, 14, 20]));
126 });
127 test("subtracts", () {
128 // This will not work if parameters are swapped.
129 var scanned = intStream(5, 2)
130 .transform(new Scan<int, int>(0, (a, v) => a - v));
131 expect(scanned.toList(), completion([-2, -5, -9, -14, -20]));
132 });
133 test("types", () {
134 var scanned = intStream(5, 2)
135 .transform(new Scan<int, String>("", (a, v) => "$a$v"));
136 expect(scanned.toList(), completion(["2", "23", "234", "2345", "23456"]));
137 });
138 test("types 2", () {
139 var scan = new Scan<int, String>("", (a, v) => "$a$v");
140 var scanned = scan.bind(intStream(5, 2));
141 expect(scanned is Stream<String>, isTrue);
142 expect(scanned.toList(), completion(["2", "23", "234", "2345", "23456"]));
143 });
144 test("error", () async {
145 var calls = 0;
146 var scanned = stringErrorStream(3)
147 .transform(new Scan<String, int>(0, (a, b) => ++calls));
148 Future list = scanned.toList();
149 Future listDone = list.catchError((_) => calls);
150 expect(list, throwsA("BAD"));
151 expect(listDone, completion(4));
152 });
153 });
154
nweiz 2016/01/29 22:19:45 Extra newline.
Lasse Reichstein Nielsen 2016/02/25 16:18:11 Rewritten.
155
156 const ms = const Duration(milliseconds: 1);
nweiz 2016/01/29 22:19:46 Making this a method-level const declaration reads
Lasse Reichstein Nielsen 2016/02/01 12:43:20 Is it because it's const, because it could just as
nweiz 2016/02/02 02:29:13 Const makes it weirder, but it would still look we
157
158 group("unbounce", () {
nweiz 2016/01/29 22:19:45 This and throttle need more tests. They should tes
Lasse Reichstein Nielsen 2016/02/01 12:43:20 The clock and fake_async packages require you to u
nweiz 2016/02/02 02:29:13 I suppose ideally the Zone API would mock them out
Lasse Reichstein Nielsen 2016/02/25 16:18:10 Ideally you could replace the core library with so
159 test("keeps restarting timer", () async {
160 var debounced = timerStream(18, ms * 10)
161 .transform(new Debounce<int>(ms * 100));
162 expect(debounced.length, completion(1));
163 });
164 });
165
166 group("throttle", () {
167 // Very hard to test safely because events may be delayed.
168 test("keeps restarting timer", () async {
169 var throttled = timerStream(16, ms * 10)
170 .transform(new Throttle<int>(ms * 50));
171 var length = throttled.length;
172 expect(length, completion(lessThan(6)));
173 expect(length, completion(greaterThan(1)));
174 });
175 });
176
177 group("merge", () {
178 test("none", () async {
179 var stream = mergeStreams([]);
180 int count = 0;
181 await for (var event in stream) {
182 count++;
183 }
184 expect(count, 0);
185 });
186
187 test("single", () async {
188 var stream = mergeStreams([intStream(5)]);
189 expect(stream.toList(), completion([0, 1, 2, 3, 4]));
190 });
191
192 test("multiple", () async {
193 var stream = mergeStreams([intStream(5), stringStream]);
194 var events = await stream.toList();
195 expect(events.where((x) => x is int), [0, 1, 2, 3, 4]);
196 expect(events.where((x) => x is String), strings);
197 expect(events.where((x) => x is! int && x is! String), isEmpty);
198 });
199
200 test("error", () async {
201 var stream = mergeStreams([stringErrorStream(3), intStream(6)]);
202 var events = await Result.captureStream(stream).toList();
203 expect(events.where((Result x) => x.isValue && x.asValue.value is int)
204 .map((ValueResult x) => x.value),
205 [0, 1, 2, 3, 4, 5]);
206 expect(events.where((x) => x.isError || x.asValue.value is! int),
207 [new Result.value("a"),
208 new Result.value("ab"),
209 new Result.value("b"),
210 new Result.value("abel"),
211 new Result.error("BAD", stack),
212 new Result.value("abe"),
213 new Result.value("bell"),
214 new Result.value("able"),
215 new Result.value("abba"),
216 new Result.value("lea"),
217 ]);
218 });
219 });
220 }
OLDNEW
« lib/src/stream_transformers.dart ('K') | « lib/src/stream_transformers.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698