diff --git a/CHANGELOG.md b/CHANGELOG.md index 89e7f66e8..17cbc2e3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange ### Added - [`newline-after-import`]: add `considerComments` option ([#2399], thanks [@pri1311]) +### Fixed +- [`order`]: move nested imports closer to main import entry ([#2396], thanks [@pri1311]) + ### Changed - [Tests] `named`: Run all TypeScript test ([#2427], thanks [@ProdigySim]) @@ -987,6 +990,7 @@ for info on changes for earlier releases. [#2417]: https://github.com/import-js/eslint-plugin-import/pull/2417 [#2411]: https://github.com/import-js/eslint-plugin-import/pull/2411 [#2399]: https://github.com/import-js/eslint-plugin-import/pull/2399 +[#2396]: https://github.com/import-js/eslint-plugin-import/pull/2396 [#2393]: https://github.com/import-js/eslint-plugin-import/pull/2393 [#2388]: https://github.com/import-js/eslint-plugin-import/pull/2388 [#2381]: https://github.com/import-js/eslint-plugin-import/pull/2381 diff --git a/src/rules/order.js b/src/rules/order.js index fce979f09..df35db065 100644 --- a/src/rules/order.js +++ b/src/rules/order.js @@ -1,6 +1,8 @@ 'use strict'; import minimatch from 'minimatch'; +import includes from 'array-includes'; + import importType from '../core/importType'; import isStaticRequire from '../core/staticRequire'; import docsUrl from '../docsUrl'; @@ -244,16 +246,37 @@ function getSorter(ascending) { const multiplier = ascending ? 1 : -1; return function importsSorter(importA, importB) { - let result; - - if (importA < importB) { - result = -1; - } else if (importA > importB) { - result = 1; + let result = 0; + + if (!includes(importA, '/') && !includes(importB, '/')) { + if (importA < importB) { + result = -1; + } else if (importA > importB) { + result = 1; + } else { + result = 0; + } } else { - result = 0; - } + const A = importA.split('/'); + const B = importB.split('/'); + const a = A.length; + const b = B.length; + + for (let i = 0; i < Math.min(a, b); i++) { + if (A[i] < B[i]) { + result = -1; + break; + } else if (A[i] > B[i]) { + result = 1; + break; + } + } + if (!result && a !== b) { + result = a < b ? -1 : 1; + } + } + return result * multiplier; }; } diff --git a/tests/src/rules/order.js b/tests/src/rules/order.js index e552c9a85..f5c3bb393 100644 --- a/tests/src/rules/order.js +++ b/tests/src/rules/order.js @@ -675,6 +675,47 @@ ruleTester.run('order', rule, { alphabetize: { order: 'desc' }, }], }), + // Option alphabetize: {order: 'asc'} and move nested import entries closer to the main import entry + test({ + code: ` + import a from "foo"; + import c from "foo/bar"; + import d from "foo/barfoo"; + import b from "foo-bar"; + `, + options: [{ alphabetize: { order: 'asc' } }], + }), + // Option alphabetize: {order: 'asc'} and move nested import entries closer to the main import entry + test({ + code: ` + import a from "foo"; + import c from "foo/foobar/bar"; + import d from "foo/foobar/barfoo"; + import b from "foo-bar"; + `, + options: [{ alphabetize: { order: 'asc' } }], + }), + // Option alphabetize: {order: 'desc'} and move nested import entries closer to the main import entry + test({ + code: ` + import b from "foo-bar"; + import d from "foo/barfoo"; + import c from "foo/bar"; + import a from "foo"; + `, + options: [{ alphabetize: { order: 'desc' } }], + }), + // Option alphabetize: {order: 'desc'} and move nested import entries closer to the main import entry with file names having non-alphanumeric characters. + test({ + code: ` + import b from "foo-bar"; + import c from "foo,bar"; + import d from "foo/barfoo"; + import a from "foo";`, + options: [{ + alphabetize: { order: 'desc' }, + }], + }), // Option alphabetize with newlines-between: {order: 'asc', newlines-between: 'always'} test({ code: ` @@ -2230,6 +2271,27 @@ ruleTester.run('order', rule, { message: '`bar` import should occur before import of `Bar`', }], }), + // Option alphabetize: {order: 'asc'} and move nested import entries closer to the main import entry + test({ + code: ` + import a from "foo"; + import b from "foo-bar"; + import c from "foo/bar"; + import d from "foo/barfoo"; + `, + options: [{ + alphabetize: { order: 'asc' }, + }], + output: ` + import a from "foo"; + import c from "foo/bar"; + import d from "foo/barfoo"; + import b from "foo-bar"; + `, + errors: [{ + message: '`foo-bar` import should occur after import of `foo/barfoo`', + }], + }), // Option alphabetize {order: 'asc': caseInsensitive: true} test({ code: `