Skip to content

Commit

Permalink
Merge pull request #1564 from a8m/master
Browse files Browse the repository at this point in the history
shorten stack traces by default, add --full-trace
  • Loading branch information
Travis Jeffery committed Mar 9, 2015
2 parents 83e1bc8 + 558191d commit 369fb48
Show file tree
Hide file tree
Showing 9 changed files with 381 additions and 46 deletions.
5 changes: 5 additions & 0 deletions bin/_mocha
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ program
.option('-u, --ui <name>', 'specify user-interface (bdd|tdd|exports)', 'bdd')
.option('-w, --watch', 'watch files for changes')
.option('--check-leaks', 'check for global variable leaks')
.option('--full-trace', 'display the full stack trace')
.option('--compilers <ext>:<module>,...', 'use the given module(s) to compile files', list, [])
.option('--debug-brk', "enable node's debugger breaking on the first line")
.option('--globals <names>', 'allow the given comma-delimited global [names]', list, [])
Expand Down Expand Up @@ -258,6 +259,10 @@ if (program.invert) mocha.invert();

if (program.checkLeaks) mocha.checkLeaks();

// --stack-trace

if(program.fullTrace) mocha.fullTrace();

// --growl

if (program.growl) mocha.growl();
Expand Down
22 changes: 18 additions & 4 deletions lib/mocha.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ function image(name) {
* - `bail` bail on the first test failure
* - `slow` milliseconds to wait before considering a test slow
* - `ignoreLeaks` ignore global leaks
* - `fullTrace` display the full stack-trace on failing
* - `grep` string or regexp to filter tests with
*
* @param {Object} options
Expand All @@ -83,7 +84,7 @@ function Mocha(options) {
this.bail(options.bail);
this.reporter(options.reporter, options.reporterOptions);
if (null != options.timeout) this.timeout(options.timeout);
this.useColors(options.useColors)
this.useColors(options.useColors);
if (options.enableTimeouts !== null) this.enableTimeouts(options.enableTimeouts);
if (options.slow) this.slow(options.slow);

Expand Down Expand Up @@ -142,8 +143,8 @@ Mocha.prototype.reporter = function(reporter, reporterOptions){
} else {
reporter = reporter || 'spec';
var _reporter;
try { _reporter = require('./reporters/' + reporter); } catch (err) {};
if (!_reporter) try { _reporter = require(reporter); } catch (err) {};
try { _reporter = require('./reporters/' + reporter); } catch (err) {}
if (!_reporter) try { _reporter = require(reporter); } catch (err) {}
if (!_reporter && reporter === 'teamcity')
console.warn('The Teamcity reporter was moved to a package named ' +
'mocha-teamcity-reporter ' +
Expand All @@ -165,7 +166,7 @@ Mocha.prototype.reporter = function(reporter, reporterOptions){
Mocha.prototype.ui = function(name){
name = name || 'bdd';
this._ui = exports.interfaces[name];
if (!this._ui) try { this._ui = require(name); } catch (err) {};
if (!this._ui) try { this._ui = require(name); } catch (err) {}
if (!this._ui) throw new Error('invalid interface "' + name + '"');
this._ui = this._ui(this.suite);
return this;
Expand Down Expand Up @@ -266,6 +267,18 @@ Mocha.prototype.checkLeaks = function(){
return this;
};

/**
* Display long stack-trace on failing
*
* @return {Mocha}
* @api public
*/

Mocha.prototype.fullTrace = function() {
this.options.fullStackTrace = true;
return this;
};

/**
* Enable growl support.
*
Expand Down Expand Up @@ -409,6 +422,7 @@ Mocha.prototype.run = function(fn){
var runner = new exports.Runner(suite, options.delay);
var reporter = new this._reporter(runner, options);
runner.ignoreLeaks = false !== options.ignoreLeaks;
runner.fullStackTrace = options.fullStackTrace;
runner.asyncOnly = options.asyncOnly;
if (options.grep) runner.grep(options.grep, options.invert);
if (options.globals) runner.globals(options.globals);
Expand Down
39 changes: 21 additions & 18 deletions lib/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ var EventEmitter = require('events').EventEmitter
, filter = utils.filter
, keys = utils.keys
, type = utils.type
, stringify = utils.stringify;
, stringify = utils.stringify
, stackFilter = utils.stackTraceFilter();

/**
* Non-enumerable globals.
Expand Down Expand Up @@ -197,16 +198,18 @@ Runner.prototype.checkGlobals = function(test){
* @api private
*/

Runner.prototype.fail = function(test, err){
Runner.prototype.fail = function(test, err) {
++this.failures;
test.state = 'failed';

if ('string' == typeof err) {
err = new Error('the string "' + err + '" was thrown, throw an Error :)');
} else if (!(err instanceof Error)) {
if (!(err instanceof Error)) {
err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)');
}

err.stack = this.fullStackTrace
? err.stack
: stackFilter(err.stack);

this.emit('fail', test, err);
};

Expand Down Expand Up @@ -694,20 +697,20 @@ function filterLeaks(ok, globals) {
* @api private
*/

function extraGlobals() {
if (typeof(process) === 'object' &&
typeof(process.version) === 'string') {
function extraGlobals() {
if (typeof(process) === 'object' &&
typeof(process.version) === 'string') {

var nodeVersion = process.version.split('.').reduce(function(a, v) {
return a << 8 | v;
});
var nodeVersion = process.version.split('.').reduce(function(a, v) {
return a << 8 | v;
});

// 'errno' was renamed to process._errno in v0.9.11.
// 'errno' was renamed to process._errno in v0.9.11.

if (nodeVersion < 0x00090B) {
return ['errno'];
}
}

return [];
if (nodeVersion < 0x00090B) {
return ['errno'];
}
}

return [];
}
65 changes: 65 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -629,3 +629,68 @@ exports.getError = function(err) {
return err || exports.undefinedError();
};


/**
* @summary
* This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`)
* @description
* When invoking this function you get a filter function that get the Error.stack as an input,
* and return a prettify output.
* (i.e: strip Mocha, node_modules, bower and componentJS from stack trace).
* @returns {Function}
*/

exports.stackTraceFilter = function() {
var slash = '/'
, is = typeof document === 'undefined'
? { node: true }
: { browser: true }
, cwd = is.node
? process.cwd() + slash
: location.href.replace(/\/[^\/]*$/, '/');

function isNodeModule (line) {
return (~line.indexOf('node_modules'));
}

function isMochaInternal (line) {
return (~line.indexOf('node_modules' + slash + 'mocha')) ||
(~line.indexOf('components' + slash + 'mochajs')) ||
(~line.indexOf('components' + slash + 'mocha'));
}

// node_modules, bower, componentJS
function isBrowserModule(line) {
return (~line.indexOf('node_modules')) ||
(~line.indexOf('components'));
}

function isNodeInternal (line) {
return (~line.indexOf('(timers.js:')) ||
(~line.indexOf('(events.js:')) ||
(~line.indexOf('(node.js:')) ||
(~line.indexOf('(module.js:')) ||
(~line.indexOf('GeneratorFunctionPrototype.next (native)')) ||
false
}

return function(stack) {
stack = stack.split('\n');

stack = stack.reduce(function (list, line) {
if (is.node && (isNodeModule(line) ||
isMochaInternal(line) ||
isNodeInternal(line)))
return list;

if (is.browser && (isBrowserModule(line)))
return list;

// Clean up cwd(absolute)
list.push(line.replace(cwd, ''));
return list;
}, []);

return stack.join('\n');
}
};
Loading

0 comments on commit 369fb48

Please sign in to comment.