Skip to content

Commit

Permalink
Deprecate this.skip() for "after all" hooks (#3719)
Browse files Browse the repository at this point in the history
Print a DeprecationWarning when `this.skip()` is used in `after` hooks.
  • Loading branch information
juergba authored and boneskull committed Apr 2, 2019
1 parent 81cfa90 commit e87c689
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 4 deletions.
6 changes: 4 additions & 2 deletions docs/index.md
Expand Up @@ -626,7 +626,7 @@ Because this test _does nothing_, it will be reported as _passing_.

> _Best practice_: Don't do nothing! A test should make an assertion or use `this.skip()`.
To skip _multiple_ tests in this manner, use `this.skip()` in a "before" hook:
To skip _multiple_ tests in this manner, use `this.skip()` in a "before all" hook:

```js
before(function() {
Expand Down Expand Up @@ -662,6 +662,8 @@ describe('outer', function() {
});
```

Skipping a test within an "after all" hook is deprecated and will throw an exception in a future version of Mocha. Use a return statement or other means to abort hook execution.

> Before Mocha v3.0.0, `this.skip()` was not supported in asynchronous tests and hooks.
## Retry Tests
Expand Down Expand Up @@ -910,7 +912,7 @@ Enforce a rule that tests must be written in "async" style, meaning each test pr

### `--bail, -b`

Causes Mocha to stop running tests after the first test failure it encounters. Corresponding `after()` and `afterEach()` hooks are executed for potential cleanup.
Causes Mocha to stop running tests after the first test failure it encounters. Corresponding "after each" and "after all" hooks are executed for potential cleanup.

`--bail` does _not_ imply `--exit`.

Expand Down
10 changes: 8 additions & 2 deletions lib/runner.js
Expand Up @@ -363,9 +363,9 @@ Runner.prototype.hook = function(name, fn) {
}
self.currentRunnable = hook;

if (name === 'beforeAll') {
if (name === HOOK_TYPE_BEFORE_ALL) {
hook.ctx.currentTest = hook.parent.tests[0];
} else if (name === 'afterAll') {
} else if (name === HOOK_TYPE_AFTER_ALL) {
hook.ctx.currentTest = hook.parent.tests[hook.parent.tests.length - 1];
} else {
hook.ctx.currentTest = self.test;
Expand All @@ -388,6 +388,12 @@ Runner.prototype.hook = function(name, fn) {
}
if (err) {
if (err instanceof Pending) {
if (name === HOOK_TYPE_AFTER_ALL) {
utils.deprecate(
'Skipping a test within an "after all" hook is DEPRECATED and will throw an exception in a future version of Mocha. ' +
'Use a return statement or other means to abort hook execution.'
);
}
if (name === HOOK_TYPE_BEFORE_EACH || name === HOOK_TYPE_AFTER_EACH) {
if (self.test) {
self.test.pending = true;
Expand Down
18 changes: 18 additions & 0 deletions test/integration/fixtures/pending/skip-sync-after.fixture.js
@@ -0,0 +1,18 @@
'use strict';

describe('skip in after', function () {
it('should run this test-1', function () {});

after('should print DeprecationWarning', function () {
this.skip();
throw new Error('never throws this error');
});

describe('inner suite', function () {
it('should run this test-2', function () {});
});
});

describe('second suite', function () {
it('should run this test-3', function () {});
});
22 changes: 22 additions & 0 deletions test/integration/pending.spec.js
Expand Up @@ -71,6 +71,28 @@ describe('pending', function() {
});
});

describe('in after', function() {
it('should run all tests', function(done) {
runMocha(
'pending/skip-sync-after.fixture.js',
args,
function(err, res) {
if (err) {
return done(err);
}
expect(res, 'to have passed').and('to satisfy', {
passing: 3,
failing: 0,
pending: 0,
output: expect.it('to contain', '"after all" hook is DEPRECATED')
});
done();
},
'pipe'
);
});
});

describe('in before', function() {
it('should skip all suite specs', function(done) {
run('pending/skip-sync-before.fixture.js', args, function(err, res) {
Expand Down

0 comments on commit e87c689

Please sign in to comment.