Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 } | |
| OLD | NEW |