Skip to content

Commit 816dc27

Browse files
juergbaboneskull
authored andcommitted
uncaughtException: fix double EVENT_RUN_END events (#4025)
abort runner instead of end event
1 parent 9650d3f commit 816dc27

File tree

6 files changed

+41
-41
lines changed

6 files changed

+41
-41
lines changed

Diff for: lib/runner.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@ Runner.prototype.uncaught = function(err) {
865865
}
866866

867867
// bail
868-
this.emit(constants.EVENT_RUN_END);
868+
this.abort();
869869
};
870870

871871
/**
+4-4
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
'use strict';
22

3+
// we cannot recover gracefully if a Runnable has already passed
4+
// then fails asynchronously
35
it('test 1', function () {
4-
console.log('testbody1');
56
process.nextTick(function () {
67
throw new Error('Too bad');
78
});
89
});
910

1011
it('test 2', function () {
11-
console.log('testbody2');
12+
throw new Error('should not run - test 2');
1213
});
1314

1415
it('test 3', function () {
15-
console.log('testbody3');
16-
throw new Error('OUCH');
16+
throw new Error('should not run - test 3');
1717
});

Diff for: test/integration/fixtures/uncaught-fatal.fixture.js

+18-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
11
'use strict';
22

3-
it('should bail if a successful test asynchronously fails', function(done) {
4-
done();
5-
process.nextTick(function () {
6-
throw new Error('global error');
7-
});
8-
});
3+
describe('fatal uncaught exception', function () {
4+
describe('first suite', function () {
5+
it('should bail if a successful test asynchronously fails', function (done) {
6+
done();
7+
process.nextTick(function () {
8+
throw new Error('global error');
9+
});
10+
});
911

10-
it('should not actually get run', function () {
12+
it('should not actually get run', function () {
13+
throw new Error('should never throw - first suite');
14+
});
15+
});
16+
17+
describe('second suite', function () {
18+
it('should not actually get run', function () {
19+
throw new Error('should never throw - second suite');
20+
});
21+
});
1122
});

Diff for: test/integration/regression.spec.js

+8-13
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,17 @@ var run = require('./helpers').runMocha;
44
var runJSON = require('./helpers').runMochaJSON;
55

66
describe('regressions', function() {
7-
it('issue-1327: should run all 3 specs exactly once', function(done) {
7+
it('issue-1327: should run the first test and then bail', function(done) {
88
var args = [];
9-
run('regression/issue-1327.fixture.js', args, function(err, res) {
10-
var occurences = function(str) {
11-
var pattern = new RegExp(str, 'g');
12-
return (res.output.match(pattern) || []).length;
13-
};
14-
9+
runJSON('regression/issue-1327.fixture.js', args, function(err, res) {
1510
if (err) {
16-
done(err);
17-
return;
11+
return done(err);
1812
}
19-
expect(res, 'to have failed');
20-
expect(occurences('testbody1'), 'to be', 1);
21-
expect(occurences('testbody2'), 'to be', 1);
22-
expect(occurences('testbody3'), 'to be', 1);
13+
expect(res, 'to have failed')
14+
.and('to have passed test count', 1)
15+
.and('to have failed test count', 1)
16+
.and('to have passed test', 'test 1')
17+
.and('to have failed test', 'test 1');
2318
done();
2419
});
2520
});

Diff for: test/integration/uncaught.spec.js

+7-14
Original file line numberDiff line numberDiff line change
@@ -50,23 +50,16 @@ describe('uncaught exceptions', function() {
5050
it('handles uncaught exceptions from which Mocha cannot recover', function(done) {
5151
run('uncaught-fatal.fixture.js', args, function(err, res) {
5252
if (err) {
53-
done(err);
54-
return;
53+
return done(err);
5554
}
56-
assert.strictEqual(res.stats.pending, 0);
57-
assert.strictEqual(res.stats.passes, 1);
58-
assert.strictEqual(res.stats.failures, 1);
5955

60-
assert.strictEqual(
61-
res.failures[0].title,
62-
'should bail if a successful test asynchronously fails'
63-
);
64-
assert.strictEqual(
65-
res.passes[0].title,
66-
'should bail if a successful test asynchronously fails'
67-
);
56+
var testName = 'should bail if a successful test asynchronously fails';
57+
expect(res, 'to have failed')
58+
.and('to have passed test count', 1)
59+
.and('to have failed test count', 1)
60+
.and('to have passed test', testName)
61+
.and('to have failed test', testName);
6862

69-
assert.strictEqual(res.code, 1);
7063
done();
7164
});
7265
});

Diff for: test/unit/runner.spec.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -830,15 +830,16 @@ describe('Runner', function() {
830830
]).and('was called once');
831831
});
832832

833-
it('should notify run has ended', function() {
833+
it('should abort the runner without emitting end event', function() {
834834
expect(
835835
function() {
836836
runner.uncaught(err);
837837
},
838-
'to emit from',
838+
'not to emit from',
839839
runner,
840840
'end'
841841
);
842+
expect(runner._abort, 'to be', true);
842843
});
843844
});
844845

0 commit comments

Comments
 (0)