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

Side by Side Diff: pkg/scheduled_test/lib/src/stream_matcher.dart

Issue 196063004: Move dart2js entrypoint detection into isPrimary. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: use dart2js error messages Created 6 years, 9 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 | Annotate | Revision Log
OLDNEW
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 scheduled_test.stream_matcher; 5 library scheduled_test.stream_matcher;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import '../scheduled_stream.dart'; 10 import '../scheduled_stream.dart';
11 import '../scheduled_test.dart'; 11 import '../scheduled_test.dart';
12 import 'utils.dart'; 12 import 'utils.dart';
13 13
14 /// An abstract superclass for matchers that validate and consume zero or more 14 /// An abstract superclass for matchers that validate and consume zero or more
15 /// values emitted by a [ScheduledStream]. 15 /// values emitted by a [ScheduledStream].
16 /// 16 ///
17 /// [StreamMatcher]s are most commonly used by passing them to 17 /// [StreamMatcher]s are most commonly used by passing them to
18 /// [ScheduledStream.expect]. 18 /// [ScheduledStream.expect].
19 abstract class StreamMatcher { 19 abstract class StreamMatcher {
20 /// Wrap a [Matcher], [StreamMatcher] or [Object] in a [StreamMatcher]. 20 /// Wrap a [Matcher], [StreamMatcher] or [Object] in a [StreamMatcher].
21 /// 21 ///
22 /// If this isn't a [StreamMatcher], a [nextValue] matcher is used. 22 /// If this isn't a [StreamMatcher], a [nextValue] matcher is used.
23 factory StreamMatcher.wrap(matcher) => 23 factory StreamMatcher.wrap(matcher) =>
24 matcher is StreamMatcher ? matcher : nextValue(matcher); 24 matcher is StreamMatcher ? matcher : nextValue(matcher);
25 25
26 StreamMatcher();
Bob Nystrom 2014/03/12 21:12:25 Is this needed?
nweiz 2014/03/12 21:49:06 Since the matchers now extend rather than implemen
27
26 /// Tries to match [this] against [stream]. 28 /// Tries to match [this] against [stream].
27 /// 29 ///
28 /// If the match succeeds, this returns `null`. If it fails, this returns a 30 /// If the match succeeds, this returns `null`. If it fails, this returns a
29 /// [Description] describing the failure. 31 /// [Description] describing the failure.
30 Future<Description> tryMatch(ScheduledStream stream); 32 Future<Description> tryMatch(ScheduledStream stream);
31 33
34 /// Returns whether [this] would match [stream] without actually consuming
35 /// values from [stream].
36 ///
37 /// If the match succeeds, this returns `null`. If it fails, this returns a
38 /// [Description] describing the failure.
39 Future<Description> hasMatch(ScheduledStream stream) {
40 var fork = stream.fork();
41 return tryMatch(fork).whenComplete(fork.close);
42 }
43
32 String toString(); 44 String toString();
33 } 45 }
34 46
35 /// A matcher that consumes and matches a single value. 47 /// A matcher that consumes and matches a single value.
36 /// 48 ///
37 /// [matcher] can be a [Matcher] or an [Object], but not a [StreamMatcher]. 49 /// [matcher] can be a [Matcher] or an [Object], but not a [StreamMatcher].
38 StreamMatcher nextValue(matcher) => new _NextValueMatcher(matcher); 50 StreamMatcher nextValue(matcher) => new _NextValueMatcher(matcher);
39 51
40 /// A matcher that consumes [n] values and matches a list containing those 52 /// A matcher that consumes [n] values and matches a list containing those
41 /// objects against [matcher]. 53 /// objects against [matcher].
42 /// 54 ///
43 /// [matcher] can be a [Matcher] or an [Object], but not a [StreamMatcher]. 55 /// [matcher] can be a [Matcher] or an [Object], but not a [StreamMatcher].
44 StreamMatcher nextValues(int n, matcher) => new _NextValuesMatcher(n, matcher); 56 StreamMatcher nextValues(int n, matcher) => new _NextValuesMatcher(n, matcher);
45 57
46 /// A matcher that matches several sub-matchers in sequence. 58 /// A matcher that matches several sub-matchers in sequence.
47 /// 59 ///
48 /// Each element of [streamMatchers] can be a [StreamMatcher], a [Matcher], or 60 /// Each element of [streamMatchers] can be a [StreamMatcher], a [Matcher], or
49 /// an [Object]. 61 /// an [Object].
50 StreamMatcher inOrder(Iterable streamMatchers) { 62 StreamMatcher inOrder(Iterable streamMatchers) {
51 streamMatchers = streamMatchers.toList(); 63 streamMatchers = streamMatchers.toList();
52 if (streamMatchers.length == 1) { 64 if (streamMatchers.length == 1) {
53 return new StreamMatcher.wrap(streamMatchers.first); 65 return new StreamMatcher.wrap(streamMatchers.first);
54 } else { 66 } else {
55 return new _InOrderMatcher(streamMatchers); 67 return new _InOrderMatcher(streamMatchers);
56 } 68 }
57 } 69 }
58 70
59 /// A matcher that consumes values emitted by a stream until one matching 71 /// A matcher that consumes values emitted by a stream until one matching
60 /// [matcher] is emitted. 72 /// [streamMatcher] is emitted.
61 /// 73 ///
62 /// This will fail if the stream never emits a value that matches [matcher]. 74 /// This will fail if the stream never emits a value that matches
75 /// [streamMatcher].
63 /// 76 ///
64 /// [matcher] can be a [Matcher] or an [Object], but not a [StreamMatcher]. 77 /// [streamMatcher] can be a [StreamMatcher], a [Matcher] or an [Object].
65 StreamMatcher consumeThrough(matcher) => new _ConsumeThroughMatcher(matcher); 78 StreamMatcher consumeThrough(streamMatcher) =>
79 new _ConsumeThroughMatcher(streamMatcher);
66 80
67 /// A matcher that consumes values emitted by a stream as long as they match 81 /// A matcher that consumes values emitted by a stream as long as they match
68 /// [matcher]. 82 /// [streamMatcher].
69 /// 83 ///
70 /// This matcher will always match a stream. It exists to consume values. 84 /// This matcher will always match a stream. It exists to consume values. If
85 /// [streamMatcher] consumes more than one value, the next match will begin
86 /// after all the consumed values.
71 /// 87 ///
72 /// [matcher] can be a [Matcher] or an [Object], but not a [StreamMatcher]. 88 /// [streamMatcher] can be a [StreamMatcher], a [Matcher] or an [Object].
73 StreamMatcher consumeWhile(matcher) => new _ConsumeWhileMatcher(matcher); 89 StreamMatcher consumeWhile(streamMatcher) =>
90 new _ConsumeWhileMatcher(streamMatcher);
74 91
75 /// A matcher that matches either [streamMatcher1], [streamMatcher2], or both. 92 /// A matcher that matches either [streamMatcher1], [streamMatcher2], or both.
76 /// 93 ///
77 /// If both matchers match the stream, the one that consumed more values will be 94 /// If both matchers match the stream, the one that consumed more values will be
78 /// used. 95 /// used.
79 /// 96 ///
80 /// Both [streamMatcher1] and [streamMatcher2] can be a [StreamMatcher], a 97 /// Both [streamMatcher1] and [streamMatcher2] can be a [StreamMatcher], a
81 /// [Matcher], or an [Object]. 98 /// [Matcher], or an [Object].
82 StreamMatcher either(streamMatcher1, streamMatcher2) => 99 StreamMatcher either(streamMatcher1, streamMatcher2) =>
83 new _EitherMatcher(streamMatcher1, streamMatcher2); 100 new _EitherMatcher(streamMatcher1, streamMatcher2);
(...skipping 11 matching lines...) Expand all
95 /// 112 ///
96 /// This will consume the remainder of a stream. 113 /// This will consume the remainder of a stream.
97 /// 114 ///
98 /// [streamMatcher] can be a [StreamMatcher], a [Matcher], or an [Object]. 115 /// [streamMatcher] can be a [StreamMatcher], a [Matcher], or an [Object].
99 StreamMatcher never(streamMatcher) => new _NeverMatcher(streamMatcher); 116 StreamMatcher never(streamMatcher) => new _NeverMatcher(streamMatcher);
100 117
101 /// A matcher that matches a stream that emits no more values. 118 /// A matcher that matches a stream that emits no more values.
102 StreamMatcher get isDone => new _IsDoneMatcher(); 119 StreamMatcher get isDone => new _IsDoneMatcher();
103 120
104 /// See [nextValue]. 121 /// See [nextValue].
105 class _NextValueMatcher implements StreamMatcher { 122 class _NextValueMatcher extends StreamMatcher {
106 final Matcher _matcher; 123 final Matcher _matcher;
107 124
108 _NextValueMatcher(matcher) 125 _NextValueMatcher(matcher)
109 : _matcher = wrapMatcher(matcher); 126 : _matcher = wrapMatcher(matcher);
110 127
111 Future<Description> tryMatch(ScheduledStream stream) { 128 Future<Description> tryMatch(ScheduledStream stream) {
112 return stream.hasNext.then((hasNext) { 129 return stream.hasNext.then((hasNext) {
113 if (!hasNext) { 130 if (!hasNext) {
114 return new StringDescription("unexpected end of stream"); 131 return new StringDescription("unexpected end of stream");
115 } 132 }
116 return stream.next().then((value) { 133 return stream.next().then((value) {
117 var matchState = {}; 134 var matchState = {};
118 if (_matcher.matches(value, matchState)) return null; 135 if (_matcher.matches(value, matchState)) return null;
119 return _matcher.describeMismatch(value, new StringDescription(), 136 return _matcher.describeMismatch(value, new StringDescription(),
120 matchState, false); 137 matchState, false);
121 }); 138 });
122 }); 139 });
123 } 140 }
124 141
125 String toString() => _matcher.describe(new StringDescription()).toString(); 142 String toString() => _matcher.describe(new StringDescription()).toString();
126 } 143 }
127 144
128 /// See [nextValues]. 145 /// See [nextValues].
129 class _NextValuesMatcher implements StreamMatcher { 146 class _NextValuesMatcher extends StreamMatcher {
130 final int _n; 147 final int _n;
131 final Matcher _matcher; 148 final Matcher _matcher;
132 149
133 _NextValuesMatcher(this._n, matcher) 150 _NextValuesMatcher(this._n, matcher)
134 : _matcher = wrapMatcher(matcher); 151 : _matcher = wrapMatcher(matcher);
135 152
136 Future<Description> tryMatch(ScheduledStream stream) { 153 Future<Description> tryMatch(ScheduledStream stream) {
137 var collectedValues = []; 154 var collectedValues = [];
138 collectValues(count) { 155 collectValues(count) {
139 if (count == 0) return null; 156 if (count == 0) return null;
(...skipping 18 matching lines...) Expand all
158 } 175 }
159 176
160 String toString() { 177 String toString() {
161 return new StringDescription('$_n values that ') 178 return new StringDescription('$_n values that ')
162 .addDescriptionOf(_matcher) 179 .addDescriptionOf(_matcher)
163 .toString(); 180 .toString();
164 } 181 }
165 } 182 }
166 183
167 /// See [inOrder]. 184 /// See [inOrder].
168 class _InOrderMatcher implements StreamMatcher { 185 class _InOrderMatcher extends StreamMatcher {
169 final List<StreamMatcher> _matchers; 186 final List<StreamMatcher> _matchers;
170 187
171 _InOrderMatcher(Iterable streamMatchers) 188 _InOrderMatcher(Iterable streamMatchers)
172 : _matchers = streamMatchers.map((matcher) => 189 : _matchers = streamMatchers.map((matcher) =>
173 new StreamMatcher.wrap(matcher)).toList(); 190 new StreamMatcher.wrap(matcher)).toList();
174 191
175 Future<Description> tryMatch(ScheduledStream stream) { 192 Future<Description> tryMatch(ScheduledStream stream) {
176 var matchers = new Queue.from(_matchers); 193 var matchers = new Queue.from(_matchers);
177 194
178 matchNext() { 195 matchNext() {
(...skipping 10 matching lines...) Expand all
189 206
190 return matchNext(); 207 return matchNext();
191 } 208 }
192 209
193 String toString() => _matchers 210 String toString() => _matchers
194 .map((matcher) => prefixLines(matcher.toString(), firstPrefix: '* ')) 211 .map((matcher) => prefixLines(matcher.toString(), firstPrefix: '* '))
195 .join('\n'); 212 .join('\n');
196 } 213 }
197 214
198 /// See [consumeThrough]. 215 /// See [consumeThrough].
199 class _ConsumeThroughMatcher implements StreamMatcher { 216 class _ConsumeThroughMatcher extends StreamMatcher {
200 final Matcher _matcher; 217 final StreamMatcher _matcher;
201 218
202 _ConsumeThroughMatcher(matcher) 219 _ConsumeThroughMatcher(streamMatcher)
203 : _matcher = wrapMatcher(matcher); 220 : _matcher = new StreamMatcher.wrap(streamMatcher);
204 221
205 Future<Description> tryMatch(ScheduledStream stream) { 222 Future<Description> tryMatch(ScheduledStream stream) {
206 consumeNext() { 223 consumeNext() {
207 return stream.hasNext.then((hasNext) { 224 return stream.hasNext.then((hasNext) {
208 if (!hasNext) return new StringDescription("unexpected end of stream"); 225 if (!hasNext) return new StringDescription("unexpected end of stream");
209 226
210 return stream.next().then((value) { 227 return _matcher.hasMatch(stream).then((failure) {
211 if (_matcher.matches(value, {})) return null; 228 if (failure != null) return stream.next().then((_) => consumeNext());
212 return consumeNext(); 229 return _matcher.tryMatch(stream);
213 }); 230 });
214 }); 231 });
215 } 232 }
216 233
217 return consumeNext(); 234 return consumeNext();
218 } 235 }
219 236
220 String toString() { 237 String toString() {
221 return new StringDescription('values followed by ') 238 var matcherString = _matcher.toString();
222 .addDescriptionOf(_matcher).toString(); 239 if (matcherString.contains("\n")) {
240 return 'values followed by:\n' + prefixLines(matcherString, prefix: ' ');
241 } else {
242 return 'values followed by $matcherString';
243 }
223 } 244 }
224 } 245 }
225 246
226 /// See [consumeWhile]. 247 /// See [consumeWhile].
227 class _ConsumeWhileMatcher implements StreamMatcher { 248 class _ConsumeWhileMatcher extends StreamMatcher {
228 final Matcher _matcher; 249 final StreamMatcher _matcher;
229 250
230 _ConsumeWhileMatcher(matcher) 251 _ConsumeWhileMatcher(matcher)
231 : _matcher = wrapMatcher(matcher); 252 : _matcher = new StreamMatcher.wrap(matcher);
232 253
233 Future<Description> tryMatch(ScheduledStream stream) { 254 Future<Description> tryMatch(ScheduledStream stream) {
234 consumeNext() { 255 consumeNext() {
235 return stream.hasNext.then((hasNext) { 256 return stream.hasNext.then((hasNext) {
236 if (!hasNext) return new Future.value(); 257 if (!hasNext) return new Future.value();
237 258
238 return _peek(stream).then((value) { 259 return _matcher.hasMatch(stream).then((failure) {
239 if (!_matcher.matches(value, {})) return null; 260 if (failure != null) return new Future.value();
240 return stream.next().then((_) => consumeNext()); 261 return _matcher.tryMatch(stream).then((_) => consumeNext());
241 }); 262 });
242 }); 263 });
243 } 264 }
244 265
245 return consumeNext(); 266 return consumeNext();
246 } 267 }
247 268
248 String toString() { 269 String toString() {
249 return new StringDescription('any number of ') 270 var matcherString = _matcher.toString();
250 .addDescriptionOf(_matcher).toString(); 271 if (matcherString.contains("\n")) {
272 return 'any number of\n' + prefixLines(matcherString, prefix: ' ');
273 } else {
274 return 'any number of $matcherString';
275 }
251 } 276 }
252 } 277 }
253 278
254 /// See [either]. 279 /// See [either].
255 class _EitherMatcher implements StreamMatcher { 280 class _EitherMatcher extends StreamMatcher {
256 final StreamMatcher _matcher1; 281 final StreamMatcher _matcher1;
257 final StreamMatcher _matcher2; 282 final StreamMatcher _matcher2;
258 283
259 _EitherMatcher(streamMatcher1, streamMatcher2) 284 _EitherMatcher(streamMatcher1, streamMatcher2)
260 : _matcher1 = new StreamMatcher.wrap(streamMatcher1), 285 : _matcher1 = new StreamMatcher.wrap(streamMatcher1),
261 _matcher2 = new StreamMatcher.wrap(streamMatcher2); 286 _matcher2 = new StreamMatcher.wrap(streamMatcher2);
262 287
263 Future<Description> tryMatch(ScheduledStream stream) { 288 Future<Description> tryMatch(ScheduledStream stream) {
264 var stream1 = stream.fork(); 289 var stream1 = stream.fork();
265 var stream2 = stream.fork(); 290 var stream2 = stream.fork();
(...skipping 29 matching lines...) Expand all
295 String toString() { 320 String toString() {
296 return new StringDescription('either\n') 321 return new StringDescription('either\n')
297 .add(prefixLines(_matcher1.toString(), prefix: ' ')) 322 .add(prefixLines(_matcher1.toString(), prefix: ' '))
298 .add('\nor\n') 323 .add('\nor\n')
299 .add(prefixLines(_matcher2.toString(), prefix: ' ')) 324 .add(prefixLines(_matcher2.toString(), prefix: ' '))
300 .toString(); 325 .toString();
301 } 326 }
302 } 327 }
303 328
304 /// See [allow]. 329 /// See [allow].
305 class _AllowMatcher implements StreamMatcher { 330 class _AllowMatcher extends StreamMatcher {
306 final StreamMatcher _matcher; 331 final StreamMatcher _matcher;
307 332
308 _AllowMatcher(streamMatcher) 333 _AllowMatcher(streamMatcher)
309 : _matcher = new StreamMatcher.wrap(streamMatcher); 334 : _matcher = new StreamMatcher.wrap(streamMatcher);
310 335
311 Future<Description> tryMatch(ScheduledStream stream) { 336 Future<Description> tryMatch(ScheduledStream stream) {
312 var fork = stream.fork(); 337 return _matcher.hasMatch(stream).then((failure) {
313 return _matcher.tryMatch(fork).whenComplete(fork.close).then((failure) {
314 if (failure != null) return null; 338 if (failure != null) return null;
315 return _matcher.tryMatch(stream); 339 return _matcher.tryMatch(stream);
316 }); 340 });
317 } 341 }
318 342
319 String toString() { 343 String toString() {
320 return new StringDescription('allow\n') 344 return new StringDescription('allow\n')
321 .add(prefixLines(_matcher.toString())) 345 .add(prefixLines(_matcher.toString()))
322 .toString(); 346 .toString();
323 } 347 }
324 } 348 }
325 349
326 /// See [never]. 350 /// See [never].
327 class _NeverMatcher implements StreamMatcher { 351 class _NeverMatcher extends StreamMatcher {
328 final StreamMatcher _matcher; 352 final StreamMatcher _matcher;
329 353
330 _NeverMatcher(streamMatcher) 354 _NeverMatcher(streamMatcher)
331 : _matcher = new StreamMatcher.wrap(streamMatcher); 355 : _matcher = new StreamMatcher.wrap(streamMatcher);
332 356
333 Future<Description> tryMatch(ScheduledStream stream) { 357 Future<Description> tryMatch(ScheduledStream stream) {
334 consumeNext() { 358 consumeNext() {
335 return stream.hasNext.then((hasNext) { 359 return stream.hasNext.then((hasNext) {
336 if (!hasNext) return new Future.value(); 360 if (!hasNext) return new Future.value();
337 361
338 var fork = stream.fork(); 362 return _matcher.hasMatch(stream).then((failure) {
339 return _matcher.tryMatch(fork).whenComplete(fork.close)
340 .then((failure) {
341 if (failure != null) { 363 if (failure != null) {
342 return stream.next().then((_) => consumeNext()); 364 return stream.next().then((_) => consumeNext());
343 } 365 }
344 366
345 return new StringDescription("matched\n") 367 return new StringDescription("matched\n")
346 .add(prefixLines(_matcher.toString(), prefix: ' ')); 368 .add(prefixLines(_matcher.toString(), prefix: ' '));
347 }); 369 });
348 }); 370 });
349 } 371 }
350 372
351 return consumeNext(); 373 return consumeNext();
352 } 374 }
353 375
354 String toString() => 376 String toString() =>
355 'never\n${prefixLines(_matcher.toString(), prefix: ' ')}'; 377 'never\n${prefixLines(_matcher.toString(), prefix: ' ')}';
356 } 378 }
357 379
358 /// See [isDone]. 380 /// See [isDone].
359 class _IsDoneMatcher implements StreamMatcher { 381 class _IsDoneMatcher extends StreamMatcher {
360 _IsDoneMatcher(); 382 _IsDoneMatcher();
361 383
362 Future<Description> tryMatch(ScheduledStream stream) { 384 Future<Description> tryMatch(ScheduledStream stream) {
363 return stream.hasNext.then((hasNext) { 385 return stream.hasNext.then((hasNext) {
364 if (!hasNext) return null; 386 if (!hasNext) return null;
365 return new StringDescription("stream wasn't finished"); 387 return new StringDescription("stream wasn't finished");
366 }); 388 });
367 } 389 }
368 390
369 String toString() => 'is done'; 391 String toString() => 'is done';
370 } 392 }
371 393
372 /// Returns a [Future] that completes to the next value emitted by [stream] 394 /// Returns a [Future] that completes to the next value emitted by [stream]
373 /// without actually consuming that value. 395 /// without actually consuming that value.
374 Future _peek(ScheduledStream stream) { 396 Future _peek(ScheduledStream stream) {
375 var fork = stream.fork(); 397 var fork = stream.fork();
376 return fork.next().whenComplete(fork.close); 398 return fork.next().whenComplete(fork.close);
377 } 399 }
OLDNEW
« no previous file with comments | « no previous file | pkg/scheduled_test/pubspec.yaml » ('j') | sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698