Skip to content

Commit

Permalink
uncaughtException: fix double EVENT_RUN_END events (#4025)
Browse files Browse the repository at this point in the history
abort runner instead of end event
  • Loading branch information
juergba authored and boneskull committed Oct 18, 2019
1 parent 9650d3f commit 816dc27
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 41 deletions.
2 changes: 1 addition & 1 deletion lib/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,7 @@ Runner.prototype.uncaught = function(err) {
}

// bail
this.emit(constants.EVENT_RUN_END);
this.abort();
};

/**
Expand Down
8 changes: 4 additions & 4 deletions test/integration/fixtures/regression/issue-1327.fixture.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
'use strict';

// we cannot recover gracefully if a Runnable has already passed
// then fails asynchronously
it('test 1', function () {
console.log('testbody1');
process.nextTick(function () {
throw new Error('Too bad');
});
});

it('test 2', function () {
console.log('testbody2');
throw new Error('should not run - test 2');
});

it('test 3', function () {
console.log('testbody3');
throw new Error('OUCH');
throw new Error('should not run - test 3');
});
25 changes: 18 additions & 7 deletions test/integration/fixtures/uncaught-fatal.fixture.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
'use strict';

it('should bail if a successful test asynchronously fails', function(done) {
done();
process.nextTick(function () {
throw new Error('global error');
});
});
describe('fatal uncaught exception', function () {
describe('first suite', function () {
it('should bail if a successful test asynchronously fails', function (done) {
done();
process.nextTick(function () {
throw new Error('global error');
});
});

it('should not actually get run', function () {
it('should not actually get run', function () {
throw new Error('should never throw - first suite');
});
});

describe('second suite', function () {
it('should not actually get run', function () {
throw new Error('should never throw - second suite');
});
});
});
21 changes: 8 additions & 13 deletions test/integration/regression.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,17 @@ var run = require('./helpers').runMocha;
var runJSON = require('./helpers').runMochaJSON;

describe('regressions', function() {
it('issue-1327: should run all 3 specs exactly once', function(done) {
it('issue-1327: should run the first test and then bail', function(done) {
var args = [];
run('regression/issue-1327.fixture.js', args, function(err, res) {
var occurences = function(str) {
var pattern = new RegExp(str, 'g');
return (res.output.match(pattern) || []).length;
};

runJSON('regression/issue-1327.fixture.js', args, function(err, res) {
if (err) {
done(err);
return;
return done(err);
}
expect(res, 'to have failed');
expect(occurences('testbody1'), 'to be', 1);
expect(occurences('testbody2'), 'to be', 1);
expect(occurences('testbody3'), 'to be', 1);
expect(res, 'to have failed')
.and('to have passed test count', 1)
.and('to have failed test count', 1)
.and('to have passed test', 'test 1')
.and('to have failed test', 'test 1');
done();
});
});
Expand Down
21 changes: 7 additions & 14 deletions test/integration/uncaught.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,16 @@ describe('uncaught exceptions', function() {
it('handles uncaught exceptions from which Mocha cannot recover', function(done) {
run('uncaught-fatal.fixture.js', args, function(err, res) {
if (err) {
done(err);
return;
return done(err);
}
assert.strictEqual(res.stats.pending, 0);
assert.strictEqual(res.stats.passes, 1);
assert.strictEqual(res.stats.failures, 1);

assert.strictEqual(
res.failures[0].title,
'should bail if a successful test asynchronously fails'
);
assert.strictEqual(
res.passes[0].title,
'should bail if a successful test asynchronously fails'
);
var testName = 'should bail if a successful test asynchronously fails';
expect(res, 'to have failed')
.and('to have passed test count', 1)
.and('to have failed test count', 1)
.and('to have passed test', testName)
.and('to have failed test', testName);

assert.strictEqual(res.code, 1);
done();
});
});
Expand Down
5 changes: 3 additions & 2 deletions test/unit/runner.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -830,15 +830,16 @@ describe('Runner', function() {
]).and('was called once');
});

it('should notify run has ended', function() {
it('should abort the runner without emitting end event', function() {
expect(
function() {
runner.uncaught(err);
},
'to emit from',
'not to emit from',
runner,
'end'
);
expect(runner._abort, 'to be', true);
});
});

Expand Down

0 comments on commit 816dc27

Please sign in to comment.