From 3d61c4a20e16a04a9cd81588c2d47cd393202fde Mon Sep 17 00:00:00 2001 From: Ed Sanders Date: Wed, 27 May 2020 13:46:00 +0100 Subject: [PATCH 1/2] Support comments in arrow functions when fixing Fixes #251 --- lib/rules/no-mocha-arrows.js | 27 ++++++++++++++++++--------- test/rules/no-mocha-arrows.js | 9 +++++++-- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/lib/rules/no-mocha-arrows.js b/lib/rules/no-mocha-arrows.js index 89f5dd5..56840f8 100644 --- a/lib/rules/no-mocha-arrows.js +++ b/lib/rules/no-mocha-arrows.js @@ -5,7 +5,6 @@ * @author Paul Melnikow */ -const last = require('ramda/src/last'); const astUtils = require('../util/ast'); module.exports = { @@ -16,21 +15,31 @@ module.exports = { create(context) { const sourceCode = context.getSourceCode(); + // eslint-disable-next-line max-statements function formatFunctionHead(fn) { - const paramsLeftParen = sourceCode.getFirstToken(fn); - const paramsRightParen = sourceCode.getTokenBefore(sourceCode.getTokenBefore(fn.body)); - let paramsFullText = sourceCode.text.slice(paramsLeftParen.range[0], paramsRightParen.range[1]); + const arrow = sourceCode.getTokenBefore(fn.body); + let firstToken = sourceCode.getFirstToken(fn); + const beforeArrowToken = sourceCode.getTokenBefore(arrow); + let paramsFullText; + let params = sourceCode.text.slice(firstToken.range[0], beforeArrowToken.range[1]).trim(); let functionKeyword = 'function'; + const beforeArrowComment = sourceCode.text.slice(beforeArrowToken.range[1], arrow.range[0]).trim(); + const afterArrowComment = sourceCode.text.slice(arrow.range[1], fn.body.range[0]).trim(); if (fn.async) { - // When 'async' specified, take care about the keyword. + // When 'async' specified strip the token from the params text + // and prepend it to the function keyword + params = params.slice(firstToken.range[1] - firstToken.range[0]).trim(); functionKeyword = 'async function'; - // Strip 'async (...)' to ' (...)' - paramsFullText = paramsFullText.slice(5); + + // Advance firstToken pointer + firstToken = sourceCode.getTokenAfter(firstToken); } - if (fn.params.length > 0) { - paramsFullText = `(${ sourceCode.text.slice(fn.params[0].range[0], last(fn.params).range[1]) })`; + if (firstToken.type !== 'Punctuator') { + paramsFullText = `(${params}${beforeArrowComment})${afterArrowComment}`; + } else { + paramsFullText = `${params}${beforeArrowComment}${afterArrowComment}`; } return `${functionKeyword}${paramsFullText} `; diff --git a/test/rules/no-mocha-arrows.js b/test/rules/no-mocha-arrows.js index 94f32d6..a388a7f 100644 --- a/test/rules/no-mocha-arrows.js +++ b/test/rules/no-mocha-arrows.js @@ -74,12 +74,12 @@ ruleTester.run('no-mocha-arrows', rules['no-mocha-arrows'], { { code: 'it(async () => { assert(something, false) })', errors, - output: 'it(async function () { assert(something, false) })' + output: 'it(async function() { assert(something, false) })' }, { code: 'it(async () => assert(something, false))', errors, - output: 'it(async function () { return assert(something, false); })' + output: 'it(async function() { return assert(something, false); })' }, { code: 'it(async done => assert(something, false))', @@ -95,6 +95,11 @@ ruleTester.run('no-mocha-arrows', rules['no-mocha-arrows'], { code: 'it(async() => assert(something, false))', errors, output: 'it(async function() { return assert(something, false); })' + }, + { + code: 'it(/*one*/async/*two*/(done)/*three*/=>/*four*/assert(something, false))', + errors, + output: 'it(/*one*/async function/*two*/(done)/*three*//*four*/ { return assert(something, false); })' } ] From 2eefa13c49c6f5ee6f2594d8964305dd128820f2 Mon Sep 17 00:00:00 2001 From: Ed Sanders Date: Fri, 29 May 2020 19:41:38 +0100 Subject: [PATCH 2/2] Add 'extractSourceTextByRange' and move const/lets around --- lib/rules/no-mocha-arrows.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/rules/no-mocha-arrows.js b/lib/rules/no-mocha-arrows.js index 56840f8..30a7977 100644 --- a/lib/rules/no-mocha-arrows.js +++ b/lib/rules/no-mocha-arrows.js @@ -15,17 +15,18 @@ module.exports = { create(context) { const sourceCode = context.getSourceCode(); + function extractSourceTextByRange(start, end) { + return sourceCode.text.slice(start, end).trim(); + } + // eslint-disable-next-line max-statements function formatFunctionHead(fn) { const arrow = sourceCode.getTokenBefore(fn.body); - let firstToken = sourceCode.getFirstToken(fn); const beforeArrowToken = sourceCode.getTokenBefore(arrow); - let paramsFullText; - let params = sourceCode.text.slice(firstToken.range[0], beforeArrowToken.range[1]).trim(); - let functionKeyword = 'function'; - const beforeArrowComment = sourceCode.text.slice(beforeArrowToken.range[1], arrow.range[0]).trim(); - const afterArrowComment = sourceCode.text.slice(arrow.range[1], fn.body.range[0]).trim(); + let firstToken = sourceCode.getFirstToken(fn); + let functionKeyword = 'function'; + let params = extractSourceTextByRange(firstToken.range[0], beforeArrowToken.range[1]); if (fn.async) { // When 'async' specified strip the token from the params text // and prepend it to the function keyword @@ -36,6 +37,9 @@ module.exports = { firstToken = sourceCode.getTokenAfter(firstToken); } + const beforeArrowComment = extractSourceTextByRange(beforeArrowToken.range[1], arrow.range[0]); + const afterArrowComment = extractSourceTextByRange(arrow.range[1], fn.body.range[0]); + let paramsFullText; if (firstToken.type !== 'Punctuator') { paramsFullText = `(${params}${beforeArrowComment})${afterArrowComment}`; } else {