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

Side by Side 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE.md file.
4
5 library testing.run;
6
7 import 'dart:async' show
8 Future,
9 Stream;
10
11 import 'dart:convert' show
12 JSON;
13
14 import 'dart:io' show
15 Platform;
16
17 import 'dart:isolate' show
18 Isolate,
19 ReceivePort;
20
21 import 'test_root.dart' show
22 TestRoot;
23
24 import 'test_description.dart' show
25 TestDescription;
26
27 import 'error_handling.dart' show
28 withErrorHandling;
29
30 import 'chain.dart' show
31 CreateContext;
32
33 import '../testing.dart' show
34 Chain,
35 ChainContext,
36 TestDescription,
37 listTests;
38
39 import 'analyze.dart' show
40 Analyze;
41
42 import 'log.dart' show
43 isVerbose,
44 logMessage,
45 logNumberedLines,
46 splitLines;
47
48 import 'suite.dart' show
49 Dart,
50 Suite;
51
52 import 'zone_helper.dart' show
53 acknowledgeControlMessages;
54
55 Future<TestRoot> computeTestRoot(String configurationPath, Uri base) {
56 Uri configuration = configurationPath == null
57 ? Uri.base.resolve("testing.json")
58 : base.resolve(configurationPath);
59 return TestRoot.fromUri(configuration);
60 }
61
62 /// This is called from a Chain suite, and helps implement main. In most cases,
63 /// main will look like this:
64 ///
65 /// main(List<String> arguments) => runMe(arguments, createContext);
66 ///
67 /// The optional argument [configurationPath] should be used when
68 /// `testing.json` isn't located in the current working directory and is a path
69 /// relative to `Platform.script`.
70 Future<Null> runMe(
71 List<String> arguments, CreateContext f, [String configurationPath]) {
72 return withErrorHandling(() async {
73 TestRoot testRoot =
74 await computeTestRoot(configurationPath, Platform.script);
75 for (Chain suite in testRoot.toolChains) {
76 if (Platform.script == suite.source) {
77 print("Running suite ${suite.name}...");
78 ChainContext context = await f(suite, <String, String>{});
79 await context.run(suite, new Set<String>());
80 }
81 }
82 });
83 }
84
85 /// This is called from a `_test.dart` file, and helps integration in other
86 /// test runner frameworks.
87 ///
88 /// For example, to run the suite `my_suite` from `test.dart`, create a file
89 /// with this content:
90 ///
91 /// import 'package:async_helper/async_helper.dart' show asyncTest;
92 ///
93 /// import 'package:testing/testing.dart' show run;
94 ///
95 /// main(List<String> arguments) => asyncTest(run(arguments, ["my_suite"]));
96 ///
97 /// To run run the same suite from `package:test`, create a file with this
98 /// content:
99 ///
100 /// import 'package:test/test.dart' show Timeout, test;
101 ///
102 /// import 'package:testing/testing.dart' show run;
103 ///
104 /// main() {
105 /// test("my_suite", () => run([], ["my_suite"]),
106 /// timeout: new Timeout(new Duration(minutes: 5)));
107 /// }
108 ///
109 /// The optional argument [configurationPath] should be used when
110 /// `testing.json` isn't located in the current working directory and is a path
111 /// relative to `Uri.base`.
112 Future<Null> run(
113 List<String> arguments, List<String> suiteNames,
114 [String configurationPath]) {
115 return withErrorHandling(() async {
116 TestRoot root = await computeTestRoot(configurationPath, Uri.base);
117 List<Suite> suites = root.suites.where(
118 (Suite suite) => suiteNames.contains(suite.name)).toList();
119 SuiteRunner runner = new SuiteRunner(suites, <String, String>{}, null);
120 String program = await runner.generateDartProgram();
121 await runner.analyze(root.packages);
122 if (program != null) {
123 await runProgram(program, root.packages);
124 }
125 });
126 }
127
128 Future<Null> runProgram(String program, Uri packages) async {
129 logMessage("Running:");
130 logNumberedLines(program);
131 Uri dataUri = new Uri.dataFromString(program);
132 ReceivePort exitPort = new ReceivePort();
133 Isolate isolate = await Isolate.spawnUri(dataUri, <String>[], null,
134 paused: true, onExit: exitPort.sendPort, errorsAreFatal: false,
135 checked: true, packageConfig: packages);
136 List error;
137 var subscription = isolate.errors.listen((data) {
138 error = data;
139 exitPort.close();
140 });
141 await acknowledgeControlMessages(isolate, resume: isolate.pauseCapability);
142 await for (var _ in exitPort) {
143 exitPort.close();
144 }
145 subscription.cancel();
146 return error == null
147 ? null
148 : new Future<Null>.error(error[0], new StackTrace.fromString(error[1]));
149 }
150
151 class SuiteRunner {
152 final List<Suite> suites;
153
154 final Map<String, String> environment;
155
156 final List<String> selectors;
157
158 List<Uri> testUris;
159
160 SuiteRunner(this.suites, this.environment, Iterable<String> selectors)
161 : selectors = selectors.toList(growable: false);
162
163 Future<String> generateDartProgram() async {
164 List<TestDescription> descriptions = await list().toList();
165 testUris = <Uri>[];
166 StringBuffer imports = new StringBuffer();
167 StringBuffer dart = new StringBuffer();
168 StringBuffer chain = new StringBuffer();
169
170 for (TestDescription description in descriptions) {
171 testUris.add(await Isolate.resolvePackageUri(description.uri));
172 description.writeImportOn(imports);
173 description.writeClosureOn(dart);
174 }
175
176 for (Chain suite in suites.where((Suite suite) => suite is Chain)) {
177 testUris.add(await Isolate.resolvePackageUri(suite.source));
178 suite.writeImportOn(imports);
179 suite.writeClosureOn(chain);
180 }
181
182 if (testUris.isEmpty) return null;
183
184 return """
185 library testing.generated;
186
187 import 'dart:async' show Future;
188
189 import 'dart:convert' show JSON;
190
191 import 'package:testing/src/run_tests.dart' show runTests;
192
193 import 'package:testing/src/chain.dart' show runChain;
194
195 import 'package:testing/src/log.dart' show enableVerboseOutput, isVerbose;
196
197 ${imports.toString().trim()}
198
199 Future<Null> main() async {
200 if ($isVerbose) enableVerboseOutput();
201 Map<String, String> environment = JSON.decode('${JSON.encode(environment)}');
202 Set<String> selectors = JSON.decode('${JSON.encode(selectors)}').toSet();
203 await runTests(<String, Function> {
204 ${splitLines(dart.toString().trim()).join(' ')}
205 });
206 ${splitLines(chain.toString().trim()).join(' ')}
207 }
208 """;
209 }
210
211 Future<Null> analyze(Uri packages) async {
212 for (Analyze suite in suites.where((Suite suite) => suite is Analyze)) {
213 await suite.run(packages, testUris);
214 }
215 }
216
217 Stream<TestDescription> list() async* {
218 for (Dart suite in suites.where((Suite suite) => suite is Dart)) {
219 await for (TestDescription description in
220 listTests(<Uri>[suite.uri], pattern: "")) {
221 String path = description.file.uri.path;
222 if (suite.exclude.any((RegExp r) => path.contains(r))) continue;
223 if (suite.pattern.any((RegExp r) => path.contains(r))) {
224 yield description;
225 }
226 }
227 }
228 }
229 }
OLDNEW
« 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