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

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

Issue 179993007: Make scheduled_test play nicer with plain unittest tests. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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
« no previous file with comments | « no previous file | pkg/scheduled_test/test/unittest_compatibility_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // TODO(nweiz): Add support for calling [schedule] while the schedule is already 5 // TODO(nweiz): Add support for calling [schedule] while the schedule is already
6 // running. 6 // running.
7 // TODO(nweiz): Port the non-Pub-specific scheduled test libraries from Pub. 7 // TODO(nweiz): Port the non-Pub-specific scheduled test libraries from Pub.
8 /// A package for writing readable tests of asynchronous behavior. 8 /// A package for writing readable tests of asynchronous behavior.
9 /// 9 ///
10 /// ## Installing ## 10 /// ## Installing ##
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 void test(String description, void body()) => 221 void test(String description, void body()) =>
222 _test(description, body, unittest.test); 222 _test(description, body, unittest.test);
223 223
224 /// Creates a new test case with the given description and body that will be the 224 /// Creates a new test case with the given description and body that will be the
225 /// only test run in this file. This has the same semantics as 225 /// only test run in this file. This has the same semantics as
226 /// [unittest.solo_test]. 226 /// [unittest.solo_test].
227 void solo_test(String description, void body()) => 227 void solo_test(String description, void body()) =>
228 _test(description, body, unittest.solo_test); 228 _test(description, body, unittest.solo_test);
229 229
230 void _test(String description, void body(), Function testFn) { 230 void _test(String description, void body(), Function testFn) {
231 _ensureInitialized(); 231 unittest.ensureInitialized();
232 _ensureSetUpForTopLevel(); 232 _ensureSetUpForTopLevel();
233 testFn(description, () { 233 testFn(description, () {
234 var completer = new Completer(); 234 var completer = new Completer();
235 235
236 Chain.capture(() { 236 Chain.capture(() {
237 _currentSchedule = new Schedule(); 237 _currentSchedule = new Schedule();
238 return currentSchedule.run(() { 238 return currentSchedule.run(() {
239 if (_setUpFn != null) _setUpFn(); 239 if (_setUpFn != null) _setUpFn();
240 body(); 240 body();
241 }).catchError((error, stackTrace) { 241 }).catchError((error, stackTrace) {
(...skipping 11 matching lines...) Expand all
253 }); 253 });
254 } 254 }
255 255
256 /// Whether or not the tests currently being defined are in a group. This is 256 /// Whether or not the tests currently being defined are in a group. This is
257 /// only true when defining tests, not when executing them. 257 /// only true when defining tests, not when executing them.
258 bool _inGroup = false; 258 bool _inGroup = false;
259 259
260 /// Creates a new named group of tests. This has the same semantics as 260 /// Creates a new named group of tests. This has the same semantics as
261 /// [unittest.group]. 261 /// [unittest.group].
262 void group(String description, void body()) { 262 void group(String description, void body()) {
263 _ensureInitialized(); 263 unittest.ensureInitialized();
264 _ensureSetUpForTopLevel(); 264 _ensureSetUpForTopLevel();
265 unittest.group(description, () { 265 unittest.group(description, () {
266 var wasInGroup = _inGroup; 266 var wasInGroup = _inGroup;
267 _inGroup = true; 267 _inGroup = true;
268 body(); 268 body();
269 _inGroup = wasInGroup; 269 _inGroup = wasInGroup;
270 }); 270 });
271 } 271 }
272 272
273 /// Schedules a task, [fn], to run asynchronously as part of the main task queue 273 /// Schedules a task, [fn], to run asynchronously as part of the main task queue
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 void _ensureSetUpForTopLevel() { 309 void _ensureSetUpForTopLevel() {
310 if (_inGroup || _setUpForTopLevel) return; 310 if (_inGroup || _setUpForTopLevel) return;
311 _setUpScheduledTest(); 311 _setUpScheduledTest();
312 } 312 }
313 313
314 /// Registers callbacks for [unittest.setUp] and [unittest.tearDown] that set up 314 /// Registers callbacks for [unittest.setUp] and [unittest.tearDown] that set up
315 /// and tear down the scheduled test infrastructure. 315 /// and tear down the scheduled test infrastructure.
316 void _setUpScheduledTest([void setUpFn()]) { 316 void _setUpScheduledTest([void setUpFn()]) {
317 if (!_inGroup) { 317 if (!_inGroup) {
318 _setUpForTopLevel = true; 318 _setUpForTopLevel = true;
319 var oldWrapAsync = unittest.wrapAsync;
319 unittest.setUp(() { 320 unittest.setUp(() {
320 if (currentSchedule != null) { 321 if (currentSchedule != null) {
321 throw new StateError('There seems to be another scheduled test ' 322 throw new StateError('There seems to be another scheduled test '
322 'still running.'); 323 'still running.');
323 } 324 }
325
326 unittest.wrapAsync = (f, [description]) {
327 // It's possible that this setup is run before a vanilla unittest test
328 // if [unittest.test] is run in the same context as
329 // [scheduled_test.test]. In that case, [currentSchedule] will never be
330 // set and we should forward to the [unittest.wrapAsync].
331 if (currentSchedule == null) return oldWrapAsync(f, description);
332 return currentSchedule.wrapAsync(f, description);
333 };
334
324 if (_setUpFn != null) { 335 if (_setUpFn != null) {
325 var parentFn = _setUpFn; 336 var parentFn = _setUpFn;
326 _setUpFn = () { parentFn(); setUpFn(); }; 337 _setUpFn = () { parentFn(); setUpFn(); };
327 } else { 338 } else {
328 _setUpFn = setUpFn; 339 _setUpFn = setUpFn;
329 } 340 }
330 }); 341 });
331 342
332 unittest.tearDown(() { 343 unittest.tearDown(() {
344 unittest.wrapAsync = oldWrapAsync;
333 _currentSchedule = null; 345 _currentSchedule = null;
334 _setUpFn = null; 346 _setUpFn = null;
335 }); 347 });
336 } else { 348 } else {
337 unittest.setUp(() { 349 unittest.setUp(() {
338 if (_setUpFn != null) { 350 if (_setUpFn != null) {
339 var parentFn = _setUpFn; 351 var parentFn = _setUpFn;
340 _setUpFn = () { parentFn(); setUpFn(); }; 352 _setUpFn = () { parentFn(); setUpFn(); };
341 } else { 353 } else {
342 _setUpFn = setUpFn; 354 _setUpFn = setUpFn;
343 } 355 }
344 }); 356 });
345 } 357 }
346 } 358 }
347 359
348 /// Ensures that the global configuration for `scheduled_test` has been
349 /// initialized.
350 void _ensureInitialized() {
351 unittest.ensureInitialized();
352 unittest.wrapAsync = (f, [description]) {
353 if (currentSchedule == null) {
354 throw new StateError("Unexpected call to wrapAsync with no current "
355 "schedule.");
356 }
357
358 return currentSchedule.wrapAsync(f, description);
359 };
360 }
361
362 /// Like [wrapAsync], this ensures that the current task queue waits for 360 /// Like [wrapAsync], this ensures that the current task queue waits for
363 /// out-of-band asynchronous code, and that errors raised in that code are 361 /// out-of-band asynchronous code, and that errors raised in that code are
364 /// handled correctly. However, [wrapFuture] wraps a [Future] chain rather than 362 /// handled correctly. However, [wrapFuture] wraps a [Future] chain rather than
365 /// a single callback. 363 /// a single callback.
366 /// 364 ///
367 /// The returned [Future] completes to the same value or error as [future]. 365 /// The returned [Future] completes to the same value or error as [future].
368 /// 366 ///
369 /// [description] provides an optional description of the future, which is 367 /// [description] provides an optional description of the future, which is
370 /// used when generating error messages. 368 /// used when generating error messages.
371 Future wrapFuture(Future future, [String description]) { 369 Future wrapFuture(Future future, [String description]) {
372 if (currentSchedule == null) { 370 if (currentSchedule == null) {
373 throw new StateError("Unexpected call to wrapFuture with no current " 371 throw new StateError("Unexpected call to wrapFuture with no current "
374 "schedule."); 372 "schedule.");
375 } 373 }
376 374
377 return currentSchedule.wrapFuture(future, description); 375 return currentSchedule.wrapFuture(future, description);
378 } 376 }
OLDNEW
« no previous file with comments | « no previous file | pkg/scheduled_test/test/unittest_compatibility_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698