| Index: lib/src/runner/engine.dart
|
| diff --git a/lib/src/runner/engine.dart b/lib/src/runner/engine.dart
|
| index c93e793a2de1ce102f06573e1a309348e9caee91..c30333d5e8160687554f917cb4798973e29a049e 100644
|
| --- a/lib/src/runner/engine.dart
|
| +++ b/lib/src/runner/engine.dart
|
| @@ -11,9 +11,12 @@ import 'package:async/async.dart' hide Result;
|
| import 'package:collection/collection.dart';
|
| import 'package:pool/pool.dart';
|
|
|
| +import '../backend/group.dart';
|
| +import '../backend/invoker.dart';
|
| import '../backend/live_test.dart';
|
| import '../backend/live_test_controller.dart';
|
| import '../backend/state.dart';
|
| +import '../backend/suite_entry.dart';
|
| import '../backend/test.dart';
|
| import 'load_suite.dart';
|
| import 'runner_suite.dart';
|
| @@ -24,7 +27,7 @@ import 'runner_suite.dart';
|
| /// have been provided, the user should close [suiteSink] to indicate this.
|
| /// [run] won't terminate until [suiteSink] is closed. Suites will be run in the
|
| /// order they're provided to [suiteSink]. Tests within those suites will
|
| -/// likewise be run in the order of [Suite.tests].
|
| +/// likewise be run in the order they're declared.
|
| ///
|
| /// The current status of every test is visible via [liveTests]. [onTestStarted]
|
| /// can also be used to be notified when a test is about to be run.
|
| @@ -195,55 +198,8 @@ class Engine {
|
| }
|
|
|
| await _runPool.withResource(() async {
|
| - if (_closed) return null;
|
| -
|
| - // TODO(nweiz): Use a real for loop when issue 23394 is fixed.
|
| - await Future.forEach(suite.tests, (test) async {
|
| - if (_closed) return;
|
| -
|
| - var liveTest = test.metadata.skip
|
| - ? _skippedTest(suite, test)
|
| - : test.load(suite);
|
| - _liveTests.add(liveTest);
|
| - _active.add(liveTest);
|
| -
|
| - // If there were no active non-load tests, the current active test
|
| - // would have been a load test. In that case, remove it, since now we
|
| - // have a non-load test to add.
|
| - if (_active.isNotEmpty && _active.first.suite is LoadSuite) {
|
| - _liveTests.remove(_active.removeFirst());
|
| - }
|
| -
|
| - liveTest.onStateChange.listen((state) {
|
| - if (state.status != Status.complete) return;
|
| - _active.remove(liveTest);
|
| -
|
| - // If we're out of non-load tests, surface a load test.
|
| - if (_active.isEmpty && _activeLoadTests.isNotEmpty) {
|
| - _active.add(_activeLoadTests.first);
|
| - _liveTests.add(_activeLoadTests.first);
|
| - }
|
| -
|
| - if (state.result != Result.success) {
|
| - _passed.remove(liveTest);
|
| - _failed.add(liveTest);
|
| - } else if (liveTest.test.metadata.skip) {
|
| - _skipped.add(liveTest);
|
| - } else {
|
| - _passed.add(liveTest);
|
| - }
|
| - });
|
| -
|
| - _onTestStartedController.add(liveTest);
|
| -
|
| - // First, schedule a microtask to ensure that [onTestStarted] fires
|
| - // before the first [LiveTest.onStateChange] event. Once the test
|
| - // finishes, use [new Future] to do a coarse-grained event loop pump
|
| - // to avoid starving non-microtask events.
|
| - await new Future.microtask(liveTest.run);
|
| - await new Future(() {});
|
| - });
|
| -
|
| + if (_closed) return;
|
| + await _runEntries(suite, suite.entries);
|
| loadResource.allowRelease(() => suite.close());
|
| });
|
| }));
|
| @@ -252,8 +208,25 @@ class Engine {
|
| return success;
|
| }
|
|
|
| - /// Returns a dummy [LiveTest] for a test marked as "skip".
|
| - LiveTest _skippedTest(RunnerSuite suite, Test test) {
|
| + /// Runs all the entries in [entries] in sequence.
|
| + Future _runEntries(RunnerSuite suite, List<SuiteEntry> entries) async {
|
| + for (var entry in entries) {
|
| + if (_closed) return;
|
| +
|
| + if (entry.metadata.skip) {
|
| + await _runLiveTest(_skippedTest(suite, entry));
|
| + } else if (entry is Test) {
|
| + await _runLiveTest(entry.load(suite));
|
| + } else {
|
| + var group = entry as Group;
|
| + await _runEntries(suite, group.entries);
|
| + }
|
| + }
|
| + }
|
| +
|
| + /// Returns a dummy [LiveTest] for a test or group marked as "skip".
|
| + LiveTest _skippedTest(RunnerSuite suite, SuiteEntry entry) {
|
| + var test = new LocalTest(entry.name, entry.metadata, () {});
|
| var controller;
|
| controller = new LiveTestController(suite, test, () {
|
| controller.setState(const State(Status.running, Result.success));
|
| @@ -263,11 +236,53 @@ class Engine {
|
| return controller.liveTest;
|
| }
|
|
|
| + /// Runs [liveTest].
|
| + Future _runLiveTest(LiveTest liveTest) async {
|
| + _liveTests.add(liveTest);
|
| + _active.add(liveTest);
|
| +
|
| + // If there were no active non-load tests, the current active test would
|
| + // have been a load test. In that case, remove it, since now we have a
|
| + // non-load test to add.
|
| + if (_active.isNotEmpty && _active.first.suite is LoadSuite) {
|
| + _liveTests.remove(_active.removeFirst());
|
| + }
|
| +
|
| + liveTest.onStateChange.listen((state) {
|
| + if (state.status != Status.complete) return;
|
| + _active.remove(liveTest);
|
| +
|
| + // If we're out of non-load tests, surface a load test.
|
| + if (_active.isEmpty && _activeLoadTests.isNotEmpty) {
|
| + _active.add(_activeLoadTests.first);
|
| + _liveTests.add(_activeLoadTests.first);
|
| + }
|
| +
|
| + if (state.result != Result.success) {
|
| + _passed.remove(liveTest);
|
| + _failed.add(liveTest);
|
| + } else if (liveTest.test.metadata.skip) {
|
| + _skipped.add(liveTest);
|
| + } else {
|
| + _passed.add(liveTest);
|
| + }
|
| + });
|
| +
|
| + _onTestStartedController.add(liveTest);
|
| +
|
| + // First, schedule a microtask to ensure that [onTestStarted] fires before
|
| + // the first [LiveTest.onStateChange] event. Once the test finishes, use
|
| + // [new Future] to do a coarse-grained event loop pump to avoid starving
|
| + // non-microtask events.
|
| + await new Future.microtask(liveTest.run);
|
| + await new Future(() {});
|
| + }
|
| +
|
| /// Adds listeners for [suite].
|
| ///
|
| /// Load suites have specific logic apart from normal test suites.
|
| Future<RunnerSuite> _addLoadSuite(LoadSuite suite) async {
|
| - var liveTest = await suite.tests.single.load(suite);
|
| + var liveTest = await suite.test.load(suite);
|
|
|
| _activeLoadTests.add(liveTest);
|
|
|
|
|