Skip to content

Commit

Permalink
added allowUncaught option (mochajs#553)
Browse files Browse the repository at this point in the history
  • Loading branch information
amsul committed Apr 17, 2015
1 parent f9fad1b commit c4f0c42
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 34 deletions.
13 changes: 13 additions & 0 deletions lib/mocha.js
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,18 @@ Mocha.prototype.noHighlighting = function() {
return this;
};

/**
* Enable uncaught errors to propagate (in browser).
*
* @return {Mocha}
* @api public
*/

Mocha.prototype.allowUncaught = function(){
this.options.allowUncaught = global.mocha.allowUncaught = true;
return this;
};

/**
* Delay root suite execution.
* @returns {Mocha}
Expand Down Expand Up @@ -428,6 +440,7 @@ Mocha.prototype.run = function(fn){
runner.ignoreLeaks = false !== options.ignoreLeaks;
runner.fullStackTrace = options.fullStackTrace;
runner.asyncOnly = options.asyncOnly;
runner.allowUncaught = options.allowUncaught;
if (options.grep) runner.grep(options.grep, options.invert);
if (options.globals) runner.globals(options.globals);
if (options.growl) this._growl(runner, reporter);
Expand Down
36 changes: 24 additions & 12 deletions lib/runnable.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,18 +229,10 @@ Runnable.prototype.run = function(fn){
if (this.async) {
this.resetTimeout();

try {
this.fn.call(ctx, function(err){
if (err instanceof Error || toString.call(err) === "[object Error]") return done(err);
if (null != err) {
if (Object.prototype.toString.call(err) === '[object Object]') {
return done(new Error('done() invoked with non-Error: ' + JSON.stringify(err)));
} else {
return done(new Error('done() invoked with non-Error: ' + err));
}
}
done();
});
if (this.allowUncaught) {
callFnAsync(this.fn);
} else try {
callFnAsync(this.fn);
} catch (err) {
done(utils.getError(err));
}
Expand All @@ -251,6 +243,12 @@ Runnable.prototype.run = function(fn){
return done(new Error('--async-only option in use without declaring `done()`'));
}

if (this.allowUncaught) {
callFn(this.fn);
done();
return;
}

// sync or promise-returning
try {
if (this.pending) {
Expand All @@ -277,4 +275,18 @@ Runnable.prototype.run = function(fn){
done();
}
}

function callFnAsync(fn) {
fn.call(ctx, function(err){
if (err instanceof Error || toString.call(err) === "[object Error]") return done(err);
if (null != err) {
if (Object.prototype.toString.call(err) === '[object Object]') {
return done(new Error('done() invoked with non-Error: ' + JSON.stringify(err)));
} else {
return done(new Error('done() invoked with non-Error: ' + err));
}
}
done();
});
}
};
5 changes: 4 additions & 1 deletion lib/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,10 @@ Runner.prototype.runTest = function(fn){

if (this.asyncOnly) test.asyncOnly = true;

try {
if (this.allowUncaught) {
test.allowUncaught = true;
test.run(fn);
} else try {
test.on('error', function(err){
self.fail(test, err);
});
Expand Down
64 changes: 47 additions & 17 deletions mocha.js
Original file line number Diff line number Diff line change
Expand Up @@ -1805,6 +1805,18 @@ Mocha.prototype.noHighlighting = function() {
return this;
};

/**
* Enable uncaught errors to propagate (in browser).
*
* @return {Mocha}
* @api public
*/

Mocha.prototype.allowUncaught = function(){
this.options.allowUncaught = global.mocha.allowUncaught = true;
return this;
};

/**
* Delay root suite execution.
* @returns {Mocha}
Expand Down Expand Up @@ -1832,6 +1844,7 @@ Mocha.prototype.run = function(fn){
runner.ignoreLeaks = false !== options.ignoreLeaks;
runner.fullStackTrace = options.fullStackTrace;
runner.asyncOnly = options.asyncOnly;
runner.allowUncaught = options.allowUncaught;
if (options.grep) runner.grep(options.grep, options.invert);
if (options.globals) runner.globals(options.globals);
if (options.growl) this._growl(runner, reporter);
Expand Down Expand Up @@ -4525,18 +4538,10 @@ Runnable.prototype.run = function(fn){
if (this.async) {
this.resetTimeout();

try {
this.fn.call(ctx, function(err){
if (err instanceof Error || toString.call(err) === "[object Error]") return done(err);
if (null != err) {
if (Object.prototype.toString.call(err) === '[object Object]') {
return done(new Error('done() invoked with non-Error: ' + JSON.stringify(err)));
} else {
return done(new Error('done() invoked with non-Error: ' + err));
}
}
done();
});
if (this.allowUncaught) {
callFnAsync(this.fn);
} else try {
callFnAsync(this.fn);
} catch (err) {
done(utils.getError(err));
}
Expand All @@ -4547,6 +4552,12 @@ Runnable.prototype.run = function(fn){
return done(new Error('--async-only option in use without declaring `done()`'));
}

if (this.allowUncaught) {
callFn(this.fn);
done();
return;
}

// sync or promise-returning
try {
if (this.pending) {
Expand All @@ -4573,6 +4584,20 @@ Runnable.prototype.run = function(fn){
done();
}
}

function callFnAsync(fn) {
fn.call(ctx, function(err){
if (err instanceof Error || toString.call(err) === "[object Error]") return done(err);
if (null != err) {
if (Object.prototype.toString.call(err) === '[object Object]') {
return done(new Error('done() invoked with non-Error: ' + JSON.stringify(err)));
} else {
return done(new Error('done() invoked with non-Error: ' + err));
}
}
done();
});
}
};

}); // module: runnable.js
Expand Down Expand Up @@ -4967,7 +4992,10 @@ Runner.prototype.runTest = function(fn){

if (this.asyncOnly) test.asyncOnly = true;

try {
if (this.allowUncaught) {
test.allowUncaught = true;
test.run(fn);
} else try {
test.on('error', function(err){
self.fail(test, err);
});
Expand Down Expand Up @@ -6454,10 +6482,12 @@ process.removeListener = function(e, fn){

process.on = function(e, fn){
if ('uncaughtException' == e) {
global.onerror = function(err, url, line){
fn(new Error(err + ' (' + url + ':' + line + ')'));
return true;
};
if (!mocha.allowUncaught) {
global.onerror = function(err, url, line){
fn(new Error(err + ' (' + url + ':' + line + ')'));
return true;
};
}
uncaughtExceptionHandlers.push(fn);
}
};
Expand Down
10 changes: 6 additions & 4 deletions support/tail.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,12 @@ process.removeListener = function(e, fn){

process.on = function(e, fn){
if ('uncaughtException' == e) {
global.onerror = function(err, url, line){
fn(new Error(err + ' (' + url + ':' + line + ')'));
return true;
};
if (!mocha.allowUncaught) {
global.onerror = function(err, url, line){
fn(new Error(err + ' (' + url + ':' + line + ')'));
return true;
};
}
uncaughtExceptionHandlers.push(fn);
}
};
Expand Down

0 comments on commit c4f0c42

Please sign in to comment.