Index: pkg/testing/lib/src/run_tests.dart |
diff --git a/pkg/testing/lib/src/run_tests.dart b/pkg/testing/lib/src/run_tests.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f351f678d5397008c765ea70e89e545c6a329fab |
--- /dev/null |
+++ b/pkg/testing/lib/src/run_tests.dart |
@@ -0,0 +1,205 @@ |
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE.md file. |
+ |
+library testing.run_tests; |
+ |
+import 'dart:async' show |
+ Future; |
+ |
+import 'dart:io' show |
+ Directory, |
+ File, |
+ FileSystemEntity; |
+ |
+import 'dart:io' as io show |
+ exitCode; |
+ |
+import 'dart:isolate' show |
+ Isolate; |
+ |
+import 'error_handling.dart' show |
+ withErrorHandling; |
+ |
+import 'test_root.dart' show |
+ TestRoot; |
+ |
+import 'zone_helper.dart' show |
+ runGuarded; |
+ |
+import 'log.dart' show |
+ enableVerboseOutput, |
+ isVerbose, |
+ logMessage, |
+ logSuiteComplete, |
+ logTestComplete; |
+ |
+import 'run.dart' show |
+ SuiteRunner, |
+ runProgram; |
+ |
+import 'suite.dart' show |
+ Suite; |
+ |
+class CommandLine { |
+ final Set<String> options; |
+ final List<String> arguments; |
+ |
+ CommandLine(this.options, this.arguments); |
+ |
+ bool get verbose => options.contains("--verbose") || options.contains("-v"); |
+ |
+ Set<String> get skip { |
+ return options.expand((String s) { |
+ const String prefix = "--skip="; |
+ if (!s.startsWith(prefix)) return const []; |
+ s = s.substring(prefix.length); |
+ return s.split(","); |
+ }).toSet(); |
+ } |
+ |
+ Map<String, String> get environment { |
+ Map<String, String> result = <String, String>{}; |
+ for (String option in options) { |
+ if (option.startsWith("-D")) { |
+ int equalIndex = option.indexOf("="); |
+ if (equalIndex != -1) { |
+ String key = option.substring(2, equalIndex); |
+ String value = option.substring(equalIndex + 1); |
+ result[key] = value; |
+ } |
+ } |
+ } |
+ return result; |
+ } |
+ |
+ Set<String> get selectedSuites { |
+ return selectors.map((String selector) { |
+ int index = selector.indexOf("/"); |
+ return index == -1 ? selector : selector.substring(0, index); |
+ }).toSet(); |
+ } |
+ |
+ Iterable<String> get selectors => arguments; |
+ |
+ Future<Uri> get configuration async { |
+ const String configPrefix = "--config="; |
+ List<String> configurationPaths = options |
+ .where((String option) => option.startsWith(configPrefix)) |
+ .map((String option) => option.substring(configPrefix.length)) |
+ .toList(); |
+ if (configurationPaths.length > 1) { |
+ return fail("Only one --config option is supported"); |
+ } |
+ String configurationPath; |
+ if (configurationPaths.length == 1) { |
+ configurationPath = configurationPaths.single; |
+ } else { |
+ configurationPath = "testing.json"; |
+ if (!await new File(configurationPath).exists()) { |
+ Directory test = new Directory("test"); |
+ if (await test.exists()) { |
+ List<FileSystemEntity> candiates = |
+ await test.list(recursive: true, followLinks: false) |
+ .where((FileSystemEntity entity) { |
+ return entity is File && |
+ entity.uri.path.endsWith("/testing.json"); |
+ }).toList(); |
+ switch (candiates.length) { |
+ case 0: |
+ return fail("Couldn't locate: '$configurationPath'."); |
+ |
+ case 1: |
+ configurationPath = candiates.single.path; |
+ break; |
+ |
+ default: |
+ return fail( |
+ "Usage: run_tests.dart [$configPrefix=configuration_file]\n" |
+ "Where configuration_file is one of:\n " |
+ "${candiates.map((File file) => file.path).join('\n ')}"); |
+ } |
+ } |
+ } |
+ } |
+ logMessage("Reading configuration file '$configurationPath'."); |
+ Uri configuration = |
+ await Isolate.resolvePackageUri(Uri.base.resolve(configurationPath)); |
+ if (configuration == null || |
+ !await new File.fromUri(configuration).exists()) { |
+ return fail("Couldn't locate: '$configurationPath'."); |
+ } |
+ return configuration; |
+ } |
+ |
+ static CommandLine parse(List<String> arguments) { |
+ int index = arguments.indexOf("--"); |
+ Set<String> options; |
+ if (index != -1) { |
+ options = new Set<String>.from(arguments.getRange(0, index - 1)); |
+ arguments = arguments.sublist(index + 1); |
+ } else { |
+ options = |
+ arguments.where((argument) => argument.startsWith("-")).toSet(); |
+ arguments = |
+ arguments.where((argument) => !argument.startsWith("-")).toList(); |
+ } |
+ return new CommandLine(options, arguments); |
+ } |
+} |
+ |
+fail(String message) { |
+ print(message); |
+ io.exitCode = 1; |
+ return null; |
+} |
+ |
+main(List<String> arguments) => withErrorHandling(() async { |
+ CommandLine cl = CommandLine.parse(arguments); |
+ if (cl.verbose) { |
+ enableVerboseOutput(); |
+ } |
+ Map<String, String> environment = cl.environment; |
+ Uri configuration = await cl.configuration; |
+ if (configuration == null) return; |
+ if (!isVerbose) { |
+ print("Use --verbose to display more details."); |
+ } |
+ TestRoot root = await TestRoot.fromUri(configuration); |
+ Set<String> skip = cl.skip; |
+ Set<String> selectedSuites = cl.selectedSuites; |
+ List<Suite> suites = root.suites.where((s) { |
+ return !skip.contains(s.name) && |
+ (selectedSuites.isEmpty || selectedSuites.contains(s.name)); |
+ }).toList(); |
+ SuiteRunner runner = new SuiteRunner(suites, environment, cl.selectors); |
+ String program = await runner.generateDartProgram(); |
+ await runner.analyze(root.packages); |
+ Stopwatch sw = new Stopwatch()..start(); |
+ if (program == null) { |
+ fail("No tests configured."); |
+ } else { |
+ await runProgram(program, root.packages); |
+ } |
+ print("Running tests took: ${sw.elapsed}."); |
+}); |
+ |
+Future<Null> runTests(Map<String, Function> tests) => |
+withErrorHandling(() async { |
+ int completed = 0; |
+ for (String name in tests.keys) { |
+ StringBuffer sb = new StringBuffer(); |
+ try { |
+ await runGuarded(() { |
+ print("Running test $name"); |
+ return tests[name](); |
+ }, printLineOnStdout: sb.writeln); |
+ logMessage(sb); |
+ } catch (e) { |
+ print(sb); |
+ rethrow; |
+ } |
+ logTestComplete(++completed, 0, tests.length, null, null); |
+ } |
+ logSuiteComplete(); |
+}); |