From 0778b0390ec18b9fdc1acfd45d10bf1b614d82ff Mon Sep 17 00:00:00 2001 From: Pearce Date: Fri, 13 Jan 2023 12:49:34 -0800 Subject: [PATCH] [Fix] `order`: Fix group ranks order when alphabetizing Fixes #2671 --- CHANGELOG.md | 4 ++++ src/rules/order.js | 9 ++++++--- tests/src/rules/order.js | 43 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48bf738e0..907ceb059 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange ## [Unreleased] +### Fixed +- [`order]`: Fix group ranks order when alphabetizing ([#2674], thanks [@Pearce-Ropion]) + ## [2.27.4] - 2023-01-11 ### Fixed @@ -1376,6 +1379,7 @@ for info on changes for earlier releases. [#211]: https://github.com/import-js/eslint-plugin-import/pull/211 [#164]: https://github.com/import-js/eslint-plugin-import/pull/164 [#157]: https://github.com/import-js/eslint-plugin-import/pull/157 +[#2674]: https://github.com/import-js/eslint-plugin-import/issues/2674 [#2668]: https://github.com/import-js/eslint-plugin-import/issues/2668 [#2666]: https://github.com/import-js/eslint-plugin-import/issues/2666 [#2665]: https://github.com/import-js/eslint-plugin-import/issues/2665 diff --git a/src/rules/order.js b/src/rules/order.js index dc9da64f2..bdead9d40 100644 --- a/src/rules/order.js +++ b/src/rules/order.js @@ -334,10 +334,13 @@ function mutateRanksToAlphabetize(imported, alphabetizeOptions) { return acc; }, {}); - const groupRanks = Object.keys(groupedByRanks); - const sorterFn = getSorter(alphabetizeOptions); + // sort group keys so that they can be iterated on in order + const groupRanks = Object.keys(groupedByRanks).sort(function (a, b) { + return a - b; + }); + // sort imports locally within their group groupRanks.forEach(function (groupRank) { groupedByRanks[groupRank].sort(sorterFn); @@ -345,7 +348,7 @@ function mutateRanksToAlphabetize(imported, alphabetizeOptions) { // assign globally unique rank to each import let newRank = 0; - const alphabetizedRanks = groupRanks.sort().reduce(function (acc, groupRank) { + const alphabetizedRanks = groupRanks.reduce(function (acc, groupRank) { groupedByRanks[groupRank].forEach(function (importedItem) { acc[`${importedItem.value}|${importedItem.node.importKind}`] = parseInt(groupRank, 10) + newRank; newRank += 1; diff --git a/tests/src/rules/order.js b/tests/src/rules/order.js index 07511ee4d..b7d86dd93 100644 --- a/tests/src/rules/order.js +++ b/tests/src/rules/order.js @@ -2280,6 +2280,8 @@ ruleTester.run('order', rule, { }, ], }), + + // pathGroups overflowing to previous/next groups test({ code: ` import path from 'path'; @@ -2349,6 +2351,47 @@ ruleTester.run('order', rule, { errors: Array.from({ length: 11 }, () => 'There should be at least one empty line between import groups'), }), + // rankings that overflow to double-digit ranks + test({ + code: ` + import external from 'external'; + import a from '@namespace/a'; + import b from '@namespace/b'; + import { parent } from '../../parent'; + import local from './local'; + import './side-effect';`, + output: ` + import external from 'external'; + + import a from '@namespace/a'; + import b from '@namespace/b'; + + import { parent } from '../../parent'; + + import local from './local'; + import './side-effect';`, + options: [ + { + alphabetize: { + order: 'asc', + caseInsensitive: true, + }, + groups: ['type', 'builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object'], + 'newlines-between': 'always', + pathGroups: [ + { pattern: '@namespace', group: 'external', position: 'after' }, + { pattern: '@namespace/**', group: 'external', position: 'after' }, + ], + pathGroupsExcludedImportTypes: ['@namespace'], + }, + ], + errors: [ + 'There should be at least one empty line between import groups', + 'There should be at least one empty line between import groups', + 'There should be at least one empty line between import groups', + ], + }), + // reorder fix cannot cross non import or require test(withoutAutofixOutput({ code: `