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

Unified Diff: pkg/testing/lib/src/run.dart

Issue 2624373003: Move package:testing to SDK. (Closed)
Patch Set: Created 3 years, 11 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 | « pkg/testing/lib/src/multitest.dart ('k') | pkg/testing/lib/src/run_tests.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/testing/lib/src/run.dart
diff --git a/pkg/testing/lib/src/run.dart b/pkg/testing/lib/src/run.dart
new file mode 100644
index 0000000000000000000000000000000000000000..d1d6d3ae653a2a8b3bede857f76b06debda4aa29
--- /dev/null
+++ b/pkg/testing/lib/src/run.dart
@@ -0,0 +1,229 @@
+// 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;
+
+import 'dart:async' show
+ Future,
+ Stream;
+
+import 'dart:convert' show
+ JSON;
+
+import 'dart:io' show
+ Platform;
+
+import 'dart:isolate' show
+ Isolate,
+ ReceivePort;
+
+import 'test_root.dart' show
+ TestRoot;
+
+import 'test_description.dart' show
+ TestDescription;
+
+import 'error_handling.dart' show
+ withErrorHandling;
+
+import 'chain.dart' show
+ CreateContext;
+
+import '../testing.dart' show
+ Chain,
+ ChainContext,
+ TestDescription,
+ listTests;
+
+import 'analyze.dart' show
+ Analyze;
+
+import 'log.dart' show
+ isVerbose,
+ logMessage,
+ logNumberedLines,
+ splitLines;
+
+import 'suite.dart' show
+ Dart,
+ Suite;
+
+import 'zone_helper.dart' show
+ acknowledgeControlMessages;
+
+Future<TestRoot> computeTestRoot(String configurationPath, Uri base) {
+ Uri configuration = configurationPath == null
+ ? Uri.base.resolve("testing.json")
+ : base.resolve(configurationPath);
+ return TestRoot.fromUri(configuration);
+}
+
+/// This is called from a Chain suite, and helps implement main. In most cases,
+/// main will look like this:
+///
+/// main(List<String> arguments) => runMe(arguments, createContext);
+///
+/// The optional argument [configurationPath] should be used when
+/// `testing.json` isn't located in the current working directory and is a path
+/// relative to `Platform.script`.
+Future<Null> runMe(
+ List<String> arguments, CreateContext f, [String configurationPath]) {
+ return withErrorHandling(() async {
+ TestRoot testRoot =
+ await computeTestRoot(configurationPath, Platform.script);
+ for (Chain suite in testRoot.toolChains) {
+ if (Platform.script == suite.source) {
+ print("Running suite ${suite.name}...");
+ ChainContext context = await f(suite, <String, String>{});
+ await context.run(suite, new Set<String>());
+ }
+ }
+ });
+}
+
+/// This is called from a `_test.dart` file, and helps integration in other
+/// test runner frameworks.
+///
+/// For example, to run the suite `my_suite` from `test.dart`, create a file
+/// with this content:
+///
+/// import 'package:async_helper/async_helper.dart' show asyncTest;
+///
+/// import 'package:testing/testing.dart' show run;
+///
+/// main(List<String> arguments) => asyncTest(run(arguments, ["my_suite"]));
+///
+/// To run run the same suite from `package:test`, create a file with this
+/// content:
+///
+/// import 'package:test/test.dart' show Timeout, test;
+///
+/// import 'package:testing/testing.dart' show run;
+///
+/// main() {
+/// test("my_suite", () => run([], ["my_suite"]),
+/// timeout: new Timeout(new Duration(minutes: 5)));
+/// }
+///
+/// The optional argument [configurationPath] should be used when
+/// `testing.json` isn't located in the current working directory and is a path
+/// relative to `Uri.base`.
+Future<Null> run(
+ List<String> arguments, List<String> suiteNames,
+ [String configurationPath]) {
+ return withErrorHandling(() async {
+ TestRoot root = await computeTestRoot(configurationPath, Uri.base);
+ List<Suite> suites = root.suites.where(
+ (Suite suite) => suiteNames.contains(suite.name)).toList();
+ SuiteRunner runner = new SuiteRunner(suites, <String, String>{}, null);
+ String program = await runner.generateDartProgram();
+ await runner.analyze(root.packages);
+ if (program != null) {
+ await runProgram(program, root.packages);
+ }
+ });
+}
+
+Future<Null> runProgram(String program, Uri packages) async {
+ logMessage("Running:");
+ logNumberedLines(program);
+ Uri dataUri = new Uri.dataFromString(program);
+ ReceivePort exitPort = new ReceivePort();
+ Isolate isolate = await Isolate.spawnUri(dataUri, <String>[], null,
+ paused: true, onExit: exitPort.sendPort, errorsAreFatal: false,
+ checked: true, packageConfig: packages);
+ List error;
+ var subscription = isolate.errors.listen((data) {
+ error = data;
+ exitPort.close();
+ });
+ await acknowledgeControlMessages(isolate, resume: isolate.pauseCapability);
+ await for (var _ in exitPort) {
+ exitPort.close();
+ }
+ subscription.cancel();
+ return error == null
+ ? null
+ : new Future<Null>.error(error[0], new StackTrace.fromString(error[1]));
+}
+
+class SuiteRunner {
+ final List<Suite> suites;
+
+ final Map<String, String> environment;
+
+ final List<String> selectors;
+
+ List<Uri> testUris;
+
+ SuiteRunner(this.suites, this.environment, Iterable<String> selectors)
+ : selectors = selectors.toList(growable: false);
+
+ Future<String> generateDartProgram() async {
+ List<TestDescription> descriptions = await list().toList();
+ testUris = <Uri>[];
+ StringBuffer imports = new StringBuffer();
+ StringBuffer dart = new StringBuffer();
+ StringBuffer chain = new StringBuffer();
+
+ for (TestDescription description in descriptions) {
+ testUris.add(await Isolate.resolvePackageUri(description.uri));
+ description.writeImportOn(imports);
+ description.writeClosureOn(dart);
+ }
+
+ for (Chain suite in suites.where((Suite suite) => suite is Chain)) {
+ testUris.add(await Isolate.resolvePackageUri(suite.source));
+ suite.writeImportOn(imports);
+ suite.writeClosureOn(chain);
+ }
+
+ if (testUris.isEmpty) return null;
+
+ return """
+library testing.generated;
+
+import 'dart:async' show Future;
+
+import 'dart:convert' show JSON;
+
+import 'package:testing/src/run_tests.dart' show runTests;
+
+import 'package:testing/src/chain.dart' show runChain;
+
+import 'package:testing/src/log.dart' show enableVerboseOutput, isVerbose;
+
+${imports.toString().trim()}
+
+Future<Null> main() async {
+ if ($isVerbose) enableVerboseOutput();
+ Map<String, String> environment = JSON.decode('${JSON.encode(environment)}');
+ Set<String> selectors = JSON.decode('${JSON.encode(selectors)}').toSet();
+ await runTests(<String, Function> {
+ ${splitLines(dart.toString().trim()).join(' ')}
+ });
+ ${splitLines(chain.toString().trim()).join(' ')}
+}
+""";
+ }
+
+ Future<Null> analyze(Uri packages) async {
+ for (Analyze suite in suites.where((Suite suite) => suite is Analyze)) {
+ await suite.run(packages, testUris);
+ }
+ }
+
+ Stream<TestDescription> list() async* {
+ for (Dart suite in suites.where((Suite suite) => suite is Dart)) {
+ await for (TestDescription description in
+ listTests(<Uri>[suite.uri], pattern: "")) {
+ String path = description.file.uri.path;
+ if (suite.exclude.any((RegExp r) => path.contains(r))) continue;
+ if (suite.pattern.any((RegExp r) => path.contains(r))) {
+ yield description;
+ }
+ }
+ }
+ }
+}
« no previous file with comments | « pkg/testing/lib/src/multitest.dart ('k') | pkg/testing/lib/src/run_tests.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698