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