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

Unified Diff: lib/src/executable.dart

Issue 1187103004: Allow Suites to be added to an Engine over time. (Closed) Base URL: git@github.com:dart-lang/test@master
Patch Set: Created 5 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | lib/src/runner/browser/browser.dart » ('j') | lib/src/runner/browser/content_shell.dart » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/executable.dart
diff --git a/lib/src/executable.dart b/lib/src/executable.dart
index f7753a0f612d84e537cd4d9f4c5d2fd956a182da..bf619b2af8e314702745953d9131994c50dc946b 100644
--- a/lib/src/executable.dart
+++ b/lib/src/executable.dart
@@ -17,12 +17,13 @@ import 'package:yaml/yaml.dart';
import 'backend/metadata.dart';
import 'backend/test_platform.dart';
-import 'runner/reporter/compact.dart';
-import 'runner/reporter/expanded.dart';
+import 'runner/engine.dart';
import 'runner/application_exception.dart';
import 'runner/load_exception.dart';
import 'runner/load_exception_suite.dart';
import 'runner/loader.dart';
+import 'runner/reporter/compact.dart';
+import 'runner/reporter/expanded.dart';
import 'util/exit_codes.dart' as exit_codes;
import 'util/io.dart';
import 'utils.dart';
@@ -166,15 +167,6 @@ transformers:
}
}
- var metadata = new Metadata(verboseTrace: options["verbose-trace"]);
- var platforms = options["platform"].map(TestPlatform.find);
- var loader = new Loader(platforms,
- pubServeUrl: pubServeUrl,
- packageRoot: options["package-root"],
- color: color,
- metadata: metadata,
- jsTrace: options["js-trace"]);
-
var concurrency = _defaultConcurrency;
if (options["concurrency"] != null) {
try {
@@ -198,83 +190,52 @@ transformers:
paths = ["test"];
}
+ var pattern;
+ if (options["name"] != null) {
+ if (options["plain-name"] != null) {
+ _printUsage("--name and --plain-name may not both be passed.");
+ exitCode = exit_codes.data;
+ return;
+ }
+ pattern = new RegExp(options["name"]);
+ } else if (options["plain-name"] != null) {
+ pattern = options["plain-name"];
+ }
+
+ var metadata = new Metadata(verboseTrace: options["verbose-trace"]);
+ var platforms = options["platform"].map(TestPlatform.find);
+ var loader = new Loader(platforms,
+ pubServeUrl: pubServeUrl,
+ packageRoot: options["package-root"],
+ color: color,
+ metadata: metadata,
+ jsTrace: options["js-trace"]);
+
var signalSubscription;
- var closed = false;
signalSubscription = _signals.listen((_) {
signalSubscription.cancel();
- closed = true;
loader.close();
});
try {
- var suites = await mergeStreams(paths.map((path) {
- if (new Directory(path).existsSync()) return loader.loadDir(path);
- if (new File(path).existsSync()) return loader.loadFile(path);
- return new Stream.fromFuture(new Future.error(
- new LoadException(path, 'Does not exist.'),
- new Trace.current()));
- })).transform(new StreamTransformer.fromHandlers(
- handleError: (error, stackTrace, sink) {
- if (error is! LoadException) {
- sink.addError(error, stackTrace);
- } else {
- sink.add(new LoadExceptionSuite(error, stackTrace));
- }
- })).toList();
-
- if (closed) return;
- suites = flatten(suites);
+ var engine = new Engine(concurrency: concurrency);
- var pattern;
- if (options["name"] != null) {
- if (options["plain-name"] != null) {
- _printUsage("--name and --plain-name may not both be passed.");
- exitCode = exit_codes.data;
- return;
- }
- pattern = new RegExp(options["name"]);
- } else if (options["plain-name"] != null) {
- pattern = options["plain-name"];
- }
-
- if (pattern != null) {
- suites = suites.map((suite) {
- // Don't ever filter out load errors.
- if (suite is LoadExceptionSuite) return suite;
- return suite.change(
- tests: suite.tests.where((test) => test.name.contains(pattern)));
- }).toList();
-
- if (suites.every((suite) => suite.tests.isEmpty)) {
- stderr.write('No tests match ');
-
- if (pattern is RegExp) {
- stderr.writeln('regular expression "${pattern.pattern}".');
- } else {
- stderr.writeln('"$pattern".');
- }
- exitCode = exit_codes.data;
- return;
- }
- }
+ var watch = options["reporter"] == "compact"
+ ? CompactReporter.watch
+ : ExpandedReporter.watch;
- var reporter = options["reporter"] == "compact"
- ? new CompactReporter(
- flatten(suites),
- concurrency: concurrency,
- color: color,
- verboseTrace: options["verbose-trace"])
- : new ExpandedReporter(
- flatten(suites),
- concurrency: concurrency,
- color: color,
- verboseTrace: options["verbose-trace"]);
+ watch(
+ engine,
+ color: color,
+ verboseTrace: options["verbose-trace"],
+ printPath: paths.length > 1 ||
+ new Directory(paths.single).existsSync(),
+ printPlatform: platforms.length > 1);
// Override the signal handler to close [reporter]. [loader] will still be
// closed in the [whenComplete] below.
- signalSubscription.onData((_) {
+ signalSubscription.onData((_) async {
signalSubscription.cancel();
- closed = true;
// Wait a bit to print this message, since printing it eagerly looks weird
// if the tests then finish immediately.
@@ -286,15 +247,35 @@ transformers:
print("Press Control-C again to terminate immediately.");
});
- reporter.close().then((_) => timer.cancel());
+ await engine.close();
+ timer.cancel();
+ await loader.close();
});
try {
- var success = await reporter.run();
- exitCode = success ? 0 : 1;
+ var results = await Future.wait([
+ _loadSuites(paths, pattern, loader, engine),
+ engine.run()
+ ], eagerError: true);
+
+ // Explicitly check "== true" here because [engine.run] can return `null`
+ // if the engine was closed prematurely.
+ exitCode = results.last == true ? 0 : 1;
} finally {
signalSubscription.cancel();
- await reporter.close();
+ await engine.close();
+ }
+
+ if (engine.passed.length == 0 && engine.failed.length == 0 &&
+ engine.skipped.length == 0 && pattern != null) {
+ stderr.write('No tests match ');
+
+ if (pattern is RegExp) {
+ stderr.writeln('regular expression "${pattern.pattern}".');
+ } else {
+ stderr.writeln('"$pattern".');
+ }
+ exitCode = exit_codes.data;
}
} on ApplicationException catch (error) {
stderr.writeln(error.message);
@@ -313,6 +294,42 @@ transformers:
}
}
+/// Load the test suites in [paths] that match [pattern] and pass them to
+/// [engine].
+///
+/// This completes once all the tests have been added to the engine. It does not
+/// run the engine.
+Future _loadSuites(List<String> paths, Pattern pattern, Loader loader,
+ Engine engine) async {
+ var completer = new Completer();
+
+ mergeStreams(paths.map((path) {
+ if (new Directory(path).existsSync()) return loader.loadDir(path);
+ if (new File(path).existsSync()) return loader.loadFile(path);
+
+ return new Stream.fromFuture(new Future.error(
+ new LoadException(path, 'Does not exist.'),
+ new Trace.current()));
+ })).map((suite) {
+ if (pattern == null) return suite;
+ return suite.change(
+ tests: suite.tests.where((test) => test.name.contains(pattern)));
+ }).listen((suite) => engine.suiteSink.add(suite),
kevmoo 2015/06/17 22:20:04 consider using await async here – won't need a com
nweiz 2015/06/17 22:41:08 We can't use it here, because we need to intercept
+ onError: (error, stackTrace) {
+ if (error is LoadException) {
+ engine.suiteSink.add(new LoadExceptionSuite(error, stackTrace));
+ } else if (!completer.isCompleted) {
+ completer.completeError(error, stackTrace);
+ }
+ }, onDone: () => completer.complete());
+
+ await completer.future;
+
+ // Once we've loaded all the suites, notify the engine that no more will be
+ // coming.
+ engine.suiteSink.close();
+}
+
/// Print usage information for this command.
///
/// If [error] is passed, it's used in place of the usage message and the whole
« no previous file with comments | « no previous file | lib/src/runner/browser/browser.dart » ('j') | lib/src/runner/browser/content_shell.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698