From ee1ea025a6843fe4380927832a31761f1f4ae339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=89=E1=85=A1=E1=86=BC?= =?UTF-8?q?=E1=84=83=E1=85=AE?= Date: Sat, 13 Jan 2024 01:42:54 +0900 Subject: [PATCH] [Fix] `newline-after-import`: fix considerComments option when require --- CHANGELOG.md | 3 ++ src/rules/newline-after-import.js | 20 +++++++++---- tests/src/rules/newline-after-import.js | 38 +++++++++++++++++++++---- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05d623f41..2d0ff1a91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange - [`no-extraneous-dependencies`]: allow wrong path ([#3012], thanks [@chabb]) - [`no-cycle`]: use scc algorithm to optimize ([#2998], thanks [@soryy708]) - [`no-duplicates`]: Removing duplicates breaks in TypeScript ([#3033], thanks [@yesl-kim]) +- [`newline-after-import`]: fix considerComments option when require ([#2952], thanks [@developer-bandi]) ### Changed - [Docs] `no-extraneous-dependencies`: Make glob pattern description more explicit ([#2944], thanks [@mulztob]) @@ -1136,6 +1137,7 @@ for info on changes for earlier releases. [#2987]: https://github.com/import-js/eslint-plugin-import/pull/2987 [#2985]: https://github.com/import-js/eslint-plugin-import/pull/2985 [#2982]: https://github.com/import-js/eslint-plugin-import/pull/2982 +[#2952]: https://github.com/import-js/eslint-plugin-import/pull/2952 [#2944]: https://github.com/import-js/eslint-plugin-import/pull/2944 [#2942]: https://github.com/import-js/eslint-plugin-import/pull/2942 [#2919]: https://github.com/import-js/eslint-plugin-import/pull/2919 @@ -1742,6 +1744,7 @@ for info on changes for earlier releases. [@bicstone]: https://github.com/bicstone [@Blasz]: https://github.com/Blasz [@bmish]: https://github.com/bmish +[@developer-bandi]: https://github.com/developer-bandi [@borisyankov]: https://github.com/borisyankov [@bradennapier]: https://github.com/bradennapier [@bradzacher]: https://github.com/bradzacher diff --git a/src/rules/newline-after-import.js b/src/rules/newline-after-import.js index a33bb615b..d10b87d78 100644 --- a/src/rules/newline-after-import.js +++ b/src/rules/newline-after-import.js @@ -124,7 +124,7 @@ module.exports = { } } - function commentAfterImport(node, nextComment) { + function commentAfterImport(node, nextComment, type) { const lineDifference = getLineDifference(node, nextComment); const EXPECTED_LINE_DIFFERENCE = options.count + 1; @@ -140,7 +140,7 @@ module.exports = { line: node.loc.end.line, column, }, - message: `Expected ${options.count} empty line${options.count > 1 ? 's' : ''} after import statement not followed by another import.`, + message: `Expected ${options.count} empty line${options.count > 1 ? 's' : ''} after ${type} statement not followed by another ${type}.`, fix: options.exactCount && EXPECTED_LINE_DIFFERENCE < lineDifference ? undefined : (fixer) => fixer.insertTextAfter( node, '\n'.repeat(EXPECTED_LINE_DIFFERENCE - lineDifference), @@ -178,7 +178,7 @@ module.exports = { } if (nextComment && typeof nextComment !== 'undefined') { - commentAfterImport(node, nextComment); + commentAfterImport(node, nextComment, 'import'); } else if (nextNode && nextNode.type !== 'ImportDeclaration' && (nextNode.type !== 'TSImportEqualsDeclaration' || nextNode.isExport)) { checkForNewLine(node, nextNode, 'import'); } @@ -215,8 +215,18 @@ module.exports = { || !containsNodeOrEqual(nextStatement, nextRequireCall) ) ) { - - checkForNewLine(statementWithRequireCall, nextStatement, 'require'); + let nextComment; + if (typeof statementWithRequireCall.parent.comments !== 'undefined' && options.considerComments) { + const endLine = node.loc.end.line; + nextComment = statementWithRequireCall.parent.comments.find((o) => o.loc.start.line >= endLine && o.loc.start.line <= endLine + options.count + 1); + } + + if (nextComment && typeof nextComment !== 'undefined') { + + commentAfterImport(statementWithRequireCall, nextComment, 'require'); + } else { + checkForNewLine(statementWithRequireCall, nextStatement, 'require'); + } } }); }, diff --git a/tests/src/rules/newline-after-import.js b/tests/src/rules/newline-after-import.js index 6a8fb83e4..b78e891a3 100644 --- a/tests/src/rules/newline-after-import.js +++ b/tests/src/rules/newline-after-import.js @@ -8,6 +8,7 @@ import { getTSParsers, parsers, testVersion } from '../utils'; const IMPORT_ERROR_MESSAGE = 'Expected 1 empty line after import statement not followed by another import.'; const IMPORT_ERROR_MESSAGE_MULTIPLE = (count) => `Expected ${count} empty lines after import statement not followed by another import.`; const REQUIRE_ERROR_MESSAGE = 'Expected 1 empty line after require statement not followed by another require.'; +const REQUIRE_ERROR_MESSAGE_MULTIPLE = (count) => `Expected ${count} empty lines after require statement not followed by another require.`; const ruleTester = new RuleTester(); @@ -202,7 +203,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { options: [{ count: 4, exactCount: true }], }, { - code: `var foo = require('foo-module');\n\n\n\n// Some random comment\nvar foo = 'bar';`, + code: `var foo = require('foo-module');\n\n\n\n\n// Some random comment\nvar foo = 'bar';`, parserOptions: { ecmaVersion: 2015, sourceType: 'module' }, options: [{ count: 4, exactCount: true, considerComments: true }], }, @@ -394,6 +395,19 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { `, parserOptions: { ecmaVersion: 2015, sourceType: 'module' }, }, + { + code: `var foo = require('foo-module');\n\n\n// Some random comment\nvar foo = 'bar';`, + options: [{ count: 2, considerComments: true }], + }, + { + code: `var foo = require('foo-module');\n\n\n/**\n * Test comment\n */\nvar foo = 'bar';`, + options: [{ count: 2, considerComments: true }], + }, + { + code: `const foo = require('foo');\n\n\n// some random comment\nconst bar = function() {};`, + options: [{ count: 2, exactCount: true, considerComments: true }], + parserOptions: { ecmaVersion: 2015 }, + }, ), invalid: [].concat( @@ -825,7 +839,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { errors: [{ line: 1, column: 1, - message: 'Expected 2 empty lines after require statement not followed by another require.', + message: REQUIRE_ERROR_MESSAGE_MULTIPLE(2), }], parserOptions: { ecmaVersion: 2015 }, }, @@ -836,7 +850,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { errors: [{ line: 1, column: 1, - message: 'Expected 2 empty lines after require statement not followed by another require.', + message: REQUIRE_ERROR_MESSAGE_MULTIPLE(2), }], parserOptions: { ecmaVersion: 2015 }, }, @@ -852,14 +866,26 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { parserOptions: { ecmaVersion: 2015, considerComments: true, sourceType: 'module' }, }, { - code: `const foo = require('foo');\n\n\n// some random comment\nconst bar = function() {};`, - options: [{ count: 2, exactCount: true, considerComments: true }], + code: `var foo = require('foo-module');\nvar foo = require('foo-module');\n\n// Some random comment\nvar foo = 'bar';`, + output: `var foo = require('foo-module');\nvar foo = require('foo-module');\n\n\n// Some random comment\nvar foo = 'bar';`, + errors: [{ + line: 2, + column: 1, + message: REQUIRE_ERROR_MESSAGE_MULTIPLE(2), + }], + parserOptions: { ecmaVersion: 2015, sourceType: 'module' }, + options: [{ considerComments: true, count: 2 }], + }, + { + code: `var foo = require('foo-module');\n\n/**\n * Test comment\n */\nvar foo = 'bar';`, + output: `var foo = require('foo-module');\n\n\n/**\n * Test comment\n */\nvar foo = 'bar';`, errors: [{ line: 1, column: 1, - message: 'Expected 2 empty lines after require statement not followed by another require.', + message: REQUIRE_ERROR_MESSAGE_MULTIPLE(2), }], parserOptions: { ecmaVersion: 2015 }, + options: [{ considerComments: true, count: 2 }], }, ), });