Skip to content

Commit

Permalink
fix: do not fix objects if last member contains a comment and doesn't…
Browse files Browse the repository at this point in the history
… contain comma
  • Loading branch information
azat-io committed Jun 6, 2023
1 parent 0abffbe commit a9915f1
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 19 deletions.
59 changes: 40 additions & 19 deletions rules/sort-objects.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import type { TSESTree } from '@typescript-eslint/types'
import type { TSESLint } from '@typescript-eslint/utils'
import type { SortingNode } from '../typings'

import { AST_NODE_TYPES } from '@typescript-eslint/types'
import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/types'

import { createEslintRule } from '../utils/create-eslint-rule'
import { toSingleLine } from '../utils/to-single-line'
import { rangeToDiff } from '../utils/range-to-diff'
import { getComment } from '../utils/get-comment'
import { SortType, SortOrder } from '../typings'
import { sortNodes } from '../utils/sort-nodes'
import { makeFixes } from '../utils/make-fixes'
import { sortNodes } from '../utils/sort-nodes'
import { complete } from '../utils/complete'
import { pairwise } from '../utils/pairwise'
import { groupBy } from '../utils/group-by'
Expand Down Expand Up @@ -159,30 +161,49 @@ export default createEslintRule<Options, MESSAGE_ID>({
}

if (comparison) {
let nextToken = source.getTokenAfter(nodes.at(-1)!.node, {
includeComments: true,
})

let hasTrailingComma =
nextToken?.type === AST_TOKEN_TYPES.Punctuator &&
nextToken.value === ','

let fix:
| ((fixer: TSESLint.RuleFixer) => TSESLint.RuleFix[])
| undefined = fixer => {
let groups = groupBy(nodes, ({ position }) => position)

let getGroup = (index: string) =>
index in groups ? groups[index] : []

let sortedNodes = [
getGroup(Position.exception).sort(
(aNode, bNode) =>
options['always-on-top'].indexOf(aNode.name) -
options['always-on-top'].indexOf(bNode.name),
),
sortNodes(getGroup(Position.ignore), options),
].flat()

return makeFixes(fixer, nodes, sortedNodes, source)
}

if (
!hasTrailingComma &&
getComment(nodes.at(-1)!.node, source).after
) {
fix = undefined
}

context.report({
messageId: 'unexpectedObjectsOrder',
data: {
left: toSingleLine(left.name),
right: toSingleLine(right.name),
},
node: right.node,
fix: fixer => {
let groups = groupBy(nodes, ({ position }) => position)

let getGroup = (index: string) =>
index in groups ? groups[index] : []

let sortedNodes = [
getGroup(Position.exception).sort(
(aNode, bNode) =>
options['always-on-top'].indexOf(aNode.name) -
options['always-on-top'].indexOf(bNode.name),
),
sortNodes(getGroup(Position.ignore), options),
].flat()

return makeFixes(fixer, nodes, sortedNodes, source)
},
fix,
})
}
})
Expand Down
93 changes: 93 additions & 0 deletions test/sort-objects.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,37 @@ describe(RULE_NAME, () => {
],
})
})

it(`${RULE_NAME}(${type}): do not sorts objects without a comma and with a comment in the last element`, () => {
ruleTester.run(RULE_NAME, rule, {
valid: [],
invalid: [
{
code: dedent`
let daddies = {
rei: 'Rei Suwa', // daddy #1
kazuki: 'Kazuki Kurusu' // daddy #2
}
`,
options: [
{
type: SortType.alphabetical,
order: SortOrder.asc,
},
],
errors: [
{
messageId: 'unexpectedObjectsOrder',
data: {
left: 'rei',
right: 'kazuki',
},
},
],
},
],
})
})
})

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

it(`${RULE_NAME}(${type}): do not sorts objects without a comma and with a comment in the last element`, () => {
ruleTester.run(RULE_NAME, rule, {
valid: [],
invalid: [
{
code: dedent`
let daddies = {
rei: 'Rei Suwa', // daddy #1
kazuki: 'Kazuki Kurusu' // daddy #2
}
`,
options: [
{
type: SortType.natural,
order: SortOrder.asc,
},
],
errors: [
{
messageId: 'unexpectedObjectsOrder',
data: {
left: 'rei',
right: 'kazuki',
},
},
],
},
],
})
})
})

describe(`${RULE_NAME}: sorting by line length`, () => {
Expand Down Expand Up @@ -1274,6 +1336,37 @@ describe(RULE_NAME, () => {
],
})
})

it(`${RULE_NAME}(${type}): do not sorts objects without a comma and with a comment in the last element`, () => {
ruleTester.run(RULE_NAME, rule, {
valid: [],
invalid: [
{
code: dedent`
let daddies = {
rei: 'Rei Suwa', // daddy #1
kazuki: 'Kazuki Kurusu' // daddy #2
}
`,
options: [
{
type: SortType['line-length'],
order: SortOrder.desc,
},
],
errors: [
{
messageId: 'unexpectedObjectsOrder',
data: {
left: 'rei',
right: 'kazuki',
},
},
],
},
],
})
})
})

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

0 comments on commit a9915f1

Please sign in to comment.