Skip to content

Commit

Permalink
fix: split imports if there are other nodes between
Browse files Browse the repository at this point in the history
  • Loading branch information
azat-io committed Jun 6, 2023
1 parent 37a537d commit b1a8837
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 46 deletions.
108 changes: 62 additions & 46 deletions rules/sort-imports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,6 @@ export default createEslintRule<Options, MESSAGE_ID>({
left: SortingNode,
right: SortingNode,
) => {
if (hasContentBetweenNodes(left, right)) {
return 0
}

let linesBetweenImports = source.lines.slice(
left.node.loc.end.line,
right.node.loc.start.line - 1,
Expand Down Expand Up @@ -396,57 +392,50 @@ export default createEslintRule<Options, MESSAGE_ID>({
return fixes
}

pairwise(nodes, (left, right) => {
let leftNum = getGroupNumber(left)
let rightNum = getGroupNumber(right)

let numberOfEmptyLinesBetween = getLinesBetweenImports(left, right)

if (
!hasContentBetweenNodes(left, right) &&
(leftNum > rightNum ||
(leftNum === rightNum && compare(left, right, options)))
) {
context.report({
messageId: 'unexpectedImportsOrder',
data: {
left: left.name,
right: right.name,
},
node: right.node,
fix,
})
}
let splittedNodes = nodes.reduce(
(
accumulator: SortingNodeWithGroup[][],
node: SortingNodeWithGroup,
) => {
let lastNode = accumulator.at(-1)?.at(-1)

if (lastNode && hasContentBetweenNodes(lastNode, node)) {
accumulator.push([node])
} else {
accumulator.at(-1)!.push(node)
}

if (
options['newlines-between'] === 'never' &&
numberOfEmptyLinesBetween > 0
) {
context.report({
messageId: 'extraSpacingBetweenImports',
data: {
left: left.name,
right: right.name,
},
node: right.node,
fix,
})
}
return accumulator
},
[[]],
)

splittedNodes.forEach(nodeList => {
pairwise(nodeList, (left, right) => {
let leftNum = getGroupNumber(left)
let rightNum = getGroupNumber(right)

let numberOfEmptyLinesBetween = getLinesBetweenImports(left, right)

if (options['newlines-between'] === 'always') {
if (leftNum < rightNum && numberOfEmptyLinesBetween === 0) {
if (
!hasContentBetweenNodes(left, right) &&
(leftNum > rightNum ||
(leftNum === rightNum && compare(left, right, options)))
) {
context.report({
messageId: 'missedSpacingBetweenImports',
messageId: 'unexpectedImportsOrder',
data: {
left: left.name,
right: right.name,
},
node: right.node,
fix,
})
} else if (
numberOfEmptyLinesBetween > 1 ||
(leftNum === rightNum && numberOfEmptyLinesBetween > 0)
}

if (
options['newlines-between'] === 'never' &&
numberOfEmptyLinesBetween > 0
) {
context.report({
messageId: 'extraSpacingBetweenImports',
Expand All @@ -458,7 +447,34 @@ export default createEslintRule<Options, MESSAGE_ID>({
fix,
})
}
}

if (options['newlines-between'] === 'always') {
if (leftNum < rightNum && numberOfEmptyLinesBetween === 0) {
context.report({
messageId: 'missedSpacingBetweenImports',
data: {
left: left.name,
right: right.name,
},
node: right.node,
fix,
})
} else if (
numberOfEmptyLinesBetween > 1 ||
(leftNum === rightNum && numberOfEmptyLinesBetween > 0)
) {
context.report({
messageId: 'extraSpacingBetweenImports',
data: {
left: left.name,
right: right.name,
},
node: right.node,
fix,
})
}
}
})
})
},
}
Expand Down
105 changes: 105 additions & 0 deletions test/sort-imports.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,41 @@ describe(RULE_NAME, () => {
invalid: [],
})
})

it(`${RULE_NAME}(${type}): breaks import sorting if there is other nodes between`, () => {
ruleTester.run(RULE_NAME, rule, {
valid: [
{
code: dedent`
import type { Totoro } from 'gods-of-forest'
export type { KonekoBus } from 'bus-station'
import type { Satsuki, Mei } from './data/users'
`,
options: [
{
type: SortType.alphabetical,
order: SortOrder.asc,
'newlines-between': NewlinesBetweenValue.always,
'internal-pattern': ['~/**'],
groups: [
'type',
['builtin', 'external'],
'internal-type',
'internal',
['parent-type', 'sibling-type', 'index-type'],
['parent', 'sibling', 'index'],
'object',
'unknown',
],
},
],
},
],
invalid: [],
})
})
})

describe(`${RULE_NAME}: sorting by natural order`, () => {
Expand Down Expand Up @@ -1390,6 +1425,41 @@ describe(RULE_NAME, () => {
invalid: [],
})
})

it(`${RULE_NAME}(${type}): breaks import sorting if there is other nodes between`, () => {
ruleTester.run(RULE_NAME, rule, {
valid: [
{
code: dedent`
import type { Totoro } from 'gods-of-forest'
export type { KonekoBus } from 'bus-station'
import type { Satsuki, Mei } from './data/users'
`,
options: [
{
type: SortType.natural,
order: SortOrder.asc,
'newlines-between': NewlinesBetweenValue.always,
'internal-pattern': ['~/**'],
groups: [
'type',
['builtin', 'external'],
'internal-type',
'internal',
['parent-type', 'sibling-type', 'index-type'],
['parent', 'sibling', 'index'],
'object',
'unknown',
],
},
],
},
],
invalid: [],
})
})
})

describe(`${RULE_NAME}: sorting by line length`, () => {
Expand Down Expand Up @@ -2123,6 +2193,41 @@ describe(RULE_NAME, () => {
invalid: [],
})
})

it(`${RULE_NAME}(${type}): breaks import sorting if there is other nodes between`, () => {
ruleTester.run(RULE_NAME, rule, {
valid: [
{
code: dedent`
import type { Totoro } from 'gods-of-forest'
export type { KonekoBus } from 'bus-station'
import type { Satsuki, Mei } from './data/users'
`,
options: [
{
type: SortType['line-length'],
order: SortOrder.desc,
'newlines-between': NewlinesBetweenValue.always,
'internal-pattern': ['~/**'],
groups: [
'type',
['builtin', 'external'],
'internal-type',
'internal',
['parent-type', 'sibling-type', 'index-type'],
['parent', 'sibling', 'index'],
'object',
'unknown',
],
},
],
},
],
invalid: [],
})
})
})

describe(`${RULE_NAME}: misc`, () => {
Expand Down

0 comments on commit b1a8837

Please sign in to comment.