fb7b9e3c5c
BUG=http://dartbug.com/1424 Review URL: https://codereview.chromium.org//11770004 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@17549 260f80e4-7a28-3924-810f-c04153c831b5
286 lines
7.8 KiB
Dart
286 lines
7.8 KiB
Dart
// 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.
|
|
|
|
// TODO(gram): dart2js is not handling 'part of' properly yet; when it does
|
|
// uncomment this.
|
|
//part of test_controller;
|
|
|
|
/** Path to DRT executable. */
|
|
String drt;
|
|
|
|
/** Whether to include elapsed time. */
|
|
bool includeTime;
|
|
|
|
/** Whether to regenerate layout test files. */
|
|
bool regenerate;
|
|
|
|
/** Whether to output test summary. */
|
|
bool summarize;
|
|
|
|
/** Whether to print results immediately as they come in. */
|
|
bool immediate;
|
|
|
|
/** Format strings to use for test result messages. */
|
|
String listFormat, passFormat, failFormat, errorFormat;
|
|
|
|
/** Path of the running test file. */
|
|
String testfile;
|
|
|
|
/** The filters must be set by the caller. */
|
|
List includeFilters;
|
|
List excludeFilters;
|
|
|
|
/** The print function to use. */
|
|
Function tprint;
|
|
|
|
/** A callback function to notify the caller we are done. */
|
|
Function notifyDone;
|
|
|
|
/** The action function to use. */
|
|
Function action;
|
|
|
|
class Macros {
|
|
static const String testTime = '<TIME>';
|
|
static const String testfile = '<FILENAME>';
|
|
static const String testGroup = '<GROUPNAME>';
|
|
static const String testDescription = '<TESTNAME>';
|
|
static const String testMessage = '<MESSAGE>';
|
|
static const String testStacktrace = '<STACK>';
|
|
}
|
|
|
|
class TestRunnerConfiguration extends unittest.Configuration {
|
|
get name => 'Minimal test runner configuration';
|
|
get autoStart => false;
|
|
|
|
String formatMessage(filename, groupname,
|
|
[ testname = '', testTime = '', result = '',
|
|
message = '', stack = '' ]) {
|
|
var format = errorFormat;
|
|
if (result == 'pass') format = passFormat;
|
|
else if (result == 'fail') format = failFormat;
|
|
return format.
|
|
replaceAll(Macros.testTime, testTime).
|
|
replaceAll(Macros.testfile, filename).
|
|
replaceAll(Macros.testGroup, groupname).
|
|
replaceAll(Macros.testDescription, testname).
|
|
replaceAll(Macros.testMessage, message).
|
|
replaceAll(Macros.testStacktrace, stack);
|
|
}
|
|
|
|
String elapsed(unittest.TestCase t) {
|
|
if (includeTime) {
|
|
double duration = t.runningTime.inMilliseconds.toDouble();
|
|
duration /= 1000;
|
|
return '${duration.toStringAsFixed(3)}s ';
|
|
} else {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
void dumpTestResult(source, unittest.TestCase t) {
|
|
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 duration = elapsed(t);
|
|
tprint(formatMessage(source, '$groupName ', '$testName ',
|
|
duration, t.result, message, stack));
|
|
}
|
|
|
|
void onTestResult(unittest.TestCase testCase) {
|
|
if (immediate) {
|
|
dumpTestResult('$testfile ', testCase);
|
|
}
|
|
}
|
|
|
|
void printSummary(int passed, int failed, int errors,
|
|
[String uncaughtError = '']) {
|
|
tprint('');
|
|
if (passed == 0 && failed == 0 && errors == 0) {
|
|
tprint('$testfile: No tests found.');
|
|
} else if (failed == 0 && errors == 0 && uncaughtError == null) {
|
|
tprint('$testfile: All $passed tests passed.');
|
|
} else {
|
|
if (uncaughtError != null) {
|
|
tprint('$testfile: Top-level uncaught error: $uncaughtError');
|
|
}
|
|
tprint('$testfile: $passed PASSED, $failed FAILED, $errors ERRORS');
|
|
}
|
|
}
|
|
|
|
void onSummary(int passed, int failed, int errors,
|
|
List<unittest.TestCase> results, String uncaughtError) {
|
|
if (!immediate) {
|
|
for (final testCase in results) {
|
|
dumpTestResult('$testfile ', testCase);
|
|
}
|
|
}
|
|
if (summarize) {
|
|
printSummary(passed, failed, errors, uncaughtError);
|
|
}
|
|
}
|
|
|
|
void onDone(bool success) {
|
|
if (notifyDone != null) {
|
|
notifyDone(success ? 0 : -1);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Support for listing tests and groups. We use a minimal config.
|
|
class MinimalTestRunnerConfiguration extends unittest.Configuration {
|
|
get name => 'Minimal test runner configuration';
|
|
get autoStart => false;
|
|
}
|
|
|
|
String formatListMessage(filename, groupname, [ testname = '']) {
|
|
return listFormat.
|
|
replaceAll(Macros.testfile, filename).
|
|
replaceAll(Macros.testGroup, groupname).
|
|
replaceAll(Macros.testDescription, testname);
|
|
}
|
|
|
|
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.keys) {
|
|
var msg = formatListMessage('$testfile ', '$g ');
|
|
print('###$msg');
|
|
}
|
|
if (notifyDone != null) {
|
|
notifyDone(0);
|
|
}
|
|
}
|
|
|
|
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 = formatListMessage('$testfile ', '$groupName ', '$testName ');
|
|
print('###$msg');
|
|
}
|
|
if (notifyDone != null) {
|
|
notifyDone(0);
|
|
}
|
|
}
|
|
|
|
// Support for running in isolates.
|
|
|
|
class TestRunnerChildConfiguration extends unittest.Configuration {
|
|
get name => 'Test runner child configuration';
|
|
get autoStart => false;
|
|
|
|
void onSummary(int passed, int failed, int errors,
|
|
List<unittest.TestCase> results, String uncaughtError) {
|
|
unittest.TestCase test = results[0];
|
|
parentPort.send([test.result, test.runningTime.inMilliseconds,
|
|
test.message, test.stackTrace]);
|
|
}
|
|
}
|
|
|
|
var parentPort;
|
|
runChildTest() {
|
|
port.receive((testName, sendport) {
|
|
parentPort = sendport;
|
|
unittest.configure(new TestRunnerChildConfiguration());
|
|
unittest.groupSep = '###';
|
|
unittest.group('', test.main);
|
|
unittest.filterTests(testName);
|
|
unittest.runTests();
|
|
});
|
|
}
|
|
|
|
var testNum;
|
|
var failed;
|
|
var errors;
|
|
var passed;
|
|
|
|
runParentTest() {
|
|
var tests = unittest.testCases;
|
|
tests[testNum].startTime = new DateTime.now();
|
|
SendPort childPort = spawnFunction(runChildTest);
|
|
childPort.call(tests[testNum].description).then((results) {
|
|
var result = results[0];
|
|
var duration = new Duration(milliseconds: results[1]);
|
|
var message = results[2];
|
|
var stack = results[3];
|
|
if (result == 'pass') {
|
|
tests[testNum].pass();
|
|
++passed;
|
|
} else if (result == 'fail') {
|
|
tests[testNum].fail(message, stack);
|
|
++failed;
|
|
} else {
|
|
tests[testNum].error(message, stack);
|
|
++errors;
|
|
}
|
|
tests[testNum].runningTime = duration;
|
|
++testNum;
|
|
if (testNum < tests.length) {
|
|
runParentTest();
|
|
} else {
|
|
unittest.config.onDone(passed, failed, errors,
|
|
unittest.testCases, null);
|
|
}
|
|
});
|
|
}
|
|
|
|
runIsolateTests() {
|
|
testNum = 0;
|
|
passed = failed = errors = 0;
|
|
runParentTest();
|
|
}
|
|
|
|
// Main
|
|
|
|
filterTest(t) {
|
|
var name = t.description.replaceAll("###", " ");
|
|
if (includeFilters.length > 0) {
|
|
for (var f in includeFilters) {
|
|
if (name.indexOf(f) >= 0) return true;
|
|
}
|
|
return false;
|
|
} else if (excludeFilters.length > 0) {
|
|
for (var f in excludeFilters) {
|
|
if (name.indexOf(f) >= 0) return false;
|
|
}
|
|
return true;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
process(testMain, action) {
|
|
unittest.groupSep = '###';
|
|
unittest.configure(new TestRunnerConfiguration());
|
|
unittest.group('', testMain);
|
|
// Do any user-specified test filtering.
|
|
unittest.filterTests(filterTest);
|
|
action();
|
|
}
|