Browse Source

Improve failure output of the default mini reporter (#951)

hoisting-throws-helper
Juan Soto 8 years ago
committed by Sindre Sorhus
parent
commit
e4f90e0f7a
  1. 2
      lib/colors.js
  2. 52
      lib/reporters/mini.js
  3. 2
      lib/run-status.js
  4. 108
      test/reporters/mini.js

2
lib/colors.js

@ -2,10 +2,12 @@
var chalk = require('chalk');
module.exports = {
title: chalk.white,
error: chalk.red,
skip: chalk.yellow,
todo: chalk.blue,
pass: chalk.green,
duration: chalk.gray.dim,
errorStack: chalk.gray,
stack: chalk.red
};

52
lib/reporters/mini.js

@ -123,11 +123,11 @@ MiniReporter.prototype.unhandledError = function (err) {
MiniReporter.prototype.reportCounts = function (time) {
var lines = [
this.passCount > 0 ? '\n ' + colors.pass(this.passCount, 'passed') : '',
this.knownFailureCount > 0 ? '\n ' + colors.error(this.knownFailureCount, plur('known failure', this.knownFailureCount)) : '',
this.failCount > 0 ? '\n ' + colors.error(this.failCount, 'failed') : '',
this.skipCount > 0 ? '\n ' + colors.skip(this.skipCount, 'skipped') : '',
this.todoCount > 0 ? '\n ' + colors.todo(this.todoCount, 'todo') : ''
this.passCount > 0 ? '\n ' + colors.pass(this.passCount, 'passed') : '',
this.knownFailureCount > 0 ? '\n ' + colors.error(this.knownFailureCount, plur('known failure', this.knownFailureCount)) : '',
this.failCount > 0 ? '\n ' + colors.error(this.failCount, 'failed') : '',
this.skipCount > 0 ? '\n ' + colors.skip(this.skipCount, 'skipped') : '',
this.todoCount > 0 ? '\n ' + colors.todo(this.todoCount, 'todo') : ''
].filter(Boolean);
if (time && lines.length > 0) {
@ -148,15 +148,15 @@ MiniReporter.prototype.finish = function (runStatus) {
var status = this.reportCounts(time);
if (this.rejectionCount > 0) {
status += '\n ' + colors.error(this.rejectionCount, plur('rejection', this.rejectionCount));
status += '\n ' + colors.error(this.rejectionCount, plur('rejection', this.rejectionCount));
}
if (this.exceptionCount > 0) {
status += '\n ' + colors.error(this.exceptionCount, plur('exception', this.exceptionCount));
status += '\n ' + colors.error(this.exceptionCount, plur('exception', this.exceptionCount));
}
if (runStatus.previousFailCount > 0) {
status += '\n ' + colors.error(runStatus.previousFailCount, 'previous', plur('failure', runStatus.previousFailCount), 'in test files that were not rerun');
status += '\n ' + colors.error(runStatus.previousFailCount, 'previous', plur('failure', runStatus.previousFailCount), 'in test files that were not rerun');
}
var i = 0;
@ -167,7 +167,7 @@ MiniReporter.prototype.finish = function (runStatus) {
var title = test.title;
status += '\n\n\n ' + colors.error(i + '.', title);
status += '\n\n ' + colors.title(title);
// TODO output description with link
// status += colors.stack(description);
});
@ -181,10 +181,26 @@ MiniReporter.prototype.finish = function (runStatus) {
i++;
var description = ' ' + test.error.message + '\n ' + stripFirstLine(test.error.stack).trimRight();
var title = test.error ? test.title : 'Unhandled Error';
var description;
var errorTitle = ' ' + test.error.message + '\n';
var isPowerAssert = test.error.message.split('\n').length > 1;
status += '\n\n\n ' + colors.error(i + '.', test.title) + '\n';
status += colors.stack(description);
if (test.error) {
description = stripFirstLine(test.error.stack).trimRight();
} else {
description = JSON.stringify(test);
}
if (isPowerAssert) {
description = stripFirstLine(description).replace(/ {3}/g, ' ');
} else {
description.replace(/ {3}/g, ' ');
}
status += '\n\n ' + colors.title(title) + '\n';
status += colors.stack(errorTitle);
status += colors.errorStack(description);
});
}
@ -197,18 +213,22 @@ MiniReporter.prototype.finish = function (runStatus) {
i++;
if (err.type === 'exception' && err.name === 'AvaError') {
status += '\n\n\n ' + colors.error(cross + ' ' + err.message);
status += '\n\n ' + colors.error(cross + ' ' + err.message);
} else {
var title = err.type === 'rejection' ? 'Unhandled Rejection' : 'Uncaught Exception';
var description = err.stack ? err.stack.trimRight() : JSON.stringify(err);
description = description.split('\n');
var errorTitle = description[0];
var errorStack = description.slice(1).join('\n');
status += '\n\n\n ' + colors.error(i + '.', title) + '\n';
status += ' ' + colors.stack(description);
status += '\n\n ' + colors.title(title) + '\n';
status += ' ' + colors.stack(errorTitle) + '\n';
status += colors.errorStack(errorStack);
}
});
}
return status + '\n';
return status + '\n\n';
};
MiniReporter.prototype.section = function () {

2
lib/run-status.js

@ -107,7 +107,7 @@ RunStatus.prototype.handleTest = function (test) {
if (test.error) {
if (test.error.name !== 'AssertionError') {
test.error.message = 'failed with "' + test.error.message + '"';
test.error.message = 'Error: ' + test.error.message;
}
this.errors.push(test);

108
test/reporters/mini.js

@ -49,7 +49,7 @@ test('passing test', function (t) {
' ',
' ' + graySpinner + ' passed',
'',
' ' + chalk.green('1 passed')
' ' + chalk.green('1 passed')
].join('\n');
t.is(actualOutput, expectedOutput);
@ -68,8 +68,8 @@ test('known failure test', function (t) {
' ',
' ' + graySpinner + ' ' + chalk.red('known failure'),
'',
' ' + chalk.green('1 passed'),
' ' + chalk.red('1 known failure')
' ' + chalk.green('1 passed'),
' ' + chalk.red('1 known failure')
].join('\n');
t.is(actualOutput, expectedOutput);
@ -90,7 +90,7 @@ test('failing test', function (t) {
' ',
' ' + graySpinner + ' ' + chalk.red('failed'),
'',
' ' + chalk.red('1 failed')
' ' + chalk.red('1 failed')
].join('\n');
t.is(actualOutput, expectedOutput);
@ -112,7 +112,7 @@ test('failed known failure test', function (t) {
' ',
' ' + graySpinner + ' ' + chalk.red('known failure'),
'',
' ' + chalk.red('1 failed')
' ' + chalk.red('1 failed')
].join('\n');
t.is(actualOutput, expectedOutput);
@ -135,8 +135,8 @@ test('passing test after failing', function (t) {
' ',
' ' + graySpinner + ' passed',
'',
' ' + chalk.green('1 passed'),
' ' + chalk.red('1 failed')
' ' + chalk.green('1 passed'),
' ' + chalk.red('1 failed')
].join('\n');
t.is(actualOutput, expectedOutput);
@ -159,8 +159,8 @@ test('failing test after passing', function (t) {
' ',
' ' + graySpinner + ' ' + chalk.red('failed'),
'',
' ' + chalk.green('1 passed'),
' ' + chalk.red('1 failed')
' ' + chalk.green('1 passed'),
' ' + chalk.red('1 failed')
].join('\n');
t.is(actualOutput, expectedOutput);
@ -199,8 +199,8 @@ test('results with passing tests', function (t) {
var actualOutput = reporter.finish({});
var expectedOutput = [
'\n ' + chalk.green('1 passed'),
''
'\n ' + chalk.green('1 passed'),
'\n'
].join('\n');
t.is(actualOutput, expectedOutput);
@ -221,12 +221,11 @@ test('results with passing known failure tests', function (t) {
};
var actualOutput = reporter.finish(runStatus);
var expectedOutput = [
'\n ' + chalk.green('1 passed'),
' ' + chalk.red('1 known failure'),
'\n ' + chalk.green('1 passed'),
' ' + chalk.red('1 known failure'),
'',
'',
' ' + chalk.red('1. known failure'),
''
' ' + chalk.white('known failure'),
'\n'
].join('\n');
t.is(actualOutput, expectedOutput);
@ -241,8 +240,8 @@ test('results with skipped tests', function (t) {
var actualOutput = reporter.finish({});
var expectedOutput = [
'\n ' + chalk.yellow('1 skipped'),
''
'\n ' + chalk.yellow('1 skipped'),
'\n'
].join('\n');
t.is(actualOutput, expectedOutput);
@ -257,8 +256,8 @@ test('results with todo tests', function (t) {
var actualOutput = reporter.finish({});
var expectedOutput = [
'\n ' + chalk.blue('1 todo'),
''
'\n ' + chalk.blue('1 todo'),
'\n'
].join('\n');
t.is(actualOutput, expectedOutput);
@ -273,8 +272,8 @@ test('results with passing skipped tests', function (t) {
var output = reporter.finish({}).split('\n');
t.is(output[0], '');
t.is(output[1], ' ' + chalk.green('1 passed'));
t.is(output[2], ' ' + chalk.yellow('1 skipped'));
t.is(output[1], ' ' + chalk.green('1 passed'));
t.is(output[2], ' ' + chalk.yellow('1 skipped'));
t.is(output[3], '');
t.end();
});
@ -298,18 +297,16 @@ test('results with passing tests and rejections', function (t) {
var output = reporter.finish(runStatus);
compareLineOutput(t, output, [
'',
' ' + chalk.green('1 passed'),
' ' + chalk.red('1 rejection'),
'',
' ' + chalk.green('1 passed'),
' ' + chalk.red('1 rejection'),
'',
' ' + chalk.red('1. Unhandled Rejection'),
' ' + chalk.white('Unhandled Rejection'),
/Error: failure/,
/test\/reporters\/mini\.js/,
compareLineOutput.SKIP_UNTIL_EMPTY_LINE,
'',
'',
' ' + chalk.red('2. Unhandled Rejection'),
' ' + colors.stack('stack line with trailing whitespace')
' ' + chalk.white('Unhandled Rejection'),
' ' + colors.stack('stack line with trailing whitespace')
]);
t.end();
});
@ -333,17 +330,15 @@ test('results with passing tests and exceptions', function (t) {
var output = reporter.finish(runStatus);
compareLineOutput(t, output, [
'',
' ' + chalk.green('1 passed'),
' ' + chalk.red('2 exceptions'),
' ' + chalk.green('1 passed'),
' ' + chalk.red('2 exceptions'),
'',
'',
' ' + chalk.red('1. Uncaught Exception'),
' ' + chalk.white('Uncaught Exception'),
/Error: failure/,
/test\/reporters\/mini\.js/,
compareLineOutput.SKIP_UNTIL_EMPTY_LINE,
'',
'',
' ' + chalk.red(cross + ' A futuristic test runner')
' ' + chalk.red(cross + ' A futuristic test runner')
]);
t.end();
});
@ -368,20 +363,22 @@ test('results with errors', function (t) {
};
var output = reporter.finish(runStatus);
var expectedStack = colors.error(' failure two\n') + colors.errorStack('stack line with trailing whitespace');
expectedStack = expectedStack.split('\n');
compareLineOutput(t, output, [
'',
' ' + chalk.red('1 failed'),
' ' + chalk.red('1 failed'),
'',
'',
' ' + chalk.red('1. failed one'),
' ' + chalk.white('failed one'),
/failure/,
/test\/reporters\/mini\.js/,
compareLineOutput.SKIP_UNTIL_EMPTY_LINE,
'',
'',
' ' + chalk.red('2. failed two')
' ' + chalk.white('failed two')
].concat(
colors.stack(' failure two\n stack line with trailing whitespace').split('\n')
expectedStack
));
t.end();
});
@ -397,8 +394,8 @@ test('results with 1 previous failure', function (t) {
var output = reporter.finish(runStatus);
compareLineOutput(t, output, [
'',
' ' + colors.todo('1 todo'),
' ' + colors.error('1 previous failure in test files that were not rerun')
' ' + colors.todo('1 todo'),
' ' + colors.error('1 previous failure in test files that were not rerun')
]);
t.end();
});
@ -414,8 +411,8 @@ test('results with 2 previous failures', function (t) {
var output = reporter.finish(runStatus);
compareLineOutput(t, output, [
'',
' ' + colors.todo('1 todo'),
' ' + colors.error('2 previous failures in test files that were not rerun')
' ' + colors.todo('1 todo'),
' ' + colors.error('2 previous failures in test files that were not rerun')
]);
t.end();
});
@ -427,7 +424,7 @@ test('empty results after reset', function (t) {
reporter.reset();
var output = reporter.finish({});
t.is(output, '\n');
t.is(output, '\n\n');
t.end();
});
@ -449,8 +446,8 @@ test('results with watching enabled', function (t) {
var actualOutput = reporter.finish({});
var expectedOutput = [
'\n ' + chalk.green('1 passed') + time,
''
'\n ' + chalk.green('1 passed') + time,
'\n'
].join('\n');
t.is(actualOutput, expectedOutput);
@ -487,8 +484,8 @@ test('silently handles errors without body', function (t) {
};
var actualOutput = reporter.finish(runStatus);
var expectedOutput = [
'\n ' + colors.error('1 failed'),
''
'\n ' + colors.error('1 failed'),
'\n'
].join('\n');
t.is(actualOutput, expectedOutput);
t.end();
@ -504,8 +501,8 @@ test('does not handle errors with body in rejections', function (t) {
};
var actualOutput = reporter.finish(runStatus);
var expectedOutput = [
'\n ' + colors.error('1 rejection'),
''
'\n ' + colors.error('1 rejection'),
'\n'
].join('\n');
t.is(actualOutput, expectedOutput);
t.end();
@ -522,9 +519,10 @@ test('returns description based on error itself if no stack available', function
};
var actualOutput = reporter.finish(runStatus);
var expectedOutput = [
'\n ' + colors.error('1 exception'),
'\n\n ' + colors.error('1. Uncaught Exception'),
' ' + colors.stack(JSON.stringify({error: err1})) + '\n'
'\n ' + colors.error('1 exception'),
'\n ' + colors.title('Uncaught Exception'),
' ' + colors.stack(JSON.stringify({error: err1})),
'\n\n'
].join('\n');
t.is(actualOutput, expectedOutput);
t.end();

Loading…
Cancel
Save