Skip to content
This repository was archived by the owner on Dec 4, 2023. It is now read-only.

Commit 9c83f23

Browse files
juergbaboneskull
authored andcommitted
Behavior of after/afterEach hooks with --bail flag (mochajs#3617)
* runner.js: delete second end emit * tests * documentation * runner.js * tests: corrections closes mochajs#3398, closes mochajs#3598, closes mochajs#3457, closes mochajs#3617
1 parent 0a0e518 commit 9c83f23

File tree

11 files changed

+351
-31
lines changed

11 files changed

+351
-31
lines changed

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ Enforce a rule that tests must be written in "async" style, meaning each test pr
909909

910910
### `--bail, -b`
911911

912-
Causes Mocha to stop running tests after the first test failure it encounters.
912+
Causes Mocha to stop running tests after the first test failure it encounters. Corresponding `after()` and `afterEach()` hooks are executed for potential cleanup.
913913

914914
`--bail` does *not* imply `--exit`.
915915

lib/runner.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -241,16 +241,14 @@ Runner.prototype.fail = function(test, err) {
241241
}
242242

243243
this.emit('fail', test, err);
244-
if (this.suite.bail()) {
245-
this.emit('end');
246-
}
247244
};
248245

249246
/**
250247
* Fail the given `hook` with `err`.
251248
*
252249
* Hook failures work in the following pattern:
253-
* - If bail, then exit
250+
* - If bail, run corresponding `after each` and `after` hooks,
251+
* then exit
254252
* - Failed `before` hook skips all tests in a suite and subsuites,
255253
* but jumps to corresponding `after` hook
256254
* - Failed `before each` hook skips remaining tests in a
@@ -494,7 +492,7 @@ Runner.prototype.runTests = function(suite, fn) {
494492
function next(err, errSuite) {
495493
// if we bail after first err
496494
if (self.failures && suite._bail) {
497-
return fn();
495+
tests = [];
498496
}
499497

500498
if (self._abort) {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use strict';
2+
3+
describe('suite1', function () {
4+
it('should display this spec', function () {});
5+
6+
it('should only display this error', function (done) {
7+
throw new Error('this should be displayed');
8+
});
9+
10+
it('should not display this error', function (done) {
11+
throw new Error('this should not be displayed');
12+
});
13+
});
14+
15+
describe('suite2', function () {
16+
before(function (done) {
17+
throw new Error('this hook should not be displayed');
18+
});
19+
20+
it('should not display this error', function (done) {
21+
throw new Error('this should not be displayed');
22+
});
23+
});
Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,57 @@
11
'use strict';
2+
var assert = require('assert');
23

34
describe('suite1', function () {
4-
it('should only display this error', function () {
5-
throw new Error('this should be displayed');
5+
var runOrder = [];
6+
before('before suite1', function () {
7+
runOrder.push('before suite1');
68
});
9+
beforeEach('beforeEach suite1', function () {
10+
runOrder.push('beforeEach suite1');
11+
});
12+
it('test suite1', function () {
13+
runOrder.push('test suite1');
14+
});
15+
16+
describe('suite1A', function () {
17+
before('before suite1A', function () {
18+
runOrder.push('before suite1A');
19+
});
20+
beforeEach('beforeEach suite1A', function () {
21+
runOrder.push('beforeEach suite1A');
22+
});
23+
it('test suite1A', function () {
24+
runOrder.push('test suite1A');
25+
});
26+
afterEach('afterEach suite1A', function () {
27+
runOrder.push('afterEach suite1A');
28+
});
29+
after('after suite1A', function () {
30+
runOrder.push('after suite1A');
31+
throw new Error('after suite1A error');
32+
});
33+
});
34+
35+
afterEach('afterEach suite1', function () {
36+
runOrder.push('afterEach suite1');
37+
});
38+
after('after suite1', function () {
39+
runOrder.push('after suite1');
40+
assert.deepStrictEqual(runOrder, [
41+
'before suite1', 'beforeEach suite1', 'test suite1',
42+
'afterEach suite1', 'before suite1A', 'beforeEach suite1',
43+
'beforeEach suite1A', 'test suite1A', 'afterEach suite1A',
44+
'afterEach suite1', 'after suite1A', 'after suite1'
45+
]);
46+
});
47+
});
748

8-
after(function () {
9-
throw new Error('this hook should not be displayed');
49+
describe('suite2', function () {
50+
before('before suite2', function () {});
51+
beforeEach('beforeEach suite2', function () {});
52+
it('test suite2', function () {
53+
runOrder.push('test suite2 - should not run');
1054
});
55+
afterEach('afterEach suite2', function () {});
56+
after('after suite2', function () {});
1157
});
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
'use strict';
2+
var assert = require('assert');
3+
4+
describe('suite1', function () {
5+
var runOrder = [];
6+
before('before suite1', function () {
7+
runOrder.push('before suite1');
8+
});
9+
beforeEach('beforeEach suite1', function () {
10+
runOrder.push('beforeEach suite1');
11+
});
12+
it('test suite1', function () {
13+
runOrder.push('test suite1');
14+
});
15+
16+
describe('suite1A', function () {
17+
before('before suite1A', function () {
18+
runOrder.push('before suite1A');
19+
});
20+
beforeEach('beforeEach suite1A', function () {
21+
runOrder.push('beforeEach suite1A');
22+
});
23+
it('test suite1A', function () {
24+
runOrder.push('test suite1A');
25+
});
26+
afterEach('afterEach suite1A', function () {
27+
runOrder.push('afterEach suite1A');
28+
throw new Error('afterEach suite1A error');
29+
});
30+
after('after suite1A', function () {
31+
runOrder.push('after suite1A');
32+
});
33+
});
34+
35+
afterEach('afterEach suite1', function () {
36+
runOrder.push('afterEach suite1');
37+
});
38+
after('after suite1', function () {
39+
runOrder.push('after suite1');
40+
assert.deepStrictEqual(runOrder, [
41+
'before suite1', 'beforeEach suite1', 'test suite1',
42+
'afterEach suite1', 'before suite1A', 'beforeEach suite1',
43+
'beforeEach suite1A', 'test suite1A', 'afterEach suite1A',
44+
'afterEach suite1', 'after suite1A', 'after suite1'
45+
]);
46+
});
47+
});
48+
49+
describe('suite2', function () {
50+
before('before suite2', function () {});
51+
beforeEach('beforeEach suite2', function () {});
52+
it('test suite2', function () {
53+
runOrder.push('test suite2 - should not run');
54+
});
55+
afterEach('afterEach suite2', function () {});
56+
after('after suite2', function () {});
57+
});
Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,44 @@
11
'use strict';
2+
var assert = require('assert');
23

34
describe('suite1', function () {
4-
before(function () {
5-
throw new Error('this hook should be only displayed');
5+
var runOrder = [];
6+
before('before suite1', function () {
7+
runOrder.push('before suite1');
8+
throw new Error('before suite1 error');
69
});
10+
beforeEach('beforeEach suite1', function () {
11+
runOrder.push('beforeEach suite1 - should not run');
12+
});
13+
it('test suite1', function () {
14+
runOrder.push('test suite1 - should not run');
15+
});
16+
17+
describe('suite1A', function () {
18+
before('before suite1A', function () {});
19+
beforeEach('beforeEach suite1A', function () {});
20+
it('test suite1A', function () {
21+
runOrder.push('test suite1A - should not run');
22+
});
23+
afterEach('afterEach suite1A', function () {});
24+
after('after suite1A', function () {});
25+
});
26+
27+
afterEach('afterEach suite1', function () {
28+
runOrder.push('afterEach suite1 - should not run');
29+
});
30+
after('after suite1', function () {
31+
runOrder.push('after suite1');
32+
assert.deepStrictEqual(runOrder, ['before suite1', 'after suite1']);
33+
});
34+
});
735

8-
it('should not display this error', function () {
9-
throw new Error('this should not be displayed');
36+
describe('suite2', function () {
37+
before('before suite2', function () {});
38+
beforeEach('beforeEach suite2', function () {});
39+
it('test suite2', function () {
40+
runOrder.push('test suite2 - should not run');
1041
});
42+
afterEach('afterEach suite2', function () {});
43+
after('after suite2', function () {});
1144
});
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
var assert = require('assert');
3+
4+
describe('suite1', function () {
5+
var runOrder = [];
6+
before('before suite1', function () {
7+
runOrder.push('before suite1');
8+
});
9+
beforeEach('beforeEach suite1', function () {
10+
runOrder.push('beforeEach suite1');
11+
throw new Error('beforeEach suite1 error');
12+
});
13+
it('test suite1', function () {
14+
runOrder.push('test suite1 - should not run');
15+
});
16+
17+
describe('suite1A', function () {
18+
before('before suite1A', function () {});
19+
beforeEach('beforeEach suite1A', function () {});
20+
it('test suite1A', function () {
21+
runOrder.push('test suite1A - should not run');
22+
});
23+
afterEach('afterEach suite1A', function () {});
24+
after('after suite1A', function () {});
25+
});
26+
27+
afterEach('afterEach suite1', function () {
28+
runOrder.push('afterEach suite1');
29+
});
30+
after('after suite1', function () {
31+
runOrder.push('after suite1');
32+
assert.deepStrictEqual(runOrder, [
33+
'before suite1', 'beforeEach suite1', 'afterEach suite1', 'after suite1'
34+
]);
35+
});
36+
});
37+
38+
describe('suite2', function () {
39+
before('before suite2', function () {});
40+
beforeEach('beforeEach suite2', function () {});
41+
it('test suite2', function () {
42+
runOrder.push('test suite2 - should not run');
43+
});
44+
afterEach('afterEach suite2', function () {});
45+
after('after suite2', function () {});
46+
});
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
'use strict';
2+
var assert = require('assert');
3+
4+
describe('suite1', function () {
5+
var runOrder = [];
6+
before('before suite1', function () {
7+
runOrder.push('before suite1');
8+
});
9+
beforeEach('beforeEach suite1', function () {
10+
runOrder.push('beforeEach suite1');
11+
});
12+
it('test suite1', function () {
13+
runOrder.push('test suite1');
14+
throw new Error('test suite1 error');
15+
});
16+
17+
describe('suite1A', function () {
18+
before('before suite1A', function () {});
19+
beforeEach('beforeEach suite1A', function () {});
20+
it('test suite1A', function () {
21+
runOrder.push('test suite1A - should not run');
22+
});
23+
afterEach('afterEach suite1A', function () {});
24+
after('after suite1A', function () {});
25+
});
26+
27+
afterEach('afterEach suite1', function () {
28+
runOrder.push('afterEach suite1');
29+
});
30+
after('after suite1', function () {
31+
runOrder.push('after suite1');
32+
assert.deepStrictEqual(runOrder, [
33+
'before suite1', 'beforeEach suite1', 'test suite1',
34+
'afterEach suite1', 'after suite1'
35+
]);
36+
});
37+
});
38+
39+
describe('suite2', function () {
40+
before('before suite2', function () {});
41+
beforeEach('beforeEach suite2', function () {});
42+
it('test suite2', function () {
43+
runOrder.push('test suite2 - should not run');
44+
});
45+
afterEach('afterEach suite2', function () {});
46+
after('after suite2', function () {});
47+
});

test/integration/fixtures/options/bail.fixture.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@
33
describe('suite1', function () {
44
it('should display this spec', function () {});
55

6-
it('should only display this error', function (done) {
6+
it('should only display this error', function () {
77
throw new Error('this should be displayed');
88
});
99

10-
it('should not display this error', function (done) {
10+
it('should not display this error', function () {
1111
throw new Error('this should not be displayed');
1212
});
1313
});
1414

1515
describe('suite2', function () {
16-
before(function (done) {
16+
before(function () {
1717
throw new Error('this hook should not be displayed');
1818
});
1919

20-
it('should not display this error', function (done) {
20+
it('should not display this error', function () {
2121
throw new Error('this should not be displayed');
2222
});
2323
});

0 commit comments

Comments
 (0)