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

Side by Side Diff: pkg/analyzer/test/cancelable_future_test.dart

Issue 806733003: Make futures returned by AnalysisContext cancelable. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years 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
(Empty)
1 // Copyright (c) 2014, 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 test.cancelable_future;
6
7 import 'reflective_tests.dart';
8 import 'package:analyzer/src/cancelable_future.dart';
9 import 'dart:async';
10 import 'package:unittest/unittest.dart';
11 import 'package:watcher/src/utils.dart';
12
13 void main() {
14 groupSep = ' | ';
15 runReflectiveTests(CancelableCompleterTests);
16 runReflectiveTests(CancelableFutureTests);
17 }
18
19 @ReflectiveTestCase()
20 class CancelableFutureTests {
21 Future test_defaultConstructor_returnValue() {
22 Object obj = new Object();
23 bool callbackInvoked = false;
24 new CancelableFuture(() => obj).then((result) {
25 expect(callbackInvoked, isFalse);
26 expect(result, same(obj));
27 callbackInvoked = true;
28 }, onError: (error) {
29 fail('Expected successful completion');
30 });
31 expect(callbackInvoked, isFalse);
32 return pumpEventQueue().then((_) {
33 expect(callbackInvoked, isTrue);
34 });
35 }
36
37 Future test_defaultConstructor_returnFuture() {
38 Object obj = new Object();
39 bool callbackInvoked = false;
40 new CancelableFuture(() => new Future(() => obj)).then((result) {
41 expect(callbackInvoked, isFalse);
42 expect(result, same(obj));
43 callbackInvoked = true;
44 }, onError: (error) {
45 fail('Expected successful completion');
46 });
47 expect(callbackInvoked, isFalse);
48 return pumpEventQueue().then((_) {
49 expect(callbackInvoked, isTrue);
50 });
51 }
52
53 Future test_defaultConstructor_throwException() {
54 Object obj = new Object();
55 bool callbackInvoked = false;
56 new CancelableFuture(() {
57 throw obj;
58 }).then((result) {
59 fail('Expected error completion');
60 }, onError: (error) {
61 expect(callbackInvoked, isFalse);
62 expect(error, same(obj));
63 callbackInvoked = true;
64 });
65 expect(callbackInvoked, isFalse);
66 return pumpEventQueue().then((_) {
67 expect(callbackInvoked, isTrue);
68 });
69 }
70
71 Future test_delayed_noCallback() {
72 DateTime start = new DateTime.now();
73 return new CancelableFuture.delayed(new Duration(seconds: 1)).then((result) {
74 DateTime end = new DateTime.now();
75 expect(result, isNull);
76 expect(end.difference(start).inMilliseconds > 900, isTrue);
77 });
78 }
79
80 Future test_delayed_withCallback() {
81 Object obj = new Object();
82 DateTime start = new DateTime.now();
83 return new CancelableFuture.delayed(new Duration(seconds: 1), () {
84 DateTime end = new DateTime.now();
85 expect(end.difference(start).inMilliseconds > 900, isTrue);
86 return obj;
87 }).then((result) {
88 expect(result, same(obj));
89 });
90 }
91
92 Future test_error() {
93 Object obj = new Object();
94 return new CancelableFuture.error(obj).then((result) {
95 fail('Expected error completion');
96 }, onError: (error) {
97 expect(error, same(obj));
98 });
99 }
100
101 Future test_microtask() {
102 Object obj = new Object();
103 bool callbackInvoked = false;
104 new CancelableFuture.microtask(() => obj).then((result) {
105 expect(callbackInvoked, isFalse);
106 expect(result, same(obj));
107 callbackInvoked = true;
108 }, onError: (error) {
109 fail('Expected successful completion');
110 });
111 expect(callbackInvoked, isFalse);
112 return pumpEventQueue().then((_) {
113 expect(callbackInvoked, isTrue);
114 });
115 }
116
117 Future test_sync() {
118 Object obj = new Object();
119 bool callbackInvoked = false;
120 new CancelableFuture.sync(() => obj).then((result) {
121 expect(callbackInvoked, isFalse);
122 expect(result, same(obj));
123 callbackInvoked = true;
124 }, onError: (error) {
125 fail('Expected successful completion');
126 });
127 expect(callbackInvoked, isFalse);
128 return pumpEventQueue().then((_) {
129 expect(callbackInvoked, isTrue);
130 });
131 }
132
133 Future test_value() {
134 Object obj = new Object();
135 return new CancelableFuture.value(obj).then((result) {
136 expect(result, same(obj));
137 }, onError: (error) {
138 fail('Expected successful completion');
139 });
140 }
141 }
142
143 @ReflectiveTestCase()
144 class CancelableCompleterTests {
145 CancelableCompleter<Object> completer;
146 int cancelCount = 0;
147
148 void setUp() {
149 completer = new CancelableCompleter<Object>(() { cancelCount++; });
150 }
151
152 void test_initialState() {
153 expect(completer.isCompleted, isFalse);
154 expect(cancelCount, 0);
155 }
156
157 void test_complete_after_complete() {
158 // As with an ordinary Completer, calling complete() (or completeError)
159 // after calling complete() should throw an exception.
160 completer.complete();
161 expect(() { completer.complete(); }, throws);
162 expect(() { completer.completeError(new Object()); }, throws);
163 }
164
165 void test_complete_after_completeError() {
166 // As with an ordinary Completer, calling complete() (or completeError)
167 // after calling completeError() should throw an exception.
168 completer.completeError(new Object());
169 expect(() { completer.complete(); }, throws);
170 expect(() { completer.completeError(new Object()); }, throws);
171 // Now absorb the error that's in the completer's future.
172 completer.future.catchError((_) => null);
173 }
174
175 Future test_complete_before_chaining() {
176 Object obj = new Object();
177 completer.complete(obj);
178 expect(completer.isCompleted, isTrue);
179 bool callbackInvoked = false;
180 completer.future.then((result) {
181 expect(callbackInvoked, isFalse);
182 expect(result, same(obj));
183 callbackInvoked = true;
184 }, onError: (error) {
185 fail('Expected successful completion');
186 });
187 // The callback should be deferred to a microtask.
188 expect(callbackInvoked, isFalse);
189 expect(completer.isCompleted, isTrue);
190 return pumpEventQueue().then((_) {
191 expect(callbackInvoked, isTrue);
192 expect(completer.isCompleted, isTrue);
193 expect(cancelCount, 0);
194 });
195 }
196
197 Future test_completeError_before_chaining() {
198 Object obj = new Object();
199 completer.completeError(obj);
200 expect(completer.isCompleted, isTrue);
201 bool callbackInvoked = false;
202 completer.future.then((_) {
203 fail('Expected error completion');
204 }, onError: (error) {
205 expect(callbackInvoked, isFalse);
206 expect(error, same(obj));
207 callbackInvoked = true;
208 });
209 // The callback should be deferred to a microtask.
210 expect(callbackInvoked, isFalse);
211 expect(completer.isCompleted, isTrue);
212 return pumpEventQueue().then((_) {
213 expect(callbackInvoked, isTrue);
214 expect(completer.isCompleted, isTrue);
215 expect(cancelCount, 0);
216 });
217 }
218
219 Future test_complete_after_chaining() {
220 Object obj = new Object();
221 bool callbackInvoked = false;
222 completer.future.then((result) {
223 expect(callbackInvoked, isFalse);
224 expect(result, same(obj));
225 callbackInvoked = true;
226 }, onError: (error) {
227 fail('Expected successful completion');
228 });
229 expect(completer.isCompleted, isFalse);
230 // Running the event loop should have no effect since the completer hasn't
231 // been completed yet.
232 return pumpEventQueue().then((_) {
233 completer.complete(obj);
234 expect(completer.isCompleted, isTrue);
235 // The callback should be deferred to a microtask.
236 expect(callbackInvoked, isFalse);
237 }).then((_) => pumpEventQueue()).then((_) {
238 expect(callbackInvoked, isTrue);
239 expect(completer.isCompleted, isTrue);
240 expect(cancelCount, 0);
241 });
242 }
243
244 Future test_completeError_after_chaining() {
245 Object obj = new Object();
246 bool callbackInvoked = false;
247 completer.future.then((_) {
248 fail('Expected error completion');
249 }, onError: (error) {
250 expect(callbackInvoked, isFalse);
251 expect(error, same(obj));
252 callbackInvoked = true;
253 });
254 expect(completer.isCompleted, isFalse);
255 // Running the event loop should have no effect since the completer hasn't
256 // been completed yet.
257 return pumpEventQueue().then((_) {
258 completer.completeError(obj);
259 expect(completer.isCompleted, isTrue);
260 // The callback should be deferred to a microtask.
261 expect(callbackInvoked, isFalse);
262 }).then((_) => pumpEventQueue()).then((_) {
263 expect(callbackInvoked, isTrue);
264 expect(completer.isCompleted, isTrue);
265 expect(cancelCount, 0);
266 });
267 }
268
269 Future test_cancel_before_chaining() {
270 completer.future.cancel();
271 // The cancel callback should have been invoked immediately.
272 expect(cancelCount, 1);
273 // But the completer should remain in the "not completed" state.
274 expect(completer.isCompleted, isFalse);
275 bool callbackInvoked = false;
276 completer.future.then((_) {
277 fail('Expected error completion');
278 }, onError: (error) {
279 expect(callbackInvoked, isFalse);
280 expect(error, new isInstanceOf<FutureCanceledError>());
281 callbackInvoked = true;
282 });
283 // The callback should be deferred to a microtask.
284 expect(callbackInvoked, isFalse);
285 expect(completer.isCompleted, isFalse);
286 return pumpEventQueue().then((_) {
287 expect(callbackInvoked, isTrue);
288 expect(completer.isCompleted, isFalse);
289 expect(cancelCount, 1);
290 });
291 }
292
293 Future test_cancel_after_chaining() {
294 bool callbackInvoked = false;
295 completer.future.then((_) {
296 fail('Expected error completion');
297 }, onError: (error) {
298 expect(callbackInvoked, isFalse);
299 expect(error, new isInstanceOf<FutureCanceledError>());
300 callbackInvoked = true;
301 });
302 expect(cancelCount, 0);
303 completer.future.cancel();
304 // The cancel callback should have been invoked immediately.
305 expect(cancelCount, 1);
306 // But the completer should remain in the "not completed" state.
307 expect(completer.isCompleted, isFalse);
308 // The callback should be deferred to a microtask.
309 expect(callbackInvoked, isFalse);
310 return pumpEventQueue().then((_) {
311 expect(callbackInvoked, isTrue);
312 expect(completer.isCompleted, isFalse);
313 expect(cancelCount, 1);
314 });
315 }
316
317 Future test_cancel_after_complete() {
318 Object obj = new Object();
319 completer.complete(obj);
320 completer.future.cancel();
321 // The cancel callback should not have been invoked, because it was too
322 // late to cancel.
323 expect(cancelCount, 0);
324 // Make sure the future still completes with the object.
325 return completer.future.then((result) {
326 expect(result, same(obj));
327 // And make sure nothing else happens.
328 }).then((_) => pumpEventQueue()).then((_) {
329 expect(completer.isCompleted, isTrue);
330 expect(cancelCount, 0);
331 });
332 }
333
334 Future test_complete_after_cancel() {
335 completer.future.cancel();
336 // The cancel callback should have been invoked immediately.
337 expect(cancelCount, 1);
338 // Completing should have no effect other than to set the isCompleted
339 // flag.
340 expect(completer.isCompleted, isFalse);
341 Object obj = new Object();
342 completer.complete(obj);
343 expect(completer.isCompleted, isTrue);
344 // Make sure the future still completer with error.
345 return completer.future.then((_) {
346 fail('Expected error completion');
347 }, onError: (error) {
348 expect(error, new isInstanceOf<FutureCanceledError>());
349 // And make sure nothing else happens.
350 }).then((_) => pumpEventQueue()).then((_) {
351 expect(completer.isCompleted, isTrue);
352 expect(cancelCount, 1);
353 });
354 }
355
356 Future test_completeError_after_cancel() {
357 completer.future.cancel();
358 // The cancel callback should have been invoked immediately.
359 expect(cancelCount, 1);
360 // Completing should have no effect other than to set the isCompleted
361 // flag.
362 expect(completer.isCompleted, isFalse);
363 Object obj = new Object();
364 completer.completeError(obj);
365 expect(completer.isCompleted, isTrue);
366 // Make sure the future still completes with error.
367 return completer.future.then((_) {
368 fail('Expected error completion');
369 }, onError: (error) {
370 expect(error, new isInstanceOf<FutureCanceledError>());
371 // And make sure nothing else happens.
372 }).then((_) => pumpEventQueue()).then((_) {
373 expect(completer.isCompleted, isTrue);
374 expect(cancelCount, 1);
375 });
376 }
377
378 Future test_cancel_after_cancel() {
379 // It is permissible to cancel multiple times, but only the first
380 // cancellation has any effect.
381 expect(cancelCount, 0);
382 completer.future.cancel();
383 expect(cancelCount, 1);
384 completer.future.cancel();
385 expect(cancelCount, 1);
386 // Make sure the future still completes with error.
387 return completer.future.then((_) {
388 fail('Expected error completion');
389 }, onError: (error) {
390 expect(error, new isInstanceOf<FutureCanceledError>());
391 // And make sure nothing else happens.
392 }).then((_) => pumpEventQueue()).then((_) {
393 expect(completer.isCompleted, isFalse);
394 expect(cancelCount, 1);
395 });
396 }
397 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698