OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE.md file. |
4 | 4 |
5 library testing.run; | 5 library testing.run; |
6 | 6 |
7 import 'dart:async' show | 7 import 'dart:async' show Future, Stream; |
8 Future, | |
9 Stream; | |
10 | 8 |
11 import 'dart:convert' show | 9 import 'dart:convert' show JSON; |
12 JSON; | |
13 | 10 |
14 import 'dart:io' show | 11 import 'dart:io' show Platform; |
15 Platform; | |
16 | 12 |
17 import 'dart:isolate' show | 13 import 'dart:isolate' show Isolate, ReceivePort; |
18 Isolate, | |
19 ReceivePort; | |
20 | 14 |
21 import 'test_root.dart' show | 15 import 'test_root.dart' show TestRoot; |
22 TestRoot; | |
23 | 16 |
24 import 'test_description.dart' show | 17 import 'test_description.dart' show TestDescription; |
25 TestDescription; | |
26 | 18 |
27 import 'error_handling.dart' show | 19 import 'error_handling.dart' show withErrorHandling; |
28 withErrorHandling; | |
29 | 20 |
30 import 'chain.dart' show | 21 import 'chain.dart' show CreateContext; |
31 CreateContext; | |
32 | 22 |
33 import '../testing.dart' show | 23 import '../testing.dart' show Chain, ChainContext, TestDescription, listTests; |
34 Chain, | |
35 ChainContext, | |
36 TestDescription, | |
37 listTests; | |
38 | 24 |
39 import 'analyze.dart' show | 25 import 'analyze.dart' show Analyze; |
40 Analyze; | |
41 | 26 |
42 import 'log.dart' show | 27 import 'log.dart' show isVerbose, logMessage, logNumberedLines, splitLines; |
43 isVerbose, | |
44 logMessage, | |
45 logNumberedLines, | |
46 splitLines; | |
47 | 28 |
48 import 'suite.dart' show | 29 import 'suite.dart' show Dart, Suite; |
49 Dart, | |
50 Suite; | |
51 | 30 |
52 import 'test_dart.dart' show | 31 import 'test_dart.dart' show TestDart; |
53 TestDart; | |
54 | 32 |
55 import 'zone_helper.dart' show | 33 import 'zone_helper.dart' show acknowledgeControlMessages; |
56 acknowledgeControlMessages; | |
57 | 34 |
58 Future<TestRoot> computeTestRoot(String configurationPath, Uri base) { | 35 Future<TestRoot> computeTestRoot(String configurationPath, Uri base) { |
59 Uri configuration = configurationPath == null | 36 Uri configuration = configurationPath == null |
60 ? Uri.base.resolve("testing.json") | 37 ? Uri.base.resolve("testing.json") |
61 : base.resolve(configurationPath); | 38 : base.resolve(configurationPath); |
62 return TestRoot.fromUri(configuration); | 39 return TestRoot.fromUri(configuration); |
63 } | 40 } |
64 | 41 |
65 /// This is called from a Chain suite, and helps implement main. In most cases, | 42 /// This is called from a Chain suite, and helps implement main. In most cases, |
66 /// main will look like this: | 43 /// main will look like this: |
67 /// | 44 /// |
68 /// main(List<String> arguments) => runMe(arguments, createContext); | 45 /// main(List<String> arguments) => runMe(arguments, createContext); |
69 /// | 46 /// |
70 /// The optional argument [configurationPath] should be used when | 47 /// The optional argument [configurationPath] should be used when |
71 /// `testing.json` isn't located in the current working directory and is a path | 48 /// `testing.json` isn't located in the current working directory and is a path |
72 /// relative to `Platform.script`. | 49 /// relative to `Platform.script`. |
73 Future<Null> runMe( | 50 Future<Null> runMe(List<String> arguments, CreateContext f, |
74 List<String> arguments, CreateContext f, [String configurationPath]) { | 51 [String configurationPath]) { |
75 return withErrorHandling(() async { | 52 return withErrorHandling(() async { |
76 TestRoot testRoot = | 53 TestRoot testRoot = |
77 await computeTestRoot(configurationPath, Platform.script); | 54 await computeTestRoot(configurationPath, Platform.script); |
78 for (Chain suite in testRoot.toolChains) { | 55 for (Chain suite in testRoot.toolChains) { |
79 if (Platform.script == suite.source) { | 56 if (Platform.script == suite.source) { |
80 print("Running suite ${suite.name}..."); | 57 print("Running suite ${suite.name}..."); |
81 ChainContext context = await f(suite, <String, String>{}); | 58 ChainContext context = await f(suite, <String, String>{}); |
82 await context.run(suite, new Set<String>()); | 59 await context.run(suite, new Set<String>()); |
83 } | 60 } |
84 } | 61 } |
(...skipping 20 matching lines...) Expand all Loading... |
105 /// import 'package:testing/testing.dart' show run; | 82 /// import 'package:testing/testing.dart' show run; |
106 /// | 83 /// |
107 /// main() { | 84 /// main() { |
108 /// test("my_suite", () => run([], ["my_suite"]), | 85 /// test("my_suite", () => run([], ["my_suite"]), |
109 /// timeout: new Timeout(new Duration(minutes: 5))); | 86 /// timeout: new Timeout(new Duration(minutes: 5))); |
110 /// } | 87 /// } |
111 /// | 88 /// |
112 /// The optional argument [configurationPath] should be used when | 89 /// The optional argument [configurationPath] should be used when |
113 /// `testing.json` isn't located in the current working directory and is a path | 90 /// `testing.json` isn't located in the current working directory and is a path |
114 /// relative to `Uri.base`. | 91 /// relative to `Uri.base`. |
115 Future<Null> run( | 92 Future<Null> run(List<String> arguments, List<String> suiteNames, |
116 List<String> arguments, List<String> suiteNames, | |
117 [String configurationPath]) { | 93 [String configurationPath]) { |
118 return withErrorHandling(() async { | 94 return withErrorHandling(() async { |
119 TestRoot root = await computeTestRoot(configurationPath, Uri.base); | 95 TestRoot root = await computeTestRoot(configurationPath, Uri.base); |
120 List<Suite> suites = root.suites.where( | 96 List<Suite> suites = root.suites |
121 (Suite suite) => suiteNames.contains(suite.name)).toList(); | 97 .where((Suite suite) => suiteNames.contains(suite.name)) |
122 SuiteRunner runner = new SuiteRunner(suites, <String, String>{}, null, | 98 .toList(); |
123 new Set<String>(), new Set<String>()); | 99 SuiteRunner runner = new SuiteRunner( |
| 100 suites, <String, String>{}, null, new Set<String>(), new Set<String>()); |
124 String program = await runner.generateDartProgram(); | 101 String program = await runner.generateDartProgram(); |
125 await runner.analyze(root.packages); | 102 await runner.analyze(root.packages); |
126 if (program != null) { | 103 if (program != null) { |
127 await runProgram(program, root.packages); | 104 await runProgram(program, root.packages); |
128 } | 105 } |
129 }); | 106 }); |
130 } | 107 } |
131 | 108 |
132 Future<Null> runProgram(String program, Uri packages) async { | 109 Future<Null> runProgram(String program, Uri packages) async { |
133 logMessage("Running:"); | 110 logMessage("Running:"); |
134 logNumberedLines(program); | 111 logNumberedLines(program); |
135 Uri dataUri = new Uri.dataFromString(program); | 112 Uri dataUri = new Uri.dataFromString(program); |
136 ReceivePort exitPort = new ReceivePort(); | 113 ReceivePort exitPort = new ReceivePort(); |
137 Isolate isolate = await Isolate.spawnUri(dataUri, <String>[], null, | 114 Isolate isolate = await Isolate.spawnUri(dataUri, <String>[], null, |
138 paused: true, onExit: exitPort.sendPort, errorsAreFatal: false, | 115 paused: true, |
139 checked: true, packageConfig: packages); | 116 onExit: exitPort.sendPort, |
| 117 errorsAreFatal: false, |
| 118 checked: true, |
| 119 packageConfig: packages); |
140 List error; | 120 List error; |
141 var subscription = isolate.errors.listen((data) { | 121 var subscription = isolate.errors.listen((data) { |
142 error = data; | 122 error = data; |
143 exitPort.close(); | 123 exitPort.close(); |
144 }); | 124 }); |
145 await acknowledgeControlMessages(isolate, resume: isolate.pauseCapability); | 125 await acknowledgeControlMessages(isolate, resume: isolate.pauseCapability); |
146 await for (var _ in exitPort) { | 126 await for (var _ in exitPort) { |
147 exitPort.close(); | 127 exitPort.close(); |
148 } | 128 } |
149 subscription.cancel(); | 129 subscription.cancel(); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 if (shouldRunSuite(suite)) { | 220 if (shouldRunSuite(suite)) { |
241 hasAnalyzerSuites = true; | 221 hasAnalyzerSuites = true; |
242 await suite.run(packages, testUris); | 222 await suite.run(packages, testUris); |
243 } | 223 } |
244 } | 224 } |
245 return hasAnalyzerSuites; | 225 return hasAnalyzerSuites; |
246 } | 226 } |
247 | 227 |
248 Stream<TestDescription> listDescriptions() async* { | 228 Stream<TestDescription> listDescriptions() async* { |
249 for (Dart suite in suites.where((Suite suite) => suite is Dart)) { | 229 for (Dart suite in suites.where((Suite suite) => suite is Dart)) { |
250 await for (TestDescription description in | 230 await for (TestDescription description |
251 listTests(<Uri>[suite.uri], pattern: "")) { | 231 in listTests(<Uri>[suite.uri], pattern: "")) { |
252 testUris.add(await Isolate.resolvePackageUri(description.uri)); | 232 testUris.add(await Isolate.resolvePackageUri(description.uri)); |
253 if (shouldRunSuite(suite)) { | 233 if (shouldRunSuite(suite)) { |
254 String path = description.file.uri.path; | 234 String path = description.file.uri.path; |
255 if (suite.exclude.any((RegExp r) => path.contains(r))) continue; | 235 if (suite.exclude.any((RegExp r) => path.contains(r))) continue; |
256 if (suite.pattern.any((RegExp r) => path.contains(r))) { | 236 if (suite.pattern.any((RegExp r) => path.contains(r))) { |
257 yield description; | 237 yield description; |
258 } | 238 } |
259 } | 239 } |
260 } | 240 } |
261 } | 241 } |
262 } | 242 } |
263 | 243 |
264 Stream<Chain> listChainSuites() async* { | 244 Stream<Chain> listChainSuites() async* { |
265 for (Chain suite in suites.where((Suite suite) => suite is Chain)) { | 245 for (Chain suite in suites.where((Suite suite) => suite is Chain)) { |
266 testUris.add(await Isolate.resolvePackageUri(suite.source)); | 246 testUris.add(await Isolate.resolvePackageUri(suite.source)); |
267 if (shouldRunSuite(suite)) { | 247 if (shouldRunSuite(suite)) { |
268 yield suite; | 248 yield suite; |
269 } | 249 } |
270 } | 250 } |
271 } | 251 } |
272 | 252 |
273 Iterable<Suite> listTestDartSuites() { | 253 Iterable<Suite> listTestDartSuites() { |
274 return suites.where((Suite suite) => suite is TestDart); | 254 return suites.where((Suite suite) => suite is TestDart); |
275 } | 255 } |
276 | 256 |
277 Iterable<Suite> listAnalyzerSuites() { | 257 Iterable<Suite> listAnalyzerSuites() { |
278 return suites.where((Suite suite) => suite is Analyze); | 258 return suites.where((Suite suite) => suite is Analyze); |
279 } | 259 } |
280 } | 260 } |
OLD | NEW |