Repository: lo1tuma/eslint-plugin-mocha
Pull request #78 (2016-07-12 00:48:59)

no-mocha-global-arrows: New rule
For #48 

coveralls: 
[![Coverage Status](https://coveralls.io/builds/6961370/badge)](https://coveralls.io/builds/6961370)

Coverage remained the same at 100.0% when pulling **b81be5be171485a61998146ebf151f5140a412fb on bodylabs:no_mocha_global_arrows** into **2f560171dd691ae444eb0a7ea819374a9497df50 on lo1tuma:master**.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/6998558/badge)](https://coveralls.io/builds/6998558)

Coverage remained the same at 100.0% when pulling **b18e8ba24fa52c6e78b9c16c498e8cd91f2db3d0 on bodylabs:no_mocha_global_arrows** into **2f560171dd691ae444eb0a7ea819374a9497df50 on lo1tuma:master**.


Patch:
diff --git a/docs/rules/README.md b/docs/rules/README.md
index e10ecda..a39c64c 100644
--- a/docs/rules/README.md
+++ b/docs/rules/README.md
@@ -8,3 +8,4 @@
 * [no-global-tests](no-global-tests.md) - disallow global tests
 * [valid-test-description](valid-test-description.md) - match test descriptions against a pre-configured regular expression
 * [valid-suite-description](valid-suite-description.md) - match suite descriptions against a pre-configured regular expression
+* [no-mocha-arrows](no-mocha-arrows.md) - disallow arrow functions as arguments to mocha globals
diff --git a/docs/rules/no-mocha-arrows.md b/docs/rules/no-mocha-arrows.md
new file mode 100644
index 0000000..2db446a
--- /dev/null
+++ b/docs/rules/no-mocha-arrows.md
@@ -0,0 +1,31 @@
+# Disallow Arrow Functions as Arguments to Mocha Functions (no-mocha-arrows)
+
+Mocha [discourages](http://mochajs.org/#arrow-functions) passing it arrow functions as arguments. This rule prevents their use on the Mocha globals.
+
+## Rule Details
+
+This rule looks for occurrences of the Mocha functions (`describe`, `it`, `beforeEach`, etc.) within the source code.
+
+The following patterns are considered warnings:
+
+```js
+it(() => { assert(something, false); })
+it("should be false", () => { assert(something, false); })
+beforeEach(() => { doSomething(); })
+beforeEach((done) => { doSomething(); done(); })
+```
+
+These patterns would not be considered warnings:
+
+```js
+it()
+it(function() { assert(something, false); })
+it("should be false", function() { assert(something, false); })
+```
+
+This does not check usage of the [`require` interface](http://mochajs.org/#require) for Mocha, only the globals.
+
+## When Not To Use It
+
+* If you want to pass arrow functions to mocha, turn this rule off.
+* If you have other globals which share names with mocha globals, you should turn this rule off, because it would raise warnings.
diff --git a/index.js b/index.js
index 3c4fc0b..5dc2c0b 100644
--- a/index.js
+++ b/index.js
@@ -9,7 +9,8 @@ module.exports = {
         'no-synchronous-tests': require('./lib/rules/no-synchronous-tests'),
         'no-global-tests': require('./lib/rules/no-global-tests'),
         'valid-test-description': require('./lib/rules/valid-test-description'),
-        'valid-suite-description': require('./lib/rules/valid-suite-description')
+        'valid-suite-description': require('./lib/rules/valid-suite-description'),
+        'no-mocha-arrows': require('./lib/rules/no-mocha-arrows')
     },
     configs: {
         recommended: {
diff --git a/lib/rules/no-mocha-arrows.js b/lib/rules/no-mocha-arrows.js
new file mode 100644
index 0000000..674a884
--- /dev/null
+++ b/lib/rules/no-mocha-arrows.js
@@ -0,0 +1,59 @@
+'use strict';
+
+/**
+ * @fileoverview Disallow arrow functions as arguments to Mocha globals
+ * @author Paul Melnikow
+ */
+
+var R = require('ramda'),
+    mochaFunctionNames = [
+        'describe',
+        'describe.skip',
+        'xdescribe',
+        'suite',
+        'context',
+        'xcontext',
+        'specify',
+        'xspecify',
+        'it',
+        'it.only',
+        'xit',
+        'test',
+        'test.only',
+        'specify',
+        'specify.only',
+        'before',
+        'after',
+        'beforeEach',
+        'afterEach'
+    ];
+
+module.exports = function (context) {
+    function getCalleeName(callee) {
+        if (callee.type === 'MemberExpression') {
+             return callee.object.name + '.' + callee.property.name;
+        }
+
+        return callee.name;
+    }
+
+    function isLikelyMochaGlobal(scope, name) {
+        return !R.find(R.propEq('name', name), scope.variables);
+    }
+
+    return {
+        CallExpression: function (node) {
+            var name = getCalleeName(node.callee),
+                fnArg;
+
+            if (name && mochaFunctionNames.indexOf(name) > -1) {
+                fnArg = node.arguments.slice(-1)[0];
+                if (fnArg && fnArg.type === 'ArrowFunctionExpression') {
+                    if (isLikelyMochaGlobal(context.getScope(), name)) {
+                        context.report(node, 'Do not pass arrow functions to ' + name + '()');
+                    }
+                }
+            }
+        }
+    };
+};


Test patch:
diff --git a/test/rules/no-mocha-arrows.js b/test/rules/no-mocha-arrows.js
new file mode 100644
index 0000000..c9c5919
--- /dev/null
+++ b/test/rules/no-mocha-arrows.js
@@ -0,0 +1,51 @@
+'use strict';
+
+var RuleTester = require('eslint').RuleTester,
+    rules = require('../../').rules,
+    ruleTester = new RuleTester(),
+    expectedErrorMessage = 'Do not pass arrow functions to it()';
+
+ruleTester.run('no-mocha-arrows', rules['no-mocha-arrows'], {
+
+    valid: [
+        'it()',
+        'it(function() { assert(something, false); })',
+        'it("should be false", function() { assert(something, false); })',
+        {
+            // In this example, `it` is not a global.
+            code: 'function it () {}; it(() => { console.log("okay") })',
+            parserOptions: { ecmaVersion: 6 }
+        },
+        'it.only()'
+    ],
+
+    invalid: [
+        {
+            code: 'it(() => { assert(something, false); })',
+            parserOptions: { ecmaVersion: 6 },
+            errors: [ { message: expectedErrorMessage, column: 1, line: 1 } ]
+        },
+        {
+            code: 'it(() => { assert(something, false); })',
+            globals: [ 'it' ],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [ { message: expectedErrorMessage, column: 1, line: 1 } ]
+        },
+        {
+            code: 'it(() => assert(something, false))',
+            parserOptions: { ecmaVersion: 6 },
+            errors: [ { message: expectedErrorMessage, column: 1, line: 1 } ]
+        },
+        {
+            code: 'it("should be false", () => { assert(something, false); })',
+            parserOptions: { ecmaVersion: 6 },
+            errors: [ { message: expectedErrorMessage, column: 1, line: 1 } ]
+        },
+        {
+            code: 'it.only(() => { assert(something, false); })',
+            parserOptions: { ecmaVersion: 6 },
+            errors: [ { message: 'Do not pass arrow functions to it.only()', column: 1, line: 1 } ]
+        }
+    ]
+
+});