Skip to content

Commit

Permalink
fix: fix use of case named default in sort-switch-case rule
Browse files Browse the repository at this point in the history
  • Loading branch information
hugop95 committed Aug 27, 2024
1 parent 69c1d50 commit 5583eb0
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 10 deletions.
25 changes: 15 additions & 10 deletions rules/sort-switch-case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ type Options = [
}>,
]

interface SortSwitchCaseSortingNode extends SortingNode<TSESTree.SwitchCase> {
isDefaultClause: boolean
}

export default createEslintRule<Options, MESSAGE_ID>({
name: 'sort-switch-case',
meta: {
Expand Down Expand Up @@ -94,20 +98,23 @@ export default createEslintRule<Options, MESSAGE_ID>({
)

if (isDiscriminantIdentifier && isCasesHasBreak) {
let nodes = node.cases.map<SortingNode<TSESTree.SwitchCase>>(
let nodes = node.cases.map<SortSwitchCaseSortingNode>(
(caseNode: TSESTree.SwitchCase) => {
let name: string
let isDefaultClause = false
if (caseNode.test?.type === 'Literal') {
name = `${caseNode.test.value}`
} else if (caseNode.test === null) {
name = 'default'
isDefaultClause = true
} else {
name = sourceCode.text.slice(...caseNode.test.range)
}

return {
size: rangeToDiff(caseNode.test?.range ?? caseNode.range),
node: caseNode,
isDefaultClause,
name,
}
},
Expand All @@ -120,8 +127,8 @@ export default createEslintRule<Options, MESSAGE_ID>({
lefter?.node.consequent.length === 0 &&
left.node.consequent.length !== 0

let isGroupContainsDefault = (group: SortingNode[]) =>
group.some(currentNode => currentNode.name === 'default')
let isGroupContainsDefault = (group: SortSwitchCaseSortingNode[]) =>
group.some(currentNode => currentNode.isDefaultClause)

let leftCaseGroup = [left]
let rightCaseGroup = [right]
Expand Down Expand Up @@ -163,12 +170,10 @@ export default createEslintRule<Options, MESSAGE_ID>({
node: right.node,
fix: fixer => {
let additionalFixes: TSESLint.RuleFix[] = []
let nodeGroups = nodes.reduce<
SortingNode<TSESTree.SwitchCase>[][]
>(
let nodeGroups = nodes.reduce<SortSwitchCaseSortingNode[][]>(
(
accumulator: SortingNode<TSESTree.SwitchCase>[][],
currentNode: SortingNode<TSESTree.SwitchCase>,
accumulator: SortSwitchCaseSortingNode[][],
currentNode: SortSwitchCaseSortingNode,
index,
) => {
if (index === 0) {
Expand All @@ -188,7 +193,7 @@ export default createEslintRule<Options, MESSAGE_ID>({
let sortedNodeGroups = nodeGroups
.map(group => {
let sortedGroup = sortNodes(group, options).sort((a, b) => {
if (b.name === 'default') {
if (b.isDefaultClause) {
return -1
}
return 1
Expand Down Expand Up @@ -244,7 +249,7 @@ export default createEslintRule<Options, MESSAGE_ID>({
let sortedNodes = sortedNodeGroups.flat()

for (let max = sortedNodes.length, i = 0; i < max; i++) {
if (sortedNodes.at(i)!.name === 'default') {
if (sortedNodes.at(i)!.isDefaultClause) {
sortedNodes.push(sortedNodes.splice(i, 1).at(0)!)
}
}
Expand Down
54 changes: 54 additions & 0 deletions test/sort-switch-case.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1626,4 +1626,58 @@ describe(ruleName, () => {
},
],
})

ruleTester.run(`${ruleName}: handles default case and default clause`, rule, {
valid: [
dedent`
switch (variable) {
case 'add':
break
case 'default':
break
case 'remove':
break
default:
break
}
`,
],
invalid: [
{
code: dedent`
switch (variable) {
case 'default':
break
case 'add':
break
case 'remove':
break
default:
break
}
`,
output: dedent`
switch (variable) {
case 'add':
break
case 'default':
break
case 'remove':
break
default:
break
}
`,
errors: [
{
messageId: 'unexpectedSwitchCaseOrder',
data: {
left: 'default',
right: 'add',
},
},
],
},
],
})
})

0 comments on commit 5583eb0

Please sign in to comment.