Permalink
Browse files

Make unexpected errors kill the process

I realized I was going to A LOT of effort to catch and report on
run-time errors in code, and this was majorly complicating the way the
whole library was being written.

But I figure if there is an error, it is something that is a show
stopper anyway, and you need to be notified about it immediately.

Suite runners will be notified of the error, right before the process
exits, so they can say what happened.

If you still really want errors to be caught, use the wrap function to
add a setup to all your tests and then set the uncaughtExceptionHandler
in the test.  You'll have to run the suite in parallel then.
  • Loading branch information...
1 parent 1221b9e commit e5090414e469636702d2a7617c418726e0c58555 Benjamin Thomas committed Oct 9, 2010
View
@@ -92,10 +92,7 @@ exports.run = function(list, options, callback) {
}
// some state
- var currentSuite = null
- , printedCurrentSuite = null
- , numSuites = null
- ;
+ var currentSuite, printedCurrentSuite, numSuites, lastStart, start = new Date();
opts =
{ parallel: options.parallel
@@ -105,6 +102,7 @@ exports.run = function(list, options, callback) {
numSuites = num;
}
, onSuiteStart: function(name) {
+ lastStart = new Date();
currentSuite = name;
printedCurrentSuite = false;
}
@@ -128,17 +126,9 @@ exports.run = function(list, options, callback) {
var totalAssertions = 0;
- var multiErrors = [];
-
for(var i = 0; i < tests.length; i++) {
var r = tests[i];
- if (typeof r.numAssertions != 'undefined') {
- totalAssertions += r.numAssertions;
- }
- else if (Array.isArray(r.failure)) {
- multiErrors.push(r);
- }
- else if (r.failure instanceof assert.AssertionError) {
+ if (r.failure) {
sys.puts(' Failure: '+red(r.name));
var s = r.failure.stack.split("\n");
sys.puts(' '+ s[0].substr(16));
@@ -157,58 +147,10 @@ exports.run = function(list, options, callback) {
}
}
else {
- sys.puts(' Error: '+yellow(r.name));
-
- if (r.failure.message) {
- sys.puts(' '+r.failure.message);
- }
- var s = r.failure.stack.split("\n");
- if (options.verbosity == 1) {
- if (s.length > 1) {
- sys.puts(s[1].replace(process.cwd(), '.'));
- }
- if (s.length > 2) {
- sys.puts(s[2].replace(process.cwd(), '.'));
- }
- }
- else {
- for(var k = 1; k < s.length; k++) {
- sys.puts(s[k].replace(process.cwd(), '.'));
- }
- }
+ totalAssertions += r.numAssertions;
}
}
- if (multiErrors.length) {
- sys.puts(' Non-specific errors: ' +
- multiErrors.map(function(el) { return yellow(el.name) }).join(', '));
-
- var errs = [];
-
- multiErrors.forEach(function(t) {
- t.failure.forEach(function(e) {
- if (errs.indexOf(e) < 0) {
- errs.push(e);
- var s = e.stack.split("\n");
- sys.puts(' + '+s[0]);
- if (options.verbosity == 1) {
- if (s.length > 1) {
- sys.puts(s[1].replace(process.cwd(), '.'));
- }
- if (s.length > 2) {
- sys.puts(s[2].replace(process.cwd(), '.'));
- }
- }
- else {
- for(var k = 1; k < s.length; k++) {
- sys.puts(s[k]);
- }
- }
- }
- });
- });
- }
-
var total = suiteResults.numFailures+suiteResults.numSuccesses;
if (suiteResults.numFailures > 0) {
@@ -218,10 +160,8 @@ exports.run = function(list, options, callback) {
sys.print(' FAILURES: '+suiteResults.numFailures+'/'+total+' tests failed.');
}
}
- else {
- if (options.verbosity > 0 && numSuites > 1) {
- sys.print(' '+green('OK: ')+total+' test'+(total == 1 ? '' : 's')+'. '+totalAssertions+' assertion'+(totalAssertions == 1 ? '' : 's')+'.');
- }
+ else if (options.verbosity > 0 && numSuites > 1) {
+ sys.print(' '+green('OK: ')+total+' test'+(total == 1 ? '' : 's')+'. '+totalAssertions+' assertion'+(totalAssertions == 1 ? '' : 's')+'.');
}
}
@@ -231,7 +171,7 @@ exports.run = function(list, options, callback) {
}
}
else if(suiteResults.numFailures > 0 || numSuites > 1) {
- sys.puts(' '+(suiteResults.duration/1000)+' seconds.');
+ sys.puts(' '+((new Date() - lastStart)/1000)+' seconds.');
sys.puts('');
}
}
@@ -246,18 +186,13 @@ exports.run = function(list, options, callback) {
}
if (result.failure) {
- if (result.failure instanceof assert.AssertionError) {
- sys.puts(red('' + result.name));
- }
- else {
- sys.puts(yellow('' + result.name))
- }
+ sys.puts(red('' + result.name));
}
else if (options.printSuccesses) {
sys.puts('' + result.name);
}
}
- , onDone: function(allResults, duration) {
+ , onDone: function(allResults) {
var successes = 0;
var total = 0;
var tests = 0;
@@ -287,10 +222,42 @@ exports.run = function(list, options, callback) {
sys.print(bold(' '+total+'/'+total+' suites passed successfully.'));
}
}
- sys.puts(bold(' ' + tests+(tests == 1 ? ' test' : ' total tests')+'. '+(duration/1000)+' seconds.'));
+ sys.puts(bold(' ' + tests+(tests == 1 ? ' test' : ' total tests')+'. '+((new Date() - start)/1000)+' seconds.'));
if (callback) {
- callback(allResults, duration);
+ callback(allResults);
+ }
+ }
+ , onError: function(err, tests) {
+ if (!printedCurrentSuite && currentSuite) {
+ sys.puts(bold(currentSuite));
+ }
+
+
+ if (tests.length > 1) {
+ sys.puts(' One of the following tests threw an error: ');
+ sys.puts(' ' + tests.map(function(name) { return yellow(name); }).join(', '));
+ }
+ else {
+ sys.puts(' Error: ' + yellow(tests[0]));
+ }
+
+ var s = err.stack.split("\n");
+ if (err.message) {
+ sys.puts(' '+err.message);
+ }
+ if (options.verbosity == 1) {
+ if (s.length > 1) {
+ sys.puts(s[1].replace(process.cwd(), '.'));
+ }
+ if (s.length > 2) {
+ sys.puts(s[2].replace(process.cwd(), '.'));
+ }
+ }
+ else {
+ for(var k = 1; k < s.length; k++) {
+ sys.puts(s[k]);
+ }
}
}
, onPrematureExit: function(tests) {
Oops, something went wrong.

0 comments on commit e509041

Please sign in to comment.