| Index: pkg/scheduled_test/lib/src/task.dart
|
| diff --git a/pkg/scheduled_test/lib/src/task.dart b/pkg/scheduled_test/lib/src/task.dart
|
| index 0819bd0e0f14a000f16d4d36cdb3a4b0574f0bba..8a34f10228581a66f3fdddea9c8ac5cb641e6710 100644
|
| --- a/pkg/scheduled_test/lib/src/task.dart
|
| +++ b/pkg/scheduled_test/lib/src/task.dart
|
| @@ -44,6 +44,10 @@ class Task {
|
| /// The body of the task.
|
| TaskBody fn;
|
|
|
| + /// The current state of [this].
|
| + TaskState get state => _state;
|
| + var _state = TaskState.WAITING;
|
| +
|
| /// The identifier of the task. For top-level tasks, this is the index of the
|
| /// task within [queue]; for nested tasks, this is the index within
|
| /// [parent.children]. It's used for debugging when [description] isn't
|
| @@ -63,6 +67,11 @@ class Task {
|
|
|
| Task._(fn(), this.description, this.queue, this.parent, this._id) {
|
| this.fn = () {
|
| + if (state != TaskState.WAITING) {
|
| + throw new StateError("Can't run $state task '$this'.");
|
| + }
|
| +
|
| + _state = TaskState.RUNNING;
|
| var future = new Future.immediate(null).then((_) => fn())
|
| .whenComplete(() {
|
| if (_childGroup == null || _childGroup.completed) return;
|
| @@ -72,9 +81,18 @@ class Task {
|
| return future;
|
| };
|
|
|
| - // Make sure any error thrown by fn isn't top-leveled by virtue of being
|
| - // passed to the result future.
|
| - result.catchError((_) {});
|
| + // If the parent queue experiences an error before this task has started
|
| + // running, pipe that error out through [result]. This ensures that we don't
|
| + // get deadlocked by something like `expect(schedule(...), completes)`.
|
| + queue.onTasksComplete.catchError((e) {
|
| + if (state == TaskState.WAITING) _resultCompleter.completeError(e);
|
| + });
|
| +
|
| + // catchError makes sure any error thrown by fn isn't top-leveled by virtue
|
| + // of being passed to the result future.
|
| + result.whenComplete(() {
|
| + _state = TaskState.DONE;
|
| + }).catchError((_) {});
|
| }
|
|
|
| /// Run [fn] as a child of this task. Returns a Future that will complete with
|
| @@ -98,3 +116,22 @@ class Task {
|
| /// Returns a detailed representation of [queue] with this task highlighted.
|
| String generateTree() => queue.generateTree(this);
|
| }
|
| +
|
| +/// An enum of states for a [Task].
|
| +class TaskState {
|
| + /// The task is waiting to be run.
|
| + static const WAITING = const TaskState._("WAITING");
|
| +
|
| + /// The task is currently running.
|
| + static const RUNNING = const TaskState._("RUNNING");
|
| +
|
| + /// The task has finished running, either successfully or with an error.
|
| + static const DONE = const TaskState._("DONE");
|
| +
|
| + /// The name of the state.
|
| + final String name;
|
| +
|
| + const TaskState._(this.name);
|
| +
|
| + String toString() => name;
|
| +}
|
|
|