Skip to content

Commit

Permalink
fix: move parentheses when sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
azat-io committed May 31, 2023
1 parent 7ec24d5 commit d09395f
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 3 deletions.
5 changes: 3 additions & 2 deletions rules/sort-union-types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createEslintRule } from '~/utils/create-eslint-rule'
import { toSingleLine } from '~/utils/to-single-line'
import { rangeToDiff } from '~/utils/range-to-diff'
import { SortType, SortOrder } from '~/typings'
import { sortNodes } from '~/utils/sort-nodes'
Expand Down Expand Up @@ -78,8 +79,8 @@ export default createEslintRule<Options, MESSAGE_ID>({
context.report({
messageId: 'unexpectedUnionTypesOrder',
data: {
first: first.name,
second: second.name,
first: toSingleLine(first.name),
second: toSingleLine(second.name),
},
node: second.node,
fix: fixer =>
Expand Down
142 changes: 142 additions & 0 deletions test/sort-union-types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,51 @@ describe(RULE_NAME, () => {
],
})
})

it(`${RULE_NAME}: sorts unions with parentheses`, () => {
ruleTester.run(RULE_NAME, rule, {
valid: [],
invalid: [
{
code: dedent`
type HeroAssociation = {
team:
| Saitama
| ((
superstrike: () => void,
) => Hero[] | Saitama)
| Hero[]
}
`,
output: dedent`
type HeroAssociation = {
team:
| ((
superstrike: () => void,
) => Hero[] | Saitama)
| Hero[]
| Saitama
}
`,
options: [
{
type: SortType.alphabetical,
order: SortOrder.asc,
},
],
errors: [
{
messageId: 'unexpectedUnionTypesOrder',
data: {
first: 'Saitama',
second: '( superstrike: () => void, ) => Hero[] | Saitama',
},
},
],
},
],
})
})
})

describe(`${RULE_NAME}: sorting by natural order`, () => {
Expand Down Expand Up @@ -424,6 +469,51 @@ describe(RULE_NAME, () => {
],
})
})

it(`${RULE_NAME}: sorts unions with parentheses`, () => {
ruleTester.run(RULE_NAME, rule, {
valid: [],
invalid: [
{
code: dedent`
type HeroAssociation = {
team:
| Saitama
| ((
superstrike: () => void,
) => Hero[] | Saitama)
| Hero[]
}
`,
output: dedent`
type HeroAssociation = {
team:
| ((
superstrike: () => void,
) => Hero[] | Saitama)
| Hero[]
| Saitama
}
`,
options: [
{
type: SortType.natural,
order: SortOrder.asc,
},
],
errors: [
{
messageId: 'unexpectedUnionTypesOrder',
data: {
first: 'Saitama',
second: '( superstrike: () => void, ) => Hero[] | Saitama',
},
},
],
},
],
})
})
})

describe(`${RULE_NAME}: sorting by line length`, () => {
Expand Down Expand Up @@ -615,5 +705,57 @@ describe(RULE_NAME, () => {
],
})
})

it(`${RULE_NAME}: sorts unions with parentheses`, () => {
ruleTester.run(RULE_NAME, rule, {
valid: [],
invalid: [
{
code: dedent`
type HeroAssociation = {
team:
| Saitama
| ((
superstrike: () => void,
) => Hero[] | Saitama)
| Hero[]
}
`,
output: dedent`
type HeroAssociation = {
team:
| ((
superstrike: () => void,
) => Hero[] | Saitama)
| Saitama
| Hero[]
}
`,
options: [
{
type: SortType['line-length'],
order: SortOrder.desc,
},
],
errors: [
{
messageId: 'unexpectedUnionTypesOrder',
data: {
first: 'Saitama',
second: '( superstrike: () => void, ) => Hero[] | Saitama',
},
},
{
messageId: 'unexpectedUnionTypesOrder',
data: {
first: 'Hero[]',
second: 'Saitama',
},
},
],
},
],
})
})
})
})
27 changes: 26 additions & 1 deletion utils/get-node-range.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,37 @@
import type { TSESLint } from '@typescript-eslint/utils'
import type { TSESTree } from '@typescript-eslint/types'

import { ASTUtils } from '@typescript-eslint/utils'

import { getComment } from '~/utils/get-comment'

export let getNodeRange = (
node: TSESTree.Node,
sourceCode: TSESLint.SourceCode,
): TSESTree.Range => {
let start = node.range.at(0)!
let end = node.range.at(1)!

if (ASTUtils.isParenthesized(node, sourceCode)) {
let bodyOpeningParen = sourceCode.getTokenBefore(
node,
ASTUtils.isOpeningParenToken,
)!

let bodyClosingParen = sourceCode.getTokenAfter(
node,
ASTUtils.isClosingParenToken,
)!

start = bodyOpeningParen.range.at(0)!
end = bodyClosingParen.range.at(1)!
}

let comment = getComment(node, sourceCode)
return [comment?.range.at(0) ?? node.range.at(0)!, node.range.at(1)!]

if (comment) {
start = comment.range.at(0)!
}

return [start, end]
}
2 changes: 2 additions & 0 deletions utils/to-single-line.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export let toSingleLine = (string: string): string =>
string.replaceAll(/\s\s+/g, ' ').trim()

0 comments on commit d09395f

Please sign in to comment.