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

Unified Diff: utils/testrunner/dart_wrap_task.dart

Issue 10897016: Testrunner for 3rd parties. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 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
Index: utils/testrunner/dart_wrap_task.dart
===================================================================
--- utils/testrunner/dart_wrap_task.dart (revision 0)
+++ utils/testrunner/dart_wrap_task.dart (revision 0)
@@ -0,0 +1,316 @@
+// Copyright (c) 2012, 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 file.
+
+class DartWrapTask extends PipelineTask {
Siggi Cherem (dart-lang) 2012/08/29 01:05:54 docs?
gram 2012/08/29 20:12:26 Done.
+ String sourceFileTemplate;
+ String tempDartFileTemplate;
+
+ DartWrapTask(this.sourceFileTemplate, this.tempDartFileTemplate);
+
+ void execute(Path testfile, List stdout, List stderr, bool verboseLogging,
+ Function exitHandler) {
+ // Get the source test file and canonicalize the path.
+ var sourceName = makePathAbsolute(concretize(sourceFileTemplate, testfile));
+ // Get the destination file.
+ var destFile = concretize(tempDartFileTemplate, testfile);
+
+ StringBuffer sbuf = new StringBuffer();
+
+ // Add the common header stuff.
+ var p = new Path(sourceName);
+ var u = new Path(configuration['unittest']);
+ sbuf.add(directives(p.filenameWithoutExtension, u.toString(), sourceName));
+
+ // Add the test configuration and the action function.
+ var action;
+ if (configuration['list-tests']) {
+ action = 'listTests';
+ sbuf.add(barebonesConfig());
+ sbuf.add(listTests(sourceName));
+ } else if (configuration['list-groups']) {
+ sbuf.add(barebonesConfig());
+ sbuf.add(listGroups(sourceName));
+ action = 'listGroups';
+ } else {
+ var runIsolated = configuration['isolate'];
+ var runInBrowser =
+ configuration['runtime'] != 'vm' &&
+ configuration['runtime'] != 'd8';
+ sbuf.add(testPrint(runInBrowser));
+ sbuf.add(testConfig(sourceName, runInBrowser, runIsolated,
+ configuration['time'],
+ configuration['summary']));
+ // Add the isolate stuff, if applicable. This overrides
+ if (runIsolated) {
+ action = 'runIsolateTests';
+ sbuf.add(isolateTests());
+ } else {
+ action = 'runTests';
+ sbuf.add("runTests() { unittest.runTests(); }\n");
+ }
+ }
+ sbuf.add(formatMessage(configuration['format']));
+
+ // Add the filter, if applicable.
+ var include = configuration['include'];
+ var filter = false;
+ if (include.length > 0) {
+ sbuf.add(filterTests(include, 'true'));
+ filter = true;
+ } else {
+ var exclude = configuration['exclude'];
+ if (exclude.length > 0) {
+ sbuf.add(filterTests(exclude, 'false'));
+ filter = true;
+ }
+ }
+
+ // Add the common trailer stuff.
+ sbuf.add(dartMain(action, filter));
+
+ // Save the Dart file.
+ createFile(destFile, sbuf.toString());
+ exitHandler(0);
+ }
+
+ String directives(String library, String unittest, String sourceName) {
+ return """
+#library('$library');
+#import('dart:isolate');
+#import('$unittest', prefix:'unittest');
+#import('$sourceName', prefix: 'test');
+""";
+ }
+
+ String testPrint(bool runInBrowser) {
+ if (runInBrowser) {
+ return """
+#import('dart:html');
+void tprint(msg) {
+var pre = query('#console');
+pre.elements.add(new Text('###\$msg\\n'));
+}
+""";
+ } else {
+ return """
+void tprint(msg) {
+print('###\$msg');
+}
+""";
+ }
+ }
+
+ String config(String body) {
+ return """
+class TestRunnerConfiguration extends unittest.Configuration {
+ get name => 'Test runner configuration';
+ get autoStart => false;
+ $body
+}
+""";
+ }
+
+ String barebonesConfig() {
+ return config('');
+ }
+
+ String testConfig(String sourceName, bool runInBrowser, bool runIsolated,
+ bool showTime, bool summary) {
+ StringBuffer sbuf = new StringBuffer();
+ if (runIsolated) {
+ sbuf.add("var port;\nTestRunnerConfiguration(this.port);\n");
+ }
+ sbuf.add("""
+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
+ if (result == 'pass') return '${configuration['pass-text']}';
+ if (result == 'fail') return '${configuration['fail-text']}';
+ return '${configuration['error-text']}';
+}
+void onTestStart(TestCase testCase) {}
+void onDone(int passed, int failed, int errors, List<TestCase> results,
+ String uncaughtError) {
+// Print each result.
+for (final t in results) {
+ var groupName = '', testName = '';
+ var idx = t.description.lastIndexOf('###');
+ if (idx >= 0) {
+ groupName = t.description.substring(0, idx).replaceAll('###', ' ');
+ testName = t.description.substring(idx+3);
+ } else {
+ testName = t.description;
+ }
+ var stack = (t.stackTrace == null) ? '' : '\${t.stackTrace} ';
+ var message = (t.message.length > 0) ? '\$t.message ' : '';
+ var elapsed = '';
+""");
+ if (showTime) {
+ sbuf.add("""
+ double duration = t.runningTime.inMilliseconds;
+ duration /= 1000;
+ elapsed = '\${duration.toStringAsFixed(3)}s ';
+""");
+ }
+ sbuf.add("""
+ tprint(formatMessage('${sourceName} ', '\$groupName ', '\$testName ',
+ elapsed, '\${resultName(t.result)} ', message, stack));
+}
+""");
+ if (summary) {
+ sbuf.add("""
+tprint('');
+var success = false;
+if (passed == 0 && failed == 0 && errors == 0) {
+ tprint('$sourceName: No tests found.');
+ // This is considered a failure too.
+} else if (failed == 0 && errors == 0 && uncaughtError == null) {
+ tprint('$sourceName: All \$passed tests passed.');
+ success = true;
+} else {
+ if (uncaughtError != null) {
+ tprint('$sourceName: Top-level uncaught error: \$uncaughtError');
+ }
+ tprint('$sourceName: \$passed PASSED, \$failed FAILED, \$errors ERRORS');
+}
+""");
+ }
+ if (runIsolated) {
+ sbuf.add("var success = (passed > 0 && failed == 0 && errors == 0 "
+ "&& uncaughtError == null);\n");
+ sbuf.add("port.send(success);\n}\n");
+ } else if (runInBrowser) {
+ sbuf.add("window.postMessage('done', '*');\n}\n");
+ } else {
+ sbuf.add("}\n");
+ }
+ return config(sbuf.toString());
+ }
+
+ String formatMessage(String format) {
+ return """
+String formatMessage(filename, groupname,
+ [ testname = '', testTime = '', result = '',
+ message = '', stack = '' ]) {
+ return '${format}'.
+ replaceAll('${Meta.testResult}', result).
+ replaceAll('${Meta.testTime}', testTime).
+ replaceAll('${Meta.testfile}', filename).
+ replaceAll('${Meta.testGroup}', groupname).
+ replaceAll('${Meta.testDescription}', testname).
+ replaceAll('${Meta.testMessage}', message).
+ replaceAll('${Meta.testStacktrace}', stack);
+}
+""";
+ }
+
+ String listGroups(String sourceName) {
+ return """
+listGroups() {
+ List tests = unittest.testCases;
+ Map groups = {};
+ for (var t in tests) {
+ var groupName, testName = '';
+ var idx = t.description.lastIndexOf('###');
+ if (idx >= 0) {
+ groupName = t.description.substring(0, idx).replaceAll('###', ' ');
+ if (!groups.containsKey(groupName)) {
+ groups[groupName] = '';
+ }
+ }
+ }
+ for (var g in groups.getKeys()) {
+ var msg = formatMessage('${sourceName} ', '\$g ');
+ print('###\$msg');
+ }
+}
+""";
+ }
+
+ String listTests(String sourceName) {
+ return """
+ listTests() {
+ List tests = unittest.testCases;
+ for (var t in tests) {
+ var groupName, testName = '';
+ var idx = t.description.lastIndexOf('###');
+ if (idx >= 0) {
+ groupName = t.description.substring(0, idx).replaceAll('###', ' ');
+ testName = t.description.substring(idx+3);
+ } else {
+ groupName = '';
+ testName = t.description;
+ }
+ var msg = formatMessage('${sourceName} ', '\$groupName ',
+ '\$testName ');
+ print('###\$msg');
+ }
+ }
+""";
+ }
+
+ String filterTests(List filters, String filterReturnValue) {
+ StringBuffer sbuf = new StringBuffer();
+ sbuf.add('filterTest(t) {\n');
+ if (filters != null) {
+ sbuf.add(' var name = t.description.replaceAll("###", " ");\n');
+ for (var f in filters) {
+ sbuf.add(' if (name.indexOf("$f")>=0) return $filterReturnValue;\n');
+ }
+ sbuf.add(' return !$filterReturnValue;\n');
+ } else {
+ // TODO - is this right? Should it be filterReturnValue?
+ sbuf.add(' return true;\n');
+ }
+ sbuf.add('}\n');
+ return sbuf.toString();
+ }
+
+ String isolateTests() {
+ return """
+runSlaveTest() {
+ port.receive((testName, sendport) {
+ unittest.configure(new TestRunnerConfiguration(sendport));
+ unittest.group('', test.main);
+ unittest.filterTests(testName);
+ unittest.runTests();
+ });
+}
+
+var testNum;
+var failed;
+
+runMasterTest() {
+ var tests = unittest.testCases;
+ SendPort sport = spawnFunction(runSlaveTest);
+ sport.call(tests[testNum].description).then((result) {
+ if (!result) failed = true;
+ ++testNum;
+ if (testNum < tests.length) {
+ runMasterTest();
+ } else if (failed) {
+ throw new Exception("Some tests failed.");
+ }
+ });
+}
+
+runIsolateTests() {
+ testNum = 0;
+ failed = false;
+ runMasterTest();
+}
+""";
+ }
+
+ String dartMain(String action, bool filter) {
+ return """
+main() {
+ unittest.groupSep = '###';
+ unittest.configure(new TestRunnerConfiguration());
+ unittest.group('', test.main);
+ ${filter?'unittest.filterTests(filterTest);':''}
+ $action();
+}
+""";
+ }
+
+}

Powered by Google App Engine
This is Rietveld 408576698