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

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

Issue 16125005: Make new StreamController be async by default. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 6 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 stream_state_helper; 5 library stream_state_helper;
6 6
7 import "../../../pkg/unittest/lib/unittest.dart"; 7 import "../../../pkg/unittest/lib/unittest.dart";
8 import "dart:async"; 8 import "dart:async";
9 import "dart:collection"; 9 import "dart:collection";
10 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
11 class StreamProtocolTest { 47 class StreamProtocolTest {
12 bool trace = false; 48 bool trace = false;
49 // If not a broadcast stream, the onComplete is called automatically by
50 // the first onCancel.
51 bool isBroadcast;
13 StreamController _controller; 52 StreamController _controller;
14 Stream _controllerStream; 53 Stream _controllerStream;
15 StreamSubscription _subscription; 54 // Most recent subscription created. Used as default for pause/resume.
55 SubscriptionProtocolTest _latestSubscription;
16 List<Event> _expectations = new List<Event>(); 56 List<Event> _expectations = new List<Event>();
17 int _nextExpectationIndex = 0; 57 int _nextExpectationIndex = 0;
58 int _subscriptionIdCounter = 0;
18 Function _onComplete; 59 Function _onComplete;
19 60
20 StreamProtocolTest([bool broadcast = false]) { 61 StreamProtocolTest.broadcast({ bool sync: false }) : isBroadcast = true {
floitsch 2013/05/30 12:13:48 move initializer list to next line.
Lasse Reichstein Nielsen 2013/05/31 05:51:59 There is room? But ok.
62 _controller = new StreamController.broadcast(
63 sync: sync,
64 onListen: _onListen,
65 onCancel: _onCancel);
66 _controllerStream = _controller.stream;
67 _onComplete = expectAsync0((){
68 _onComplete = null; // Being null marks the test as being complete.
69 });
70 }
71
72 StreamProtocolTest({ bool broadcast: false, bool sync: false })
73 : isBroadcast = false {
21 _controller = new StreamController( 74 _controller = new StreamController(
22 onListen: _onSubcription, 75 sync: sync,
23 onPause: _onPause, 76 onListen: _onListen,
24 onResume: _onResume, 77 onPause: _onPause,
25 onCancel: _onCancel); 78 onResume: _onResume,
79 onCancel: _onCancel);
26 if (broadcast) { 80 if (broadcast) {
27 _controllerStream = _controller.stream.asBroadcastStream(); 81 _controllerStream = _controller.stream.asBroadcastStream();
28 } else { 82 } else {
29 _controllerStream = _controller.stream; 83 _controllerStream = _controller.stream;
30 } 84 }
31 _onComplete = expectAsync0((){ 85 _onComplete = expectAsync0((){
32 _onComplete = null; // Being null marks the test to be complete. 86 _onComplete = null; // Being null marks the test as being complete.
33 }); 87 });
34 } 88 }
35 89
36 // Actions on the stream and controller. 90 // Actions on the stream and controller.
37 void add(var data) { _controller.add(data); } 91 void add(var data) { _controller.add(data); }
38 void error(var error) { _controller.addError(error); } 92 void error(var error) { _controller.addError(error); }
39 void close() { _controller.close(); } 93 void close() { _controller.close(); }
40 94
41 void subscribe({bool cancelOnError : false}) { 95 SubscriptionProtocolTest listen({bool cancelOnError : false}) {
42 // TODO(lrn): Handle more subscriptions (e.g., a subscription-id 96 int subscriptionId = _subscriptionIdCounter++;
43 // per subscription, and an id on event _expectations). 97
44 if (_subscription != null) throw new StateError("Already subscribed"); 98 StreamSubscription subscription = _controllerStream.listen(
45 _subscription = _controllerStream.listen(_onData, 99 (var data) { _onData(subscriptionId, data); },
46 onError: _onError, 100 onError: (Object error) { _onError(subscriptionId, error); },
47 onDone: _onDone, 101 onDone: () { _onDone(subscriptionId); },
48 cancelOnError: 102 cancelOnError: cancelOnError);
49 cancelOnError); 103 _latestSubscription =
104 new SubscriptionProtocolTest(subscriptionId, subscription, this);
105 return _latestSubscription;
50 } 106 }
51 107
108 // Actions on the most recently created subscription.
52 void pause([Future resumeSignal]) { 109 void pause([Future resumeSignal]) {
53 if (_subscription == null) throw new StateError("Not subscribed"); 110 _latestSubscription.pause(resumeSignal);
54 _subscription.pause(resumeSignal);
55 } 111 }
56 112
57 void resume() { 113 void resume() {
58 if (_subscription == null) throw new StateError("Not subscribed"); 114 _latestSubscription.resume();
59 _subscription.resume();
60 } 115 }
61 116
62 void cancel() { 117 void cancel() {
63 if (_subscription == null) throw new StateError("Not subscribed"); 118 _latestSubscription.cancel();
64 _subscription.cancel(); 119 _latestSubscription = null;
65 _subscription = null; 120 }
121
122 // End the test now. There must be no open expectations, and no furter
123 // expectations will be allowed.
124 // Called automatically by an onCancel event on a non-broadcast stream.
125 void terminate() {
126 if (_nextExpectationIndex != _expectations.length) {
127 _withNextExpectation((Event expect) {
128 _fail("Expected: $expect\n"
129 "Found : Early termination.");
130 });
131 }
132 _onComplete();
66 } 133 }
67 134
68 // Handling of stream events. 135 // Handling of stream events.
69 void _onData(var data) { 136 void _onData(int id, var data) {
70 if (trace) print("[Data : $data]"); 137 if (trace) print("[Data#$id : $data]");
71 _withNextExpectation((Event expect) { 138 _withNextExpectation((Event expect) {
72 if (!expect.matchData(data)) { 139 if (!expect.matchData(id, data)) {
73 _fail("Expected: $expect\n" 140 _fail("Expected: $expect\n"
74 "Found : [Data: $data]"); 141 "Found : [Data#$id: $data]");
75 } 142 }
76 }); 143 });
77 } 144 }
78 145
79 void _onError(error) { 146 void _onError(int id, Object error) {
80 if (trace) print("[Error : $error]"); 147 if (trace) print("[Error#$id : $error]");
81 _withNextExpectation((Event expect) { 148 _withNextExpectation((Event expect) {
82 if (!expect.matchError(error)) { 149 if (!expect.matchError(id, error)) {
83 _fail("Expected: $expect\n" 150 _fail("Expected: $expect\n"
84 "Found : [Error: ${error}]"); 151 "Found : [Error#$id: ${error}]");
85 } 152 }
86 }); 153 });
87 } 154 }
88 155
89 void _onDone() { 156 void _onDone(int id) {
90 if (trace) print("[Done]"); 157 if (trace) print("[Done#$id]");
91 _subscription = null;
92 _withNextExpectation((Event expect) { 158 _withNextExpectation((Event expect) {
93 if (!expect.matchDone()) { 159 if (!expect.matchDone(id)) {
94 _fail("Expected: $expect\n" 160 _fail("Expected: $expect\n"
95 "Found : [Done]"); 161 "Found : [Done#$id]");
96 } 162 }
97 }); 163 });
98 } 164 }
99 165
100 void _onPause() { 166 void _onPause() {
101 if (trace) print("[Pause]"); 167 if (trace) print("[Pause]");
102 _withNextExpectation((Event expect) { 168 _withNextExpectation((Event expect) {
103 if (!expect.matchPause()) { 169 if (!expect.matchPause()) {
104 _fail("Expected: $expect\n" 170 _fail("Expected: $expect\n"
105 "Found : [Paused]"); 171 "Found : [Paused]");
106 } 172 }
107 }); 173 });
108 } 174 }
109 175
110 void _onResume() { 176 void _onResume() {
111 if (trace) print("[Resumed]"); 177 if (trace) print("[Resumed]");
112 _withNextExpectation((Event expect) { 178 _withNextExpectation((Event expect) {
113 if (!expect.matchResume()) { 179 if (!expect.matchResume()) {
114 _fail("Expected: $expect\n" 180 _fail("Expected: $expect\n"
115 "Found : [Resumed]"); 181 "Found : [Resumed]");
116 } 182 }
117 }); 183 });
118 } 184 }
119 185
120 void _onSubcription() { 186 void _onListen() {
121 if (trace) print("[Subscribed]"); 187 if (trace) print("[Subscribed]");
122 _withNextExpectation((Event expect) { 188 _withNextExpectation((Event expect) {
123 if (!expect.matchSubscribe()) { 189 if (!expect.matchSubscribe()) {
124 _fail("Expected: $expect\n" 190 _fail("Expected: $expect\n"
125 "Found: [Subscribed]"); 191 "Found: [Subscribed]");
126 } 192 }
127 }); 193 });
128 } 194 }
129 195
130 void _onCancel() { 196 void _onCancel() {
131 if (trace) print("[Cancelled]"); 197 if (trace) print("[Cancelled]");
132 _withNextExpectation((Event expect) { 198 _withNextExpectation((Event expect) {
133 if (!expect.matchCancel()) { 199 if (!expect.matchCancel()) {
134 _fail("Expected: $expect\n" 200 _fail("Expected: $expect\n"
135 "Found: [Cancelled]"); 201 "Found: [Cancelled]");
136 } 202 }
137 }); 203 });
204 if (!isBroadcast) terminate();
138 } 205 }
139 206
140 void _withNextExpectation(void action(Event expect)) { 207 void _withNextExpectation(void action(Event expect)) {
141 if (_nextExpectationIndex == _expectations.length) { 208 if (_nextExpectationIndex == _expectations.length) {
142 action(new MismatchEvent()); 209 action(new MismatchEvent());
143 } else { 210 } else {
144 Event next = _expectations[_nextExpectationIndex]; 211 Event next = _expectations[_nextExpectationIndex++];
145 action(next); 212 action(next);
146 } 213 }
147 _nextExpectationIndex++;
148 _checkDone();
149 } 214 }
150 215
151 void _checkDone() {
152 if (_nextExpectationIndex == _expectations.length) {
153 _onComplete();
154 }
155 }
156
157
158 // Adds _expectations. 216 // Adds _expectations.
159 void expectAny([void action()]) { 217 void expectAny([void action()]) {
160 if (_onComplete == null) { 218 if (_onComplete == null) {
161 _fail("Adding expectation after completing"); 219 _fail("Adding expectation after completing");
162 } 220 }
163 _expectations.add(new LogAnyEvent(action)); 221 _expectations.add(new LogAnyEvent(action));
164 } 222 }
223
165 void expectData(var data, [void action()]) { 224 void expectData(var data, [void action()]) {
225 _expectData(null, data, action);
226 }
227
228 void _expectData(SubscriptionProtocolTest sub, var data, [void action()]) {
166 if (_onComplete == null) { 229 if (_onComplete == null) {
167 _fail("Adding expectation after completing"); 230 _fail("Adding expectation after completing");
168 } 231 }
169 _expectations.add(new DataEvent(data, action)); 232 _expectations.add(new DataEvent(sub, data, action));
170 } 233 }
234
171 void expectError(var error, [void action()]) { 235 void expectError(var error, [void action()]) {
236 _expectError(null, error, action);
237 }
238
239 void _expectError(SubscriptionProtocolTest sub, var error, [void action()]) {
172 if (_onComplete == null) { 240 if (_onComplete == null) {
173 _fail("Adding expectation after completing"); 241 _fail("Adding expectation after completing");
174 } 242 }
175 _expectations.add(new ErrorEvent(error, action)); 243 _expectations.add(new ErrorEvent(sub, error, action));
176 } 244 }
245
177 void expectDone([void action()]) { 246 void expectDone([void action()]) {
247 _expectDone(null, action);
248 }
249
250 void _expectDone(SubscriptionProtocolTest sub, [void action()]) {
178 if (_onComplete == null) { 251 if (_onComplete == null) {
179 _fail("Adding expectation after completing"); 252 _fail("Adding expectation after completing");
180 } 253 }
181 _expectations.add(new DoneEvent(action)); 254 _expectations.add(new DoneEvent(sub, action));
182 } 255 }
256
183 void expectPause([void action()]) { 257 void expectPause([void action()]) {
184 if (_onComplete == null) { 258 if (_onComplete == null) {
185 _fail("Adding expectation after completing"); 259 _fail("Adding expectation after completing");
186 } 260 }
187 _expectations.add(new PauseCallbackEvent(action)); 261 _expectations.add(new PauseCallbackEvent(action));
188 } 262 }
189 void expectResume([void action()]) { 263 void expectResume([void action()]) {
190 if (_onComplete == null) { 264 if (_onComplete == null) {
191 _fail("Adding expectation after completing"); 265 _fail("Adding expectation after completing");
192 } 266 }
193 _expectations.add(new ResumeCallbackEvent(action)); 267 _expectations.add(new ResumeCallbackEvent(action));
194 } 268 }
195 void expectSubscription([void action()]) { 269 void expectListen([void action()]) {
196 if (_onComplete == null) { 270 if (_onComplete == null) {
197 _fail("Adding expectation after completing"); 271 _fail("Adding expectation after completing");
198 } 272 }
199 _expectations.add( 273 _expectations.add(
200 new SubscriptionCallbackEvent(action)); 274 new SubscriptionCallbackEvent(action));
201 } 275 }
202 void expectCancel([void action()]) { 276 void expectCancel([void action()]) {
203 if (_onComplete == null) { 277 if (_onComplete == null) {
204 _fail("Adding expectation after completing"); 278 _fail("Adding expectation after completing");
205 } 279 }
206 _expectations.add( 280 _expectations.add(
207 new CancelCallbackEvent(action)); 281 new CancelCallbackEvent(action));
208 } 282 }
209 283
210 void _fail(String message) { 284 void _fail(String message) {
211 if (_nextExpectationIndex == 0) { 285 if (_nextExpectationIndex == 0) {
212 throw "Unexpected event:\n$message\nNo earlier events matched."; 286 throw "Unexpected event:\n$message\nNo earlier events matched.";
213 } 287 }
214 throw "Unexpected event:\n$message\nMatched so far:\n" 288 throw "Unexpected event:\n$message\nMatched so far:\n"
215 " ${_expectations.take(_nextExpectationIndex).join("\n ")}"; 289 " ${_expectations.take(_nextExpectationIndex - 1).join("\n ")}";
216 } 290 }
217 } 291 }
218 292
219 class Event { 293 class Event {
220 Function _action; 294 Function _action;
221 Event(void this._action()); 295 Event(void this._action());
222 296
223 bool matchData(var data) { 297 bool matchData(int id, var data) {
224 if (!_testData(data)) return false; 298 return false;
225 if (_action != null) _action();
226 return true;
227 } 299 }
228 bool matchError(e) { 300 bool matchError(int id, e) {
229 if (!_testError(e)) return false; 301 return false;
230 if (_action != null) _action();
231 return true;
232 } 302 }
233 bool matchDone() { 303 bool matchDone(int id) {
234 if (!_testDone()) return false; 304 return false;
235 if (_action != null) _action();
236 return true;
237 } 305 }
238 bool matchPause() { 306 bool matchPause() {
239 if (!_testPause()) return false; 307 if (!_testPause()) return false;
240 if (_action != null) _action(); 308 if (_action != null) _action();
241 return true; 309 return true;
242 } 310 }
243 bool matchResume() { 311 bool matchResume() {
244 if (!_testResume()) return false; 312 if (!_testResume()) return false;
245 if (_action != null) _action(); 313 if (_action != null) _action();
246 return true; 314 return true;
(...skipping 11 matching lines...) Expand all
258 326
259 bool _testData(_) => false; 327 bool _testData(_) => false;
260 bool _testError(_) => false; 328 bool _testError(_) => false;
261 bool _testDone() => false; 329 bool _testDone() => false;
262 bool _testPause() => false; 330 bool _testPause() => false;
263 bool _testResume() => false; 331 bool _testResume() => false;
264 bool _testSubscribe() => false; 332 bool _testSubscribe() => false;
265 bool _testCancel() => false; 333 bool _testCancel() => false;
266 } 334 }
267 335
336 class SubscriptionEvent extends Event {
337 SubscriptionProtocolTest subscription;
338 SubscriptionEvent(this.subscription, void action()) : super(action);
339
340 bool matchData(int id, var data) {
341 if (subscription != null && subscription.id != id) return false;
342 if (!_testData(data)) return false;
343 if (_action != null) _action();
344 return true;
345 }
346 bool matchError(int id, e) {
347 if (subscription != null && subscription.id != id) return false;
348 if (!_testError(e)) return false;
349 if (_action != null) _action();
350 return true;
351 }
352 bool matchDone(int id) {
353 if (subscription != null && subscription.id != id) return false;
354 if (!_testDone()) return false;
355 if (_action != null) _action();
356 return true;
357 }
358 String get _id => (subscription == null) ? "" : "#${subscription.id}";
359 }
360
268 class MismatchEvent extends Event { 361 class MismatchEvent extends Event {
269 MismatchEvent() : super(null); 362 MismatchEvent() : super(null);
270 toString() => "[No event expected]"; 363 toString() => "[No event expected]";
271 } 364 }
272 365
273 class DataEvent extends Event { 366 class DataEvent extends SubscriptionEvent {
274 final data; 367 final data;
275 DataEvent(this.data, void action()) : super(action); 368 DataEvent(SubscriptionProtocolTest sub, this.data, void action())
369 : super(sub, action);
276 bool _testData(var data) => this.data == data; 370 bool _testData(var data) => this.data == data;
277 String toString() => "[Data: $data]"; 371 String toString() => "[Data$_id: $data]";
278 } 372 }
279 373
280 class ErrorEvent extends Event { 374 class ErrorEvent extends SubscriptionEvent {
281 final error; 375 final error;
282 ErrorEvent(this.error, void action()) : super(action); 376 ErrorEvent(SubscriptionProtocolTest sub, this.error, void action())
377 : super(sub, action);
283 bool _testError(error) => this.error == error; 378 bool _testError(error) => this.error == error;
284 String toString() => "[Error: $error]"; 379 String toString() => "[Error$_id: $error]";
285 } 380 }
286 381
287 class DoneEvent extends Event { 382 class DoneEvent extends SubscriptionEvent {
288 DoneEvent(void action()) : super(action); 383 DoneEvent(SubscriptionProtocolTest sub, void action()) : super(sub, action);
289 bool _testDone() => true; 384 bool _testDone() => true;
290 String toString() => "[Done]"; 385 String toString() => "[Done$_id]";
291 } 386 }
292 387
293 class PauseCallbackEvent extends Event { 388 class PauseCallbackEvent extends Event {
294 PauseCallbackEvent(void action()) : super(action); 389 PauseCallbackEvent(void action()) : super(action);
295 bool _testPause() => true; 390 bool _testPause() => true;
296 String toString() => "[Paused]"; 391 String toString() => "[Paused]";
297 } 392 }
298 393
299 class ResumeCallbackEvent extends Event { 394 class ResumeCallbackEvent extends Event {
300 ResumeCallbackEvent(void action()) : super(action); 395 ResumeCallbackEvent(void action()) : super(action);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 _actual = "*[Subscribed]"; 437 _actual = "*[Subscribed]";
343 return true; 438 return true;
344 } 439 }
345 bool _testCancel() { 440 bool _testCancel() {
346 _actual = "*[Cancelled]"; 441 _actual = "*[Cancelled]";
347 return true; 442 return true;
348 } 443 }
349 444
350 String toString() => _actual; 445 String toString() => _actual;
351 } 446 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698