Skip to content

Commit b39770d

Browse files
geraintwhiteljharb
authored andcommitted
[Fix] order: restore default behavior unless type is in groups
Fixes #2070. Fixes #2084.
1 parent 72b9c3d commit b39770d

File tree

3 files changed

+182
-37
lines changed

3 files changed

+182
-37
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
1010
- [`no-restricted-paths`]: fix false positive matches ([#2090], thanks [@malykhinvi])
1111
- [`no-cycle`]: ignore imports where imported file only imports types of importing file ([#2083], thanks [@cherryblossom000])
1212
- [`no-cycle`]: fix false negative when file imports a type after importing a value in Flow ([#2083], thanks [@cherryblossom000])
13+
- [`order`]: restore default behavior unless `type` is in groups ([#2087], thanks [@grit96])
1314

1415
### Changed
1516
- [Docs] Add `no-relative-packages` to list of to the list of rules ([#2075], thanks [@arvigeus])
@@ -792,6 +793,7 @@ for info on changes for earlier releases.
792793
[`memo-parser`]: ./memo-parser/README.md
793794

794795
[#2090]: https://github.com/benmosher/eslint-plugin-import/pull/2090
796+
[#2087]: https://github.com/benmosher/eslint-plugin-import/pull/2087
795797
[#2083]: https://github.com/benmosher/eslint-plugin-import/pull/2083
796798
[#2075]: https://github.com/benmosher/eslint-plugin-import/pull/2075
797799
[#2071]: https://github.com/benmosher/eslint-plugin-import/pull/2071

src/rules/order.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ function computeRank(context, ranks, importEntry, excludedImportTypes) {
313313
let rank;
314314
if (importEntry.type === 'import:object') {
315315
impType = 'object';
316-
} else if (importEntry.node.importKind === 'type') {
316+
} else if (importEntry.node.importKind === 'type' && ranks.omittedTypes.indexOf('type') === -1) {
317317
impType = 'type';
318318
} else {
319319
impType = importType(importEntry.value, context);
@@ -382,10 +382,12 @@ function convertGroupsToRanks(groups) {
382382
return rankObject[type] === undefined;
383383
});
384384

385-
return omittedTypes.reduce(function(res, type) {
385+
const ranks = omittedTypes.reduce(function(res, type) {
386386
res[type] = groups.length;
387387
return res;
388388
}, rankObject);
389+
390+
return { groups: ranks, omittedTypes };
389391
}
390392

391393
function convertPathGroupsForRanks(pathGroups) {
@@ -590,8 +592,10 @@ module.exports = {
590592

591593
try {
592594
const { pathGroups, maxPosition } = convertPathGroupsForRanks(options.pathGroups || []);
595+
const { groups, omittedTypes } = convertGroupsToRanks(options.groups || defaultGroups);
593596
ranks = {
594-
groups: convertGroupsToRanks(options.groups || defaultGroups),
597+
groups,
598+
omittedTypes,
595599
pathGroups,
596600
maxPosition,
597601
};

tests/src/rules/order.js

+173-34
Original file line numberDiff line numberDiff line change
@@ -2243,6 +2243,50 @@ context('TypeScript', function () {
22432243
// #1667: typescript type import support
22442244

22452245
// Option alphabetize: {order: 'asc'}
2246+
test(
2247+
{
2248+
code: `
2249+
import c from 'Bar';
2250+
import type { C } from 'Bar';
2251+
import b from 'bar';
2252+
import a from 'foo';
2253+
import type { A } from 'foo';
2254+
2255+
import index from './';
2256+
`,
2257+
parser,
2258+
options: [
2259+
{
2260+
groups: ['external', 'index'],
2261+
alphabetize: { order: 'asc' },
2262+
},
2263+
],
2264+
},
2265+
parserConfig,
2266+
),
2267+
// Option alphabetize: {order: 'desc'}
2268+
test(
2269+
{
2270+
code: `
2271+
import a from 'foo';
2272+
import type { A } from 'foo';
2273+
import b from 'bar';
2274+
import c from 'Bar';
2275+
import type { C } from 'Bar';
2276+
2277+
import index from './';
2278+
`,
2279+
parser,
2280+
options: [
2281+
{
2282+
groups: ['external', 'index'],
2283+
alphabetize: { order: 'desc' },
2284+
},
2285+
],
2286+
},
2287+
parserConfig,
2288+
),
2289+
// Option alphabetize: {order: 'asc'} with type group
22462290
test(
22472291
{
22482292
code: `
@@ -2258,14 +2302,14 @@ context('TypeScript', function () {
22582302
parser,
22592303
options: [
22602304
{
2261-
groups: ['external', 'index'],
2305+
groups: ['external', 'index', 'type'],
22622306
alphabetize: { order: 'asc' },
22632307
},
22642308
],
22652309
},
22662310
parserConfig,
22672311
),
2268-
// Option alphabetize: {order: 'desc'}
2312+
// Option alphabetize: {order: 'desc'} with type group
22692313
test(
22702314
{
22712315
code: `
@@ -2281,7 +2325,7 @@ context('TypeScript', function () {
22812325
parser,
22822326
options: [
22832327
{
2284-
groups: ['external', 'index'],
2328+
groups: ['external', 'index', 'type'],
22852329
alphabetize: { order: 'desc' },
22862330
},
22872331
],
@@ -2303,35 +2347,130 @@ context('TypeScript', function () {
23032347
},
23042348
parserConfig,
23052349
),
2350+
test(
2351+
{
2352+
code: `
2353+
import { serialize, parse, mapFieldErrors } from '@vtaits/form-schema';
2354+
import type { GetFieldSchema } from '@vtaits/form-schema';
2355+
import { useMemo, useCallback } from 'react';
2356+
import type { ReactElement, ReactNode } from 'react';
2357+
import { Form } from 'react-final-form';
2358+
import type { FormProps as FinalFormProps } from 'react-final-form';
2359+
`,
2360+
parser,
2361+
options: [
2362+
{
2363+
alphabetize: { order: 'asc' },
2364+
},
2365+
],
2366+
},
2367+
parserConfig,
2368+
),
23062369
],
23072370
invalid: [
23082371
// Option alphabetize: {order: 'asc'}
23092372
test(
23102373
{
23112374
code: `
2312-
import b from 'bar';
2313-
import c from 'Bar';
2314-
import a from 'foo';
2315-
2316-
import index from './';
2375+
import b from 'bar';
2376+
import c from 'Bar';
2377+
import type { C } from 'Bar';
2378+
import a from 'foo';
2379+
import type { A } from 'foo';
23172380
2318-
import type { A } from 'foo';
2319-
import type { C } from 'Bar';
2320-
`,
2381+
import index from './';
2382+
`,
23212383
output: `
2322-
import c from 'Bar';
2323-
import b from 'bar';
2324-
import a from 'foo';
2384+
import c from 'Bar';
2385+
import type { C } from 'Bar';
2386+
import b from 'bar';
2387+
import a from 'foo';
2388+
import type { A } from 'foo';
23252389
2326-
import index from './';
2390+
import index from './';
2391+
`,
2392+
parser,
2393+
options: [
2394+
{
2395+
groups: ['external', 'index'],
2396+
alphabetize: { order: 'asc' },
2397+
},
2398+
],
2399+
errors: [
2400+
{
2401+
message: semver.satisfies(eslintPkg.version, '< 3')
2402+
? '`bar` import should occur after import of `Bar`'
2403+
: /(`bar` import should occur after import of `Bar`)|(`Bar` import should occur before import of `bar`)/,
2404+
},
2405+
],
2406+
},
2407+
parserConfig,
2408+
),
2409+
// Option alphabetize: {order: 'desc'}
2410+
test(
2411+
{
2412+
code: `
2413+
import a from 'foo';
2414+
import type { A } from 'foo';
2415+
import c from 'Bar';
2416+
import type { C } from 'Bar';
2417+
import b from 'bar';
23272418
2328-
import type { C } from 'Bar';
2329-
import type { A } from 'foo';
2330-
`,
2419+
import index from './';
2420+
`,
2421+
output: `
2422+
import a from 'foo';
2423+
import type { A } from 'foo';
2424+
import b from 'bar';
2425+
import c from 'Bar';
2426+
import type { C } from 'Bar';
2427+
2428+
import index from './';
2429+
`,
23312430
parser,
23322431
options: [
23332432
{
23342433
groups: ['external', 'index'],
2434+
alphabetize: { order: 'desc' },
2435+
},
2436+
],
2437+
errors: [
2438+
{
2439+
message: semver.satisfies(eslintPkg.version, '< 3')
2440+
? '`bar` import should occur before import of `Bar`'
2441+
: /(`bar` import should occur before import of `Bar`)|(`Bar` import should occur after import of `bar`)/,
2442+
},
2443+
],
2444+
},
2445+
parserConfig,
2446+
),
2447+
// Option alphabetize: {order: 'asc'} with type group
2448+
test(
2449+
{
2450+
code: `
2451+
import b from 'bar';
2452+
import c from 'Bar';
2453+
import a from 'foo';
2454+
2455+
import index from './';
2456+
2457+
import type { A } from 'foo';
2458+
import type { C } from 'Bar';
2459+
`,
2460+
output: `
2461+
import c from 'Bar';
2462+
import b from 'bar';
2463+
import a from 'foo';
2464+
2465+
import index from './';
2466+
2467+
import type { C } from 'Bar';
2468+
import type { A } from 'foo';
2469+
`,
2470+
parser,
2471+
options: [
2472+
{
2473+
groups: ['external', 'index', 'type'],
23352474
alphabetize: { order: 'asc' },
23362475
},
23372476
],
@@ -2345,33 +2484,33 @@ context('TypeScript', function () {
23452484
},
23462485
parserConfig,
23472486
),
2348-
// Option alphabetize: {order: 'desc'}
2487+
// Option alphabetize: {order: 'desc'} with type group
23492488
test(
23502489
{
23512490
code: `
2352-
import a from 'foo';
2353-
import c from 'Bar';
2354-
import b from 'bar';
2491+
import a from 'foo';
2492+
import c from 'Bar';
2493+
import b from 'bar';
23552494
2356-
import index from './';
2495+
import index from './';
23572496
2358-
import type { C } from 'Bar';
2359-
import type { A } from 'foo';
2360-
`,
2497+
import type { C } from 'Bar';
2498+
import type { A } from 'foo';
2499+
`,
23612500
output: `
2362-
import a from 'foo';
2363-
import b from 'bar';
2364-
import c from 'Bar';
2501+
import a from 'foo';
2502+
import b from 'bar';
2503+
import c from 'Bar';
23652504
2366-
import index from './';
2505+
import index from './';
23672506
2368-
import type { A } from 'foo';
2369-
import type { C } from 'Bar';
2370-
`,
2507+
import type { A } from 'foo';
2508+
import type { C } from 'Bar';
2509+
`,
23712510
parser,
23722511
options: [
23732512
{
2374-
groups: ['external', 'index'],
2513+
groups: ['external', 'index', 'type'],
23752514
alphabetize: { order: 'desc' },
23762515
},
23772516
],

0 commit comments

Comments
 (0)