Skip to content

Commit

Permalink
uncaughtException: fix when current test is pending (#4083)
Browse files Browse the repository at this point in the history
  • Loading branch information
juergba committed Nov 22, 2019
1 parent b9fbd69 commit 46ca9ac
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 5 deletions.
16 changes: 13 additions & 3 deletions lib/runner.js
Expand Up @@ -794,6 +794,10 @@ Runner.prototype.uncaught = function(err) {
if (err instanceof Pending) {
return;
}
if (this.allowUncaught) {
throw err;
}

if (err) {
debug('uncaught exception %O', err);
} else {
Expand Down Expand Up @@ -829,11 +833,17 @@ Runner.prototype.uncaught = function(err) {

runnable.clearTimeout();

// Ignore errors if already failed or pending
// See #3226
if (runnable.isFailed() || runnable.isPending()) {
if (runnable.isFailed()) {
// Ignore error if already failed
return;
} else if (runnable.isPending()) {
// report 'pending test' retrospectively as failed
runnable.isPending = alwaysFalse;
this.fail(runnable, err);
delete runnable.isPending;
return;
}

// we cannot recover gracefully if a Runnable has already passed
// then fails asynchronously
var alreadyPassed = runnable.isPassed();
Expand Down
@@ -0,0 +1,12 @@
'use strict';

describe('Uncaught exception - throw and exit', () => {
it('test1', () => {
setTimeout(() => {
throw new Error('Uncaught error after test1');
}, 1);
});
it('test2', function () { });
it('test3', function () { });
it('test4', function () { });
});
15 changes: 15 additions & 0 deletions test/integration/fixtures/uncaught-pending.fixture.js
@@ -0,0 +1,15 @@
'use strict';

describe('Uncaught exception within pending test', () => {
it('test1', function () { });

it('test2', function () {
process.nextTick(function () {
throw new Error('I am uncaught!');
});
this.skip();
});

it('test3 - should run', function () { });
it('test4 - should run', function () { });
});
21 changes: 21 additions & 0 deletions test/integration/options/allowUncaught.spec.js
Expand Up @@ -2,11 +2,32 @@

var path = require('path').posix;
var helpers = require('../helpers');
var runMocha = helpers.runMocha;
var runMochaJSON = helpers.runMochaJSON;

describe('--allow-uncaught', function() {
var args = ['--allow-uncaught'];

it('should throw an uncaught error and exit process', function(done) {
var fixture = path.join('options', 'allow-uncaught', 'propagate');
runMocha(
fixture,
args,
function(err, res) {
if (err) {
return done(err);
}

expect(res.code, 'to be greater than', 0);
expect(res.output, 'to contain', 'Error: Uncaught error after test1');
expect(res.passing, 'to be', 0);
expect(res.failing, 'to be', 0);
done();
},
{stdio: 'pipe'}
);
});

it('should run with conditional `this.skip()`', function(done) {
var fixture = path.join('options', 'allow-uncaught', 'this-skip-it');
runMochaJSON(fixture, args, function(err, res) {
Expand Down
23 changes: 23 additions & 0 deletions test/integration/uncaught.spec.js
Expand Up @@ -63,4 +63,27 @@ describe('uncaught exceptions', function() {
done();
});
});

it('handles uncaught exceptions within pending tests', function(done) {
run('uncaught-pending.fixture.js', args, function(err, res) {
if (err) {
return done(err);
}

expect(res, 'to have failed')
.and('to have passed test count', 3)
.and('to have pending test count', 1)
.and('to have failed test count', 1)
.and(
'to have passed test',
'test1',
'test3 - should run',
'test4 - should run'
)
.and('to have pending test order', 'test2')
.and('to have failed test', 'test2');

done();
});
});
});
4 changes: 2 additions & 2 deletions test/unit/runner.spec.js
Expand Up @@ -811,9 +811,9 @@ describe('Runner', function() {
sandbox.stub(runnable, 'isPending').returns(true);
});

it('should not attempt to fail', function() {
it('should attempt to fail', function() {
runner.uncaught(err);
expect(runner.fail, 'was not called');
expect(runner.fail, 'was called once');
});
});

Expand Down

0 comments on commit 46ca9ac

Please sign in to comment.