From e3da641b08bed20f12df524fc64cb9579f980c1e Mon Sep 17 00:00:00 2001 From: Julian Grinblat Date: Thu, 31 Oct 2024 01:45:53 +0900 Subject: [PATCH] feat: allow calling hook methods (#5231) * feat(suite): allow calling hook methods * add tests and docs * fix * address comment --- docs/index.md | 11 +++++++++++ lib/interfaces/common.js | 8 ++++---- lib/suite.js | 8 ++++---- test/unit/timeout.spec.js | 26 ++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/docs/index.md b/docs/index.md index 1eba83acfb..cb14bb52b2 100644 --- a/docs/index.md +++ b/docs/index.md @@ -334,6 +334,17 @@ describe('my suite', () => { _If you do not need to use_ Mocha's context, lambdas should work. Be aware that using lambdas will be more painful to refactor if the need eventually arises! +Alternatively, you can override certain context variables, such as test timeouts, by chain-calling methods of the created tests and/or hooks: + +```js +describe('my suite', () => { + beforeEach(() => {}).timeout(1000); + it('my test', () => { + assert.ok(true); + }).timeout(1000); +}).timeout(1000); +``` + ## Hooks With its default "BDD"-style interface, Mocha provides the hooks `before()`, `after()`, `beforeEach()`, and `afterEach()`. These should be used to set up preconditions and clean up after your tests. diff --git a/lib/interfaces/common.js b/lib/interfaces/common.js index ba8b5f85ed..d6656b8cc6 100644 --- a/lib/interfaces/common.js +++ b/lib/interfaces/common.js @@ -57,7 +57,7 @@ module.exports = function (suites, context, mocha) { * @param {Function} fn */ before: function (name, fn) { - suites[0].beforeAll(name, fn); + return suites[0].beforeAll(name, fn); }, /** @@ -67,7 +67,7 @@ module.exports = function (suites, context, mocha) { * @param {Function} fn */ after: function (name, fn) { - suites[0].afterAll(name, fn); + return suites[0].afterAll(name, fn); }, /** @@ -77,7 +77,7 @@ module.exports = function (suites, context, mocha) { * @param {Function} fn */ beforeEach: function (name, fn) { - suites[0].beforeEach(name, fn); + return suites[0].beforeEach(name, fn); }, /** @@ -87,7 +87,7 @@ module.exports = function (suites, context, mocha) { * @param {Function} fn */ afterEach: function (name, fn) { - suites[0].afterEach(name, fn); + return suites[0].afterEach(name, fn); }, suite: { diff --git a/lib/suite.js b/lib/suite.js index 64d7183fdf..bce00731ec 100644 --- a/lib/suite.js +++ b/lib/suite.js @@ -257,7 +257,7 @@ Suite.prototype.beforeAll = function (title, fn) { var hook = this._createHook(title, fn); this._beforeAll.push(hook); this.emit(constants.EVENT_SUITE_ADD_HOOK_BEFORE_ALL, hook); - return this; + return hook; }; /** @@ -281,7 +281,7 @@ Suite.prototype.afterAll = function (title, fn) { var hook = this._createHook(title, fn); this._afterAll.push(hook); this.emit(constants.EVENT_SUITE_ADD_HOOK_AFTER_ALL, hook); - return this; + return hook; }; /** @@ -305,7 +305,7 @@ Suite.prototype.beforeEach = function (title, fn) { var hook = this._createHook(title, fn); this._beforeEach.push(hook); this.emit(constants.EVENT_SUITE_ADD_HOOK_BEFORE_EACH, hook); - return this; + return hook; }; /** @@ -329,7 +329,7 @@ Suite.prototype.afterEach = function (title, fn) { var hook = this._createHook(title, fn); this._afterEach.push(hook); this.emit(constants.EVENT_SUITE_ADD_HOOK_AFTER_EACH, hook); - return this; + return hook; }; /** diff --git a/test/unit/timeout.spec.js b/test/unit/timeout.spec.js index ed65156341..bb758a5e50 100644 --- a/test/unit/timeout.spec.js +++ b/test/unit/timeout.spec.js @@ -70,5 +70,31 @@ describe('timeouts', function () { }); }); }); + + describe('chaining calls', function () { + before(function (done) { + setTimeout(function () { + done(); + }, 50); + }).timeout(1500); + + it('should allow overriding via chaining', function (done) { + setTimeout(function () { + done(); + }, 50); + }).timeout(1500); + + describe('suite-level', function () { + it('should work with timeout(0)', function (done) { + setTimeout(done, 1); + }); + + describe('nested suite', function () { + it('should work with timeout(0)', function (done) { + setTimeout(done, 1); + }); + }); + }).timeout(1000); + }); }); });