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

Side by Side Diff: tests/lib_strong/async/stream_state_helper.dart

Issue 2802973005: Migrate async tests to strong (Closed)
Patch Set: Created 3 years, 8 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) 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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library stream_state_helper;
6
7 import "package:unittest/unittest.dart";
8 import "dart:async";
9 import "dart:collection";
10
11 class SubscriptionProtocolTest {
12 final StreamProtocolTest _streamTest;
13 final int id;
14 StreamSubscription _subscription;
15
16 SubscriptionProtocolTest(this.id, this._subscription, this._streamTest);
17
18 void pause([Future resumeSignal]) {
19 if (_subscription == null) throw new StateError("Not subscribed");
20 _subscription.pause(resumeSignal);
21 }
22
23 void resume() {
24 if (_subscription == null) throw new StateError("Not subscribed");
25 _subscription.resume();
26 }
27
28 void cancel() {
29 if (_subscription == null) throw new StateError("Not subscribed");
30 _subscription.cancel();
31 _subscription = null;
32 }
33
34 void expectData(var data, [void action()]) {
35 _streamTest._expectData(this, data, action);
36 }
37
38 void expectError(var error, [void action()]) {
39 _streamTest._expectError(this, error, action);
40 }
41
42 void expectDone([void action()]) {
43 _streamTest._expectDone(this, action);
44 }
45 }
46
47 class StreamProtocolTest {
48 bool trace = false;
49 final bool isBroadcast;
50 final bool isAsBroadcast;
51 StreamController _controller;
52 Stream _controllerStream;
53 // Most recent subscription created. Used as default for pause/resume.
54 SubscriptionProtocolTest _latestSubscription;
55 List<Event> _expectations = new List<Event>();
56 int _nextExpectationIndex = 0;
57 int _subscriptionIdCounter = 0;
58 Function _onComplete;
59
60 StreamProtocolTest.broadcast({ bool sync: false })
61 : isBroadcast = true, isAsBroadcast = false {
62 _controller = new StreamController.broadcast(
63 sync: sync,
64 onListen: _onListen,
65 onCancel: _onCancel);
66 _controllerStream = _controller.stream;
67 _onComplete = expectAsync((){
68 _onComplete = null; // Being null marks the test as being complete.
69 });
70 }
71
72 StreamProtocolTest({ bool sync: false })
73 : isBroadcast = false, isAsBroadcast = false {
74 _controller = new StreamController(
75 sync: sync,
76 onListen: _onListen,
77 onPause: _onPause,
78 onResume: _onResume,
79 onCancel: _onCancel);
80 _controllerStream = _controller.stream;
81 _onComplete = expectAsync((){
82 _onComplete = null; // Being null marks the test as being complete.
83 });
84 }
85
86 StreamProtocolTest.asBroadcast({ bool sync: false })
87 : isBroadcast = false, isAsBroadcast = true {
88 _controller = new StreamController(
89 sync: sync,
90 onListen: _onListen,
91 onPause: _onPause,
92 onResume: _onResume,
93 onCancel: _onCancel);
94 _controllerStream = _controller.stream.asBroadcastStream(
95 onListen: _onBroadcastListen,
96 onCancel: _onBroadcastCancel);
97 _onComplete = expectAsync((){
98 _onComplete = null; // Being null marks the test as being complete.
99 });
100 }
101
102 // Actions on the stream and controller.
103 void add(var data) { _controller.add(data); }
104 void error(var error) { _controller.addError(error); }
105 void close() { _controller.close(); }
106
107 SubscriptionProtocolTest listen({bool cancelOnError : false}) {
108 int subscriptionId = _subscriptionIdCounter++;
109
110 StreamSubscription subscription = _controllerStream.listen(
111 (var data) { _onData(subscriptionId, data); },
112 onError: (Object error) { _onError(subscriptionId, error); },
113 onDone: () { _onDone(subscriptionId); },
114 cancelOnError: cancelOnError);
115 _latestSubscription =
116 new SubscriptionProtocolTest(subscriptionId, subscription, this);
117 if (trace) {
118 print("[Listen #$subscriptionId(#${_latestSubscription.hashCode})]");
119 }
120 return _latestSubscription;
121 }
122
123 // Actions on the most recently created subscription.
124 void pause([Future resumeSignal]) {
125 _latestSubscription.pause(resumeSignal);
126 }
127
128 void resume() {
129 _latestSubscription.resume();
130 }
131
132 void cancel() {
133 _latestSubscription.cancel();
134 _latestSubscription = null;
135 }
136
137 // End the test now. There must be no open expectations, and no furter
138 // expectations will be allowed.
139 // Called automatically by an onCancel event on a non-broadcast stream.
140 void terminate() {
141 if (_nextExpectationIndex != _expectations.length) {
142 _withNextExpectation((Event expect) {
143 _fail("Expected: $expect\n"
144 "Found : Early termination.\n${expect._stackTrace}");
145 });
146 }
147 _onComplete();
148 }
149
150 // Handling of stream events.
151 void _onData(int id, var data) {
152 if (trace) print("[Data#$id : $data]");
153 _withNextExpectation((Event expect) {
154 if (!expect.matchData(id, data)) {
155 _fail("Expected: $expect\n"
156 "Found : [Data#$id: $data]\n${expect._stackTrace}");
157 }
158 });
159 }
160
161 void _onError(int id, Object error) {
162 if (trace) print("[Error#$id : $error]");
163 _withNextExpectation((Event expect) {
164 if (!expect.matchError(id, error)) {
165 _fail("Expected: $expect\n"
166 "Found : [Error#$id: ${error}]\n${expect._stackTrace}");
167 }
168 });
169 }
170
171 void _onDone(int id) {
172 if (trace) print("[Done#$id]");
173 _withNextExpectation((Event expect) {
174 if (!expect.matchDone(id)) {
175 _fail("Expected: $expect\n"
176 "Found : [Done#$id]\n${expect._stackTrace}");
177 }
178 });
179 }
180
181 void _onPause() {
182 if (trace) print("[Pause]");
183 _withNextExpectation((Event expect) {
184 if (!expect.matchPause()) {
185 _fail("Expected: $expect\n"
186 "Found : [Paused]\n${expect._stackTrace}");
187 }
188 });
189 }
190
191 void _onResume() {
192 if (trace) print("[Resumed]");
193 _withNextExpectation((Event expect) {
194 if (!expect.matchResume()) {
195 _fail("Expected: $expect\n"
196 "Found : [Resumed]\n${expect._stackTrace}");
197 }
198 });
199 }
200
201 void _onListen() {
202 if (trace) print("[Subscribed]");
203 _withNextExpectation((Event expect) {
204 if (!expect.matchSubscribe()) {
205 _fail("Expected: $expect\n"
206 "Found: [Subscribed]\n${expect._stackTrace}");
207 }
208 });
209 }
210
211 void _onCancel() {
212 if (trace) print("[Cancelled]");
213 _withNextExpectation((Event expect) {
214 if (!expect.matchCancel()) {
215 _fail("Expected: $expect\n"
216 "Found: [Cancelled]\n${expect._stackTrace}");
217 }
218 });
219 }
220
221 void _onBroadcastListen(StreamSubscription sub) {
222 if (trace) print("[BroadcastListen]");
223 _withNextExpectation((Event expect) {
224 if (!expect.matchBroadcastListen(sub)) {
225 _fail("Expected: $expect\n"
226 "Found: [BroadcastListen]\n${expect._stackTrace}");
227 }
228 });
229 }
230
231 void _onBroadcastCancel(StreamSubscription sub) {
232 if (trace) print("[BroadcastCancel]");
233 _withNextExpectation((Event expect) {
234 if (!expect.matchBroadcastCancel(sub)) {
235 _fail("Expected: $expect\n"
236 "Found: [BroadcastCancel]\n${expect._stackTrace}");
237 }
238 });
239 }
240
241 void _withNextExpectation(void action(Event expect)) {
242 if (_nextExpectationIndex == _expectations.length) {
243 _nextExpectationIndex++;
244 action(new MismatchEvent());
245 } else {
246 Event next = _expectations[_nextExpectationIndex++];
247 action(next);
248 }
249 }
250
251 // Adds _expectations.
252 void expectAny([void action()]) {
253 if (_onComplete == null) {
254 _fail("Adding expectation after completing");
255 }
256 _expectations.add(new LogAnyEvent(action));
257 }
258
259 void expectData(var data, [void action()]) {
260 _expectData(null, data, action);
261 }
262
263 void _expectData(SubscriptionProtocolTest sub, var data, void action()) {
264 if (_onComplete == null) {
265 _fail("Adding expectation after completing");
266 }
267 _expectations.add(new DataEvent(sub, data, action));
268 }
269
270 void expectError(var error, [void action()]) {
271 _expectError(null, error, action);
272 }
273
274 void _expectError(SubscriptionProtocolTest sub, var error, void action()) {
275 if (_onComplete == null) {
276 _fail("Adding expectation after completing");
277 }
278 _expectations.add(new ErrorEvent(sub, error, action));
279 }
280
281 void expectDone([void action()]) {
282 _expectDone(null, action);
283 }
284
285 void _expectDone(SubscriptionProtocolTest sub, [void action()]) {
286 if (_onComplete == null) {
287 _fail("Adding expectation after completing");
288 }
289 _expectations.add(new DoneEvent(sub, action));
290 }
291
292 void expectPause([void action()]) {
293 if (_onComplete == null) {
294 _fail("Adding expectation after completing");
295 }
296 _expectations.add(new PauseCallbackEvent(action));
297 }
298
299 void expectResume([void action()]) {
300 if (_onComplete == null) {
301 _fail("Adding expectation after completing");
302 }
303 _expectations.add(new ResumeCallbackEvent(action));
304 }
305
306 void expectListen([void action()]) {
307 if (_onComplete == null) {
308 _fail("Adding expectation after completing");
309 }
310 _expectations.add(
311 new SubscriptionCallbackEvent(action));
312 }
313
314 void expectCancel([void action()]) {
315 if (_onComplete == null) {
316 _fail("Adding expectation after completing");
317 }
318 _expectations.add(
319 new CancelCallbackEvent(action));
320 }
321
322 void expectBroadcastListen([void action(StreamSubscription sub)]) {
323 if (_onComplete == null) {
324 _fail("Adding expectation after completing");
325 }
326 if (!isAsBroadcast) throw new StateError("Not an asBroadcast stream");
327 _expectations.add(new BroadcastListenCallbackEvent(action));
328 }
329
330 void expectBroadcastCancel([void action(StreamSubscription sub)]) {
331 if (_onComplete == null) {
332 _fail("Adding expectation after completing");
333 }
334 if (!isAsBroadcast) throw new StateError("Not an asBroadcast stream");
335 _expectations.add(new BroadcastCancelCallbackEvent(action));
336 }
337
338 void expectBroadcastListenOpt([void action(StreamSubscription sub)]) {
339 if (_onComplete == null) {
340 _fail("Adding expectation after completing");
341 }
342 if (!isAsBroadcast) return;
343 _expectations.add(new BroadcastListenCallbackEvent(action));
344 }
345
346 void expectBroadcastCancelOpt([void action(StreamSubscription sub)]) {
347 if (_onComplete == null) {
348 _fail("Adding expectation after completing");
349 }
350 if (!isAsBroadcast) return;
351 _expectations.add(new BroadcastCancelCallbackEvent(action));
352 }
353
354 void _fail(String message) {
355 if (_nextExpectationIndex == 0) {
356 throw "Unexpected event:\n$message\nNo earlier events matched.";
357 }
358 StringBuffer buf = new StringBuffer();
359 for (int i = 0; i < _expectations.length; i++) {
360 if (i == _nextExpectationIndex - 1) {
361 buf.write("->");
362 } else {
363 buf.write(" ");
364 }
365 buf.write(_expectations[i]);
366 buf.write("\n");
367 }
368 throw "Unexpected event:\n$message\nAll expectations:\n$buf";
369 }
370 }
371
372 class Event {
373 Function _action;
374 StackTrace _stackTrace;
375 Event(void action())
376 : _action = (action == null) ? null : expectAsync(action) {
377 try { throw 0; } catch (_, s) { _stackTrace = s; }
378 }
379 Event.broadcast(void action(StreamSubscription sub))
380 : _action = (action == null) ? null : expectAsync(action) {
381 try { throw 0; } catch (_, s) { _stackTrace = s; }
382 }
383
384 bool matchData(int id, var data) {
385 return false;
386 }
387
388 bool matchError(int id, e) {
389 return false;
390 }
391
392 bool matchDone(int id) {
393 return false;
394 }
395
396 bool matchPause() {
397 if (!_testPause()) return false;
398 if (_action != null) _action();
399 return true;
400 }
401
402 bool matchResume() {
403 if (!_testResume()) return false;
404 if (_action != null) _action();
405 return true;
406 }
407
408 bool matchSubscribe() {
409 if (!_testSubscribe()) return false;
410 if (_action != null) _action();
411 return true;
412 }
413
414 bool matchCancel() {
415 if (!_testCancel()) return false;
416 if (_action != null) _action();
417 return true;
418 }
419
420 bool matchBroadcastListen(StreamSubscription sub) {
421 if (!_testBroadcastListen()) return false;
422 if (_action != null) _action(sub);
423 return true;
424 }
425
426 bool matchBroadcastCancel(StreamSubscription sub) {
427 if (!_testBroadcastCancel()) return false;
428 if (_action != null) _action(sub);
429 return true;
430 }
431
432 bool _testData(_) => false;
433 bool _testError(_) => false;
434 bool _testDone() => false;
435 bool _testPause() => false;
436 bool _testResume() => false;
437 bool _testSubscribe() => false;
438 bool _testCancel() => false;
439 bool _testBroadcastListen() => false;
440 bool _testBroadcastCancel() => false;
441 }
442
443 class SubscriptionEvent extends Event {
444 SubscriptionProtocolTest subscription;
445 SubscriptionEvent(this.subscription, void action()) : super(action);
446
447 bool matchData(int id, var data) {
448 if (subscription != null && subscription.id != id) return false;
449 if (!_testData(data)) return false;
450 if (_action != null) _action();
451 return true;
452 }
453
454 bool matchError(int id, e) {
455 if (subscription != null && subscription.id != id) return false;
456 if (!_testError(e)) return false;
457 if (_action != null) _action();
458 return true;
459 }
460
461 bool matchDone(int id) {
462 if (subscription != null && subscription.id != id) return false;
463 if (!_testDone()) return false;
464 if (_action != null) _action();
465 return true;
466 }
467
468 String get _id => (subscription == null) ? "" : "#${subscription.id}";
469 }
470
471 class MismatchEvent extends Event {
472 MismatchEvent() : super(null);
473 toString() => "[No event expected]";
474 }
475
476 class DataEvent extends SubscriptionEvent {
477 final data;
478 DataEvent(SubscriptionProtocolTest sub, this.data, void action())
479 : super(sub, action);
480 bool _testData(var data) => this.data == data;
481 String toString() => "[Data$_id: $data]";
482 }
483
484 class ErrorEvent extends SubscriptionEvent {
485 final error;
486 ErrorEvent(SubscriptionProtocolTest sub, this.error, void action())
487 : super(sub, action);
488 bool _testError(error) => this.error == error;
489 String toString() => "[Error$_id: $error]";
490 }
491
492 class DoneEvent extends SubscriptionEvent {
493 DoneEvent(SubscriptionProtocolTest sub, void action()) : super(sub, action);
494 bool _testDone() => true;
495 String toString() => "[Done$_id]";
496 }
497
498 class PauseCallbackEvent extends Event {
499 PauseCallbackEvent(void action()) : super(action);
500 bool _testPause() => true;
501 String toString() => "[Paused]";
502 }
503
504 class ResumeCallbackEvent extends Event {
505 ResumeCallbackEvent(void action()) : super(action);
506 bool _testResume() => true;
507 String toString() => "[Resumed]";
508 }
509
510 class SubscriptionCallbackEvent extends Event {
511 SubscriptionCallbackEvent(void action()) : super(action);
512 bool _testSubscribe() => true;
513 String toString() => "[Subscribed]";
514 }
515
516 class CancelCallbackEvent extends Event {
517 CancelCallbackEvent(void action()) : super(action);
518 bool _testCancel() => true;
519 String toString() => "[Cancelled]";
520 }
521
522 class BroadcastCancelCallbackEvent extends Event {
523 BroadcastCancelCallbackEvent(void action(StreamSubscription sub))
524 : super.broadcast(action);
525 bool _testBroadcastCancel() => true;
526 String toString() => "[BroadcastCancel]";
527 }
528
529 class BroadcastListenCallbackEvent extends Event {
530 BroadcastListenCallbackEvent(void action(StreamSubscription sub))
531 : super.broadcast(action);
532 bool _testBroadcastListen() => true;
533 String toString() => "[BroadcastListen]";
534 }
535
536 /** Event matcher that matches any other event. */
537 class LogAnyEvent extends Event {
538 String _actual = "*Not matched yet*";
539
540 LogAnyEvent(void action()) : super(action);
541
542 bool _testData(var data) {
543 _actual = "*[Data $data]";
544 return true;
545 }
546
547 bool _testError(error) {
548 _actual = "*[Error ${error}]";
549 return true;
550 }
551
552 bool _testDone() {
553 _actual = "*[Done]";
554 return true;
555 }
556
557 bool _testPause() {
558 _actual = "*[Paused]";
559 return true;
560 }
561
562 bool _testResume() {
563 _actual = "*[Resumed]";
564 return true;
565 }
566
567 bool _testSubcribe() {
568 _actual = "*[Subscribed]";
569 return true;
570 }
571
572 bool _testCancel() {
573 _actual = "*[Cancelled]";
574 return true;
575 }
576
577 bool _testBroadcastListen() {
578 _actual = "*[BroadcastListen]";
579 return true;
580 }
581
582 bool _testBroadcastCancel() {
583 _actual = "*[BroadcastCancel]";
584 return true;
585 }
586
587 /** Returns a representation of the event it was tested against. */
588 String toString() => _actual;
589 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698