From 8778d9604a91e7b277a0cc82d77315b29ce420ad Mon Sep 17 00:00:00 2001 From: Mathias Schreck Date: Tue, 18 Feb 2020 17:58:51 +0100 Subject: [PATCH] no-hooks: add option to allow certain kind of hooks --- docs/rules/no-hooks.md | 15 ++++++++++++++ lib/rules/no-hooks.js | 24 ++++++++++++++++++++- test/rules/no-hooks.js | 47 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 84 insertions(+), 2 deletions(-) diff --git a/docs/rules/no-hooks.md b/docs/rules/no-hooks.md index 276673d..59753a7 100644 --- a/docs/rules/no-hooks.md +++ b/docs/rules/no-hooks.md @@ -43,6 +43,21 @@ describe('foo', function () { }); ``` +## Options + +This rule supports the following options: + +* `allow`: An array containing the names of hooks to allow. Defaults to an empty array. + +```json +{ + "rules": { + "mocha/no-hooks": ["error", {"allow": ["after"]}] + } +} +``` + + ## When Not To Use It * If you use another library which exposes a similar API as mocha (e.g. `before`, `after`), you should turn this rule off, because it would raise warnings. diff --git a/lib/rules/no-hooks.js b/lib/rules/no-hooks.js index d3f5617..f1ee203 100644 --- a/lib/rules/no-hooks.js +++ b/lib/rules/no-hooks.js @@ -3,10 +3,32 @@ const astUtil = require('../util/ast'); module.exports = { + meta: { + schema: [ + { + type: 'object', + properties: { + allow: { + type: 'array', + items: { + type: 'string' + } + } + }, + additionalProperties: false + } + ] + }, + create(context) { + const [ config = {} ] = context.options; + const { allow = [] } = config; + return { CallExpression(node) { - if (astUtil.isHookIdentifier(node.callee)) { + const isHookAllowed = allow.includes(node.callee.name); + + if (astUtil.isHookIdentifier(node.callee) && !isHookAllowed) { context.report({ node: node.callee, message: `Unexpected use of Mocha \`${ node.callee.name }\` hook` diff --git a/test/rules/no-hooks.js b/test/rules/no-hooks.js index 9380186..12eba34 100644 --- a/test/rules/no-hooks.js +++ b/test/rules/no-hooks.js @@ -18,7 +18,47 @@ ruleTester.run('no-hooks', rules['no-hooks'], { 'after.foo()', 'beforeEach.foo()', 'afterEach.foo()', - 'var before = 2; before + 3;' + 'var before = 2; before + 3;', + { + code: 'describe(function() { before(function() {}); });', + options: [ { allow: [ 'before' ] } ] + }, + { + code: 'describe(function() { after(function() {}); });', + options: [ { allow: [ 'after' ] } ] + }, + { + code: 'describe(function() { beforeEach(function() {}); });', + options: [ { allow: [ 'beforeEach' ] } ] + }, + { + code: 'describe(function() { afterEach(function() {}); });', + options: [ { allow: [ 'afterEach' ] } ] + }, + { + code: 'describe(function() { beforeAll(function() {}); });', + options: [ { allow: [ 'beforeAll' ] } ] + }, + { + code: 'describe(function() { afterAll(function() {}); });', + options: [ { allow: [ 'afterAll' ] } ] + }, + { + code: 'describe(function() { setup(function() {}); });', + options: [ { allow: [ 'setup' ] } ] + }, + { + code: 'describe(function() { teardown(function() {}); });', + options: [ { allow: [ 'teardown' ] } ] + }, + { + code: 'describe(function() { suiteSetup(function() {}); });', + options: [ { allow: [ 'suiteSetup' ] } ] + }, + { + code: 'describe(function() { suiteTeardown(function() {}); });', + options: [ { allow: [ 'suiteTeardown' ] } ] + } ], invalid: [ @@ -41,6 +81,11 @@ ruleTester.run('no-hooks', rules['no-hooks'], { { code: 'describe(function() { describe(function() { before(function() {}); }); });', errors: [ { message: 'Unexpected use of Mocha `before` hook', column: 45, line: 1 } ] + }, + { + code: 'describe(function() { after(function() {}); });', + options: [ { allow: [ 'before' ] } ], + errors: [ { message: 'Unexpected use of Mocha `after` hook', column: 23, line: 1 } ] } ]