Add the ability to abort a scheduled test.

Review URL: https://codereview.chromium.org//12753005

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@20056 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
nweiz@google.com 2013-03-14 22:37:41 +00:00
parent ab0ead6b50
commit 6a22d28a86
2 changed files with 105 additions and 0 deletions

View file

@ -157,6 +157,21 @@ class Schedule {
});
}
/// Stop the current [TaskQueue] after the current task and any out-of-band
/// tasks stop executing. If this is called before [this] has started running,
/// no tasks in the [tasks] queue will be run.
///
/// This won't cause an error, but any errors that are otherwise signaled will
/// still cause the test to fail.
void abort() {
if (_state == ScheduleState.DONE) {
throw new StateError("Called abort() after the schedule has finished "
"running.");
}
currentQueue._abort();
}
/// Signals that an out-of-band error has occurred. Using [wrapAsync] along
/// with `throw` is usually preferable to calling this directly.
///
@ -342,6 +357,9 @@ class TaskQueue {
/// [this].
int _totalCallbacks = 0;
/// Whether to stop running after the current task.
bool _aborted = false;
// TODO(nweiz): make this a read-only view when issue 8321 is fixed.
/// The descriptions of all callbacks that are blocking the completion of
/// [this].
@ -418,6 +436,7 @@ class TaskQueue {
return Future.forEach(_contents, (task) {
_schedule._currentTask = task;
if (_error != null) throw _error;
if (_aborted) return;
_taskFuture = new SubstituteFuture(task.fn());
return _taskFuture.whenComplete(() {
@ -451,6 +470,13 @@ class TaskQueue {
});
}
/// Stops this queue after the current task and any out-of-band callbacks
/// finish running.
void _abort() {
assert(_schedule.state == ScheduleState.SET_UP || isRunning);
_aborted = true;
}
/// Returns a function wrapping [fn] that pipes any errors into the schedule
/// chain. This will also block [this] from completing until the returned
/// function has been called. It's used to ensure that out-of-band callbacks

View file

@ -1359,4 +1359,83 @@ void main() {
expect(errors.map((e) => e.error), equals(['error']));
});
}, passing: ['test 2']);
expectTestsPass("aborting the schedule before it's started running should "
"cause no tasks to be run", () {
test('test', () {
schedule(() {
throw 'error';
});
currentSchedule.abort();
});
});
expectTestsPass("aborting the schedule while it's running should stop future "
"tasks from running", () {
test('test', () {
schedule(currentSchedule.abort);
schedule(() {
throw 'error';
});
});
});
expectTestsPass("aborting the schedule while it's running shouldn't stop "
"tasks in other queues from running", () {
var onCompleteRun = false;
test('test 1', () {
schedule(currentSchedule.abort);
currentSchedule.onComplete.schedule(() {
onCompleteRun = true;
});
});
test('test 2', () {
expect(onCompleteRun, isTrue);
});
});
expectTestsPass("aborting the schedule while it's running shouldn't stop "
"out-of-band callbacks", () {
test('test', () {
var outOfBandFinished = false;
schedule(() {
wrapFuture(pumpEventQueue().then((_) {
outOfBandFinished = true;
}));
currentSchedule.abort();
});
currentSchedule.onComplete.schedule(() {
expect(outOfBandFinished, isTrue);
});
});
});
expectTestsPass("aborting the schedule in a non-tasks queue should stop "
"future tasks from running", () {
test('test', () {
currentSchedule.onComplete.schedule(() {
currentSchedule.abort();
});
currentSchedule.onComplete.schedule(() {
throw 'error';
});
});
});
expectTestsFail("aborting the schedule after an out-of-band error should "
"still surface the error", () {
test('test', () {
schedule(() {
currentSchedule.signalError('error');
currentSchedule.abort();
});
});
});
}