| OLD | NEW |
| 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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 /// [pkg]: http://pub.dartlang.org/packages/scheduled_test | 189 /// [pkg]: http://pub.dartlang.org/packages/scheduled_test |
| 190 library scheduled_test; | 190 library scheduled_test; |
| 191 | 191 |
| 192 import 'dart:async'; | 192 import 'dart:async'; |
| 193 | 193 |
| 194 import 'package:stack_trace/stack_trace.dart'; | 194 import 'package:stack_trace/stack_trace.dart'; |
| 195 import 'package:unittest/unittest.dart' as unittest; | 195 import 'package:unittest/unittest.dart' as unittest; |
| 196 | 196 |
| 197 import 'src/schedule.dart'; | 197 import 'src/schedule.dart'; |
| 198 import 'src/schedule_error.dart'; | 198 import 'src/schedule_error.dart'; |
| 199 import 'src/utils.dart'; |
| 199 | 200 |
| 200 export 'package:unittest/unittest.dart' hide | 201 export 'package:unittest/unittest.dart' hide |
| 201 test, solo_test, group, setUp, tearDown, completes, completion; | 202 test, solo_test, group, setUp, tearDown, completes, completion; |
| 202 | 203 |
| 203 export 'src/schedule.dart'; | 204 export 'src/schedule.dart'; |
| 204 export 'src/schedule_error.dart'; | 205 export 'src/schedule_error.dart'; |
| 205 export 'src/scheduled_future_matchers.dart'; | 206 export 'src/scheduled_future_matchers.dart'; |
| 206 export 'src/task.dart'; | 207 export 'src/task.dart'; |
| 207 | 208 |
| 208 /// The [Schedule] for the current test. This is used to add new tasks and | 209 /// The [Schedule] for the current test. This is used to add new tasks and |
| 209 /// inspect the state of the schedule. | 210 /// inspect the state of the schedule. |
| 210 /// | 211 /// |
| 211 /// This is `null` when there's no test currently running. | 212 /// This is `null` when there's no test currently running. |
| 212 Schedule get currentSchedule => _currentSchedule; | 213 Schedule get currentSchedule => _currentSchedule; |
| 213 Schedule _currentSchedule; | 214 Schedule _currentSchedule; |
| 214 | 215 |
| 215 /// The user-provided setUp function. This is set for each test during | 216 /// The user-provided setUp function. This is set for each test during |
| 216 /// `unittest.setUp`. | 217 /// `unittest.setUp`. |
| 217 Function _setUpFn; | 218 Function _setUpFn; |
| 218 | 219 |
| 219 /// Creates a new test case with the given description and body. This has the | 220 /// Creates a new test case with the given description and body. |
| 220 /// same semantics as [unittest.test]. | 221 /// |
| 221 void test(String description, void body()) => | 222 /// This has the same semantics as [unittest.test]. |
| 223 /// |
| 224 /// If [body] returns a [Future], that future will automatically be wrapped with |
| 225 /// [wrapFuture]. |
| 226 void test(String description, Future body()) => |
| 222 _test(description, body, unittest.test); | 227 _test(description, body, unittest.test); |
| 223 | 228 |
| 224 /// Creates a new test case with the given description and body that will be the | 229 /// 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 | 230 /// only test run in this file. |
| 226 /// [unittest.solo_test]. | 231 /// |
| 227 void solo_test(String description, void body()) => | 232 /// This has the same semantics as [unittest.solo_test]. |
| 233 /// |
| 234 /// If [body] returns a [Future], that future will automatically be wrapped with |
| 235 /// [wrapFuture]. |
| 236 void solo_test(String description, Future body()) => |
| 228 _test(description, body, unittest.solo_test); | 237 _test(description, body, unittest.solo_test); |
| 229 | 238 |
| 230 void _test(String description, void body(), Function testFn) { | 239 void _test(String description, Future body(), Function testFn) { |
| 240 maybeWrapFuture(future, description) { |
| 241 if (future != null) wrapFuture(future, description); |
| 242 } |
| 243 |
| 231 unittest.ensureInitialized(); | 244 unittest.ensureInitialized(); |
| 232 _ensureSetUpForTopLevel(); | 245 _ensureSetUpForTopLevel(); |
| 233 testFn(description, () { | 246 testFn(description, () { |
| 234 var completer = new Completer(); | 247 var completer = new Completer(); |
| 235 | 248 |
| 236 Chain.capture(() { | 249 Chain.capture(() { |
| 237 _currentSchedule = new Schedule(); | 250 _currentSchedule = new Schedule(); |
| 238 return currentSchedule.run(() { | 251 return currentSchedule.run(() { |
| 239 if (_setUpFn != null) _setUpFn(); | 252 if (_setUpFn != null) maybeWrapFuture(_setUpFn(), "set up"); |
| 240 body(); | 253 maybeWrapFuture(body(), "test body"); |
| 241 }).catchError((error, stackTrace) { | 254 }).catchError((error, stackTrace) { |
| 242 if (error is ScheduleError) { | 255 if (error is ScheduleError) { |
| 243 assert(error.schedule.errors.contains(error)); | 256 assert(error.schedule.errors.contains(error)); |
| 244 assert(error.schedule == currentSchedule); | 257 assert(error.schedule == currentSchedule); |
| 245 unittest.registerException(error.schedule.errorString()); | 258 unittest.registerException(error.schedule.errorString()); |
| 246 } else { | 259 } else { |
| 247 unittest.registerException(error, new Chain.forTrace(stackTrace)); | 260 unittest.registerException(error, new Chain.forTrace(stackTrace)); |
| 248 } | 261 } |
| 249 }).then(completer.complete); | 262 }).then(completer.complete); |
| 250 }, onError: (error, chain) => currentSchedule.signalError(error, chain)); | 263 }, onError: (error, chain) => currentSchedule.signalError(error, chain)); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 /// [description] provides an optional description of the future, which is | 380 /// [description] provides an optional description of the future, which is |
| 368 /// used when generating error messages. | 381 /// used when generating error messages. |
| 369 Future wrapFuture(Future future, [String description]) { | 382 Future wrapFuture(Future future, [String description]) { |
| 370 if (currentSchedule == null) { | 383 if (currentSchedule == null) { |
| 371 throw new StateError("Unexpected call to wrapFuture with no current " | 384 throw new StateError("Unexpected call to wrapFuture with no current " |
| 372 "schedule."); | 385 "schedule."); |
| 373 } | 386 } |
| 374 | 387 |
| 375 return currentSchedule.wrapFuture(future, description); | 388 return currentSchedule.wrapFuture(future, description); |
| 376 } | 389 } |
| OLD | NEW |