OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012, 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 file. | |
4 | |
5 class DartWrapTask extends PipelineTask { | |
Siggi Cherem (dart-lang)
2012/08/29 01:05:54
docs?
gram
2012/08/29 20:12:26
Done.
| |
6 String sourceFileTemplate; | |
7 String tempDartFileTemplate; | |
8 | |
9 DartWrapTask(this.sourceFileTemplate, this.tempDartFileTemplate); | |
10 | |
11 void execute(Path testfile, List stdout, List stderr, bool verboseLogging, | |
12 Function exitHandler) { | |
13 // Get the source test file and canonicalize the path. | |
14 var sourceName = makePathAbsolute(concretize(sourceFileTemplate, testfile)); | |
15 // Get the destination file. | |
16 var destFile = concretize(tempDartFileTemplate, testfile); | |
17 | |
18 StringBuffer sbuf = new StringBuffer(); | |
19 | |
20 // Add the common header stuff. | |
21 var p = new Path(sourceName); | |
22 var u = new Path(configuration['unittest']); | |
23 sbuf.add(directives(p.filenameWithoutExtension, u.toString(), sourceName)); | |
24 | |
25 // Add the test configuration and the action function. | |
26 var action; | |
27 if (configuration['list-tests']) { | |
28 action = 'listTests'; | |
29 sbuf.add(barebonesConfig()); | |
30 sbuf.add(listTests(sourceName)); | |
31 } else if (configuration['list-groups']) { | |
32 sbuf.add(barebonesConfig()); | |
33 sbuf.add(listGroups(sourceName)); | |
34 action = 'listGroups'; | |
35 } else { | |
36 var runIsolated = configuration['isolate']; | |
37 var runInBrowser = | |
38 configuration['runtime'] != 'vm' && | |
39 configuration['runtime'] != 'd8'; | |
40 sbuf.add(testPrint(runInBrowser)); | |
41 sbuf.add(testConfig(sourceName, runInBrowser, runIsolated, | |
42 configuration['time'], | |
43 configuration['summary'])); | |
44 // Add the isolate stuff, if applicable. This overrides | |
45 if (runIsolated) { | |
46 action = 'runIsolateTests'; | |
47 sbuf.add(isolateTests()); | |
48 } else { | |
49 action = 'runTests'; | |
50 sbuf.add("runTests() { unittest.runTests(); }\n"); | |
51 } | |
52 } | |
53 sbuf.add(formatMessage(configuration['format'])); | |
54 | |
55 // Add the filter, if applicable. | |
56 var include = configuration['include']; | |
57 var filter = false; | |
58 if (include.length > 0) { | |
59 sbuf.add(filterTests(include, 'true')); | |
60 filter = true; | |
61 } else { | |
62 var exclude = configuration['exclude']; | |
63 if (exclude.length > 0) { | |
64 sbuf.add(filterTests(exclude, 'false')); | |
65 filter = true; | |
66 } | |
67 } | |
68 | |
69 // Add the common trailer stuff. | |
70 sbuf.add(dartMain(action, filter)); | |
71 | |
72 // Save the Dart file. | |
73 createFile(destFile, sbuf.toString()); | |
74 exitHandler(0); | |
75 } | |
76 | |
77 String directives(String library, String unittest, String sourceName) { | |
78 return """ | |
79 #library('$library'); | |
80 #import('dart:isolate'); | |
81 #import('$unittest', prefix:'unittest'); | |
82 #import('$sourceName', prefix: 'test'); | |
83 """; | |
84 } | |
85 | |
86 String testPrint(bool runInBrowser) { | |
87 if (runInBrowser) { | |
88 return """ | |
89 #import('dart:html'); | |
90 void tprint(msg) { | |
91 var pre = query('#console'); | |
92 pre.elements.add(new Text('###\$msg\\n')); | |
93 } | |
94 """; | |
95 } else { | |
96 return """ | |
97 void tprint(msg) { | |
98 print('###\$msg'); | |
99 } | |
100 """; | |
101 } | |
102 } | |
103 | |
104 String config(String body) { | |
105 return """ | |
106 class TestRunnerConfiguration extends unittest.Configuration { | |
107 get name => 'Test runner configuration'; | |
108 get autoStart => false; | |
109 $body | |
110 } | |
111 """; | |
112 } | |
113 | |
114 String barebonesConfig() { | |
115 return config(''); | |
116 } | |
117 | |
118 String testConfig(String sourceName, bool runInBrowser, bool runIsolated, | |
119 bool showTime, bool summary) { | |
120 StringBuffer sbuf = new StringBuffer(); | |
121 if (runIsolated) { | |
122 sbuf.add("var port;\nTestRunnerConfiguration(this.port);\n"); | |
123 } | |
124 sbuf.add(""" | |
125 String resultName(result) { | |
Siggi Cherem (dart-lang)
2012/08/29 01:05:54
the mix of quoted code and normal code makes this
gram
2012/08/29 20:12:26
I've refactored this quite a bit; hopefully it wil
Siggi Cherem (dart-lang)
2012/08/29 20:47:35
it is easier to see with syntax highlighting, but
| |
126 if (result == 'pass') return '${configuration['pass-text']}'; | |
127 if (result == 'fail') return '${configuration['fail-text']}'; | |
128 return '${configuration['error-text']}'; | |
129 } | |
130 void onTestStart(TestCase testCase) {} | |
131 void onDone(int passed, int failed, int errors, List<TestCase> results, | |
132 String uncaughtError) { | |
133 // Print each result. | |
134 for (final t in results) { | |
135 var groupName = '', testName = ''; | |
136 var idx = t.description.lastIndexOf('###'); | |
137 if (idx >= 0) { | |
138 groupName = t.description.substring(0, idx).replaceAll('###', ' '); | |
139 testName = t.description.substring(idx+3); | |
140 } else { | |
141 testName = t.description; | |
142 } | |
143 var stack = (t.stackTrace == null) ? '' : '\${t.stackTrace} '; | |
144 var message = (t.message.length > 0) ? '\$t.message ' : ''; | |
145 var elapsed = ''; | |
146 """); | |
147 if (showTime) { | |
148 sbuf.add(""" | |
149 double duration = t.runningTime.inMilliseconds; | |
150 duration /= 1000; | |
151 elapsed = '\${duration.toStringAsFixed(3)}s '; | |
152 """); | |
153 } | |
154 sbuf.add(""" | |
155 tprint(formatMessage('${sourceName} ', '\$groupName ', '\$testName ', | |
156 elapsed, '\${resultName(t.result)} ', message, stack)); | |
157 } | |
158 """); | |
159 if (summary) { | |
160 sbuf.add(""" | |
161 tprint(''); | |
162 var success = false; | |
163 if (passed == 0 && failed == 0 && errors == 0) { | |
164 tprint('$sourceName: No tests found.'); | |
165 // This is considered a failure too. | |
166 } else if (failed == 0 && errors == 0 && uncaughtError == null) { | |
167 tprint('$sourceName: All \$passed tests passed.'); | |
168 success = true; | |
169 } else { | |
170 if (uncaughtError != null) { | |
171 tprint('$sourceName: Top-level uncaught error: \$uncaughtError'); | |
172 } | |
173 tprint('$sourceName: \$passed PASSED, \$failed FAILED, \$errors ERRORS'); | |
174 } | |
175 """); | |
176 } | |
177 if (runIsolated) { | |
178 sbuf.add("var success = (passed > 0 && failed == 0 && errors == 0 " | |
179 "&& uncaughtError == null);\n"); | |
180 sbuf.add("port.send(success);\n}\n"); | |
181 } else if (runInBrowser) { | |
182 sbuf.add("window.postMessage('done', '*');\n}\n"); | |
183 } else { | |
184 sbuf.add("}\n"); | |
185 } | |
186 return config(sbuf.toString()); | |
187 } | |
188 | |
189 String formatMessage(String format) { | |
190 return """ | |
191 String formatMessage(filename, groupname, | |
192 [ testname = '', testTime = '', result = '', | |
193 message = '', stack = '' ]) { | |
194 return '${format}'. | |
195 replaceAll('${Meta.testResult}', result). | |
196 replaceAll('${Meta.testTime}', testTime). | |
197 replaceAll('${Meta.testfile}', filename). | |
198 replaceAll('${Meta.testGroup}', groupname). | |
199 replaceAll('${Meta.testDescription}', testname). | |
200 replaceAll('${Meta.testMessage}', message). | |
201 replaceAll('${Meta.testStacktrace}', stack); | |
202 } | |
203 """; | |
204 } | |
205 | |
206 String listGroups(String sourceName) { | |
207 return """ | |
208 listGroups() { | |
209 List tests = unittest.testCases; | |
210 Map groups = {}; | |
211 for (var t in tests) { | |
212 var groupName, testName = ''; | |
213 var idx = t.description.lastIndexOf('###'); | |
214 if (idx >= 0) { | |
215 groupName = t.description.substring(0, idx).replaceAll('###', ' '); | |
216 if (!groups.containsKey(groupName)) { | |
217 groups[groupName] = ''; | |
218 } | |
219 } | |
220 } | |
221 for (var g in groups.getKeys()) { | |
222 var msg = formatMessage('${sourceName} ', '\$g '); | |
223 print('###\$msg'); | |
224 } | |
225 } | |
226 """; | |
227 } | |
228 | |
229 String listTests(String sourceName) { | |
230 return """ | |
231 listTests() { | |
232 List tests = unittest.testCases; | |
233 for (var t in tests) { | |
234 var groupName, testName = ''; | |
235 var idx = t.description.lastIndexOf('###'); | |
236 if (idx >= 0) { | |
237 groupName = t.description.substring(0, idx).replaceAll('###', ' '); | |
238 testName = t.description.substring(idx+3); | |
239 } else { | |
240 groupName = ''; | |
241 testName = t.description; | |
242 } | |
243 var msg = formatMessage('${sourceName} ', '\$groupName ', | |
244 '\$testName '); | |
245 print('###\$msg'); | |
246 } | |
247 } | |
248 """; | |
249 } | |
250 | |
251 String filterTests(List filters, String filterReturnValue) { | |
252 StringBuffer sbuf = new StringBuffer(); | |
253 sbuf.add('filterTest(t) {\n'); | |
254 if (filters != null) { | |
255 sbuf.add(' var name = t.description.replaceAll("###", " ");\n'); | |
256 for (var f in filters) { | |
257 sbuf.add(' if (name.indexOf("$f")>=0) return $filterReturnValue;\n'); | |
258 } | |
259 sbuf.add(' return !$filterReturnValue;\n'); | |
260 } else { | |
261 // TODO - is this right? Should it be filterReturnValue? | |
262 sbuf.add(' return true;\n'); | |
263 } | |
264 sbuf.add('}\n'); | |
265 return sbuf.toString(); | |
266 } | |
267 | |
268 String isolateTests() { | |
269 return """ | |
270 runSlaveTest() { | |
271 port.receive((testName, sendport) { | |
272 unittest.configure(new TestRunnerConfiguration(sendport)); | |
273 unittest.group('', test.main); | |
274 unittest.filterTests(testName); | |
275 unittest.runTests(); | |
276 }); | |
277 } | |
278 | |
279 var testNum; | |
280 var failed; | |
281 | |
282 runMasterTest() { | |
283 var tests = unittest.testCases; | |
284 SendPort sport = spawnFunction(runSlaveTest); | |
285 sport.call(tests[testNum].description).then((result) { | |
286 if (!result) failed = true; | |
287 ++testNum; | |
288 if (testNum < tests.length) { | |
289 runMasterTest(); | |
290 } else if (failed) { | |
291 throw new Exception("Some tests failed."); | |
292 } | |
293 }); | |
294 } | |
295 | |
296 runIsolateTests() { | |
297 testNum = 0; | |
298 failed = false; | |
299 runMasterTest(); | |
300 } | |
301 """; | |
302 } | |
303 | |
304 String dartMain(String action, bool filter) { | |
305 return """ | |
306 main() { | |
307 unittest.groupSep = '###'; | |
308 unittest.configure(new TestRunnerConfiguration()); | |
309 unittest.group('', test.main); | |
310 ${filter?'unittest.filterTests(filterTest);':''} | |
311 $action(); | |
312 } | |
313 """; | |
314 } | |
315 | |
316 } | |
OLD | NEW |