Skip to content

Commit

Permalink
Merge pull request #112 from rhysd/no-mocha-arrows-fix
Browse files Browse the repository at this point in the history
Make no-mocha-arrows rule fixable
  • Loading branch information
lo1tuma committed Nov 3, 2016
2 parents 40878b1 + 153ec6d commit 58d0405
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 19 deletions.
40 changes: 39 additions & 1 deletion lib/rules/no-mocha-arrows.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,38 @@ module.exports = function (context) {
return !R.find(R.propEq('name', name), scope.variables);
}

function fixArrowFunction(fixer, fn) {
var sourceCode = context.getSourceCode(),
paramsLeftParen = sourceCode.getFirstToken(fn),
paramsRightParen = sourceCode.getTokenBefore(sourceCode.getTokenBefore(fn.body)),
paramsFullText =
sourceCode.text.slice(paramsLeftParen.range[0], paramsRightParen.range[1]),
functionKeyword = 'function ',
bodyText;

if (fn.async) {
// When 'async' specified, take care about the keyword.
functionKeyword = 'async function';
// Strip 'async (...)' to ' (...)'
paramsFullText = paramsFullText.slice(5);
}

if (fn.body.type === 'BlockStatement') {
// When it((...) => { ... }),
// simply replace '(...) => ' with 'function () '
return fixer.replaceTextRange(
[ fn.start, fn.body.start ],
functionKeyword + paramsFullText + ' '
);
}

bodyText = sourceCode.text.slice(fn.body.range[0], fn.body.range[1]);
return fixer.replaceTextRange(
[ fn.start, fn.end ],
functionKeyword + paramsFullText + ' { return ' + bodyText + '; }'
);
}

return {
CallExpression: function (node) {
var name = getCalleeName(node.callee),
Expand All @@ -50,7 +82,13 @@ module.exports = function (context) {
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 + '()');
context.report({
node: node,
message: 'Do not pass arrow functions to ' + name + '()',
fix: function (fixer) {
return fixArrowFunction(fixer, fnArg);
}
});
}
}
}
Expand Down
64 changes: 46 additions & 18 deletions test/rules/no-mocha-arrows.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,77 @@

var RuleTester = require('eslint').RuleTester,
rules = require('../../').rules,
ruleTester = new RuleTester(),
expectedErrorMessage = 'Do not pass arrow functions to it()';
ruleTester = new RuleTester({
parserOptions: { ecmaVersion: 2017 }
}),
expectedErrorMessage = 'Do not pass arrow functions to it()',
errors = [ { message: expectedErrorMessage, column: 1, line: 1 } ];

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()'
// In this example, `it` is not a global.
'function it () {}; it(() => { console.log("okay") })',
'it.only()',
'it(function(done) { assert(something, false); done(); })',
'it(function*() { assert(something, false) })',
'it(async function () { assert(something, false) })'
],

invalid: [
{
code: 'it(() => { assert(something, false); })',
parserOptions: { ecmaVersion: 6 },
errors: [ { message: expectedErrorMessage, column: 1, line: 1 } ]
errors: errors,
output: 'it(function () { assert(something, false); })'
},
{
code: 'it(() => { assert(something, false); })',
globals: [ 'it' ],
parserOptions: { ecmaVersion: 6 },
errors: [ { message: expectedErrorMessage, column: 1, line: 1 } ]
errors: errors,
output: 'it(function () { assert(something, false); })'
},
{
code: 'it(() => assert(something, false))',
parserOptions: { ecmaVersion: 6 },
errors: [ { message: expectedErrorMessage, column: 1, line: 1 } ]
errors: errors,
output: 'it(function () { return assert(something, false); })'
},
{
code: 'it("should be false", () => { assert(something, false); })',
parserOptions: { ecmaVersion: 6 },
errors: [ { message: expectedErrorMessage, column: 1, line: 1 } ]
errors: errors,
output: 'it("should be false", function () { assert(something, false); })'
},
{
code: 'it.only(() => { assert(something, false); })',
parserOptions: { ecmaVersion: 6 },
errors: [ { message: 'Do not pass arrow functions to it.only()', column: 1, line: 1 } ]
errors: [ { message: 'Do not pass arrow functions to it.only()', column: 1, line: 1 } ],
output: 'it.only(function () { assert(something, false); })'
},
{
code: 'it((done) => { assert(something, false); })',
errors: errors,
output: 'it(function (done) { assert(something, false); })'
},
{
code: 'it("should be false", () => {\n assert(something, false);\n})',
errors: errors,
output: 'it("should be false", function () {\n assert(something, false);\n})'
},
{
code: 'it(async () => { assert(something, false) })',
errors: errors,
output: 'it(async function () { assert(something, false) })'
},
{
code: 'it(async () => assert(something, false))',
errors: errors,
output: 'it(async function () { return assert(something, false); })'
},
{
code: 'it(async() => assert(something, false))',
errors: errors,
output: 'it(async function() { return assert(something, false); })'
}
]

Expand Down

0 comments on commit 58d0405

Please sign in to comment.