Skip to content

Commit

Permalink
fix: fix switch case sorting with grouped default case
Browse files Browse the repository at this point in the history
  • Loading branch information
azat-io committed Jul 31, 2024
1 parent 7efadfa commit 7428523
Show file tree
Hide file tree
Showing 2 changed files with 212 additions and 12 deletions.
34 changes: 24 additions & 10 deletions rules/sort-switch-case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,18 @@ export default createEslintRule<Options, MESSAGE_ID>({
if (isDiscriminantIdentifier && isCasesHasBreak) {
let nodes = node.cases.map<SortingNode<TSESTree.SwitchCase>>(
(caseNode: TSESTree.SwitchCase) => {
let name
let name: string
if (caseNode.test?.type === 'Literal') {
name = `${caseNode.test.value}`
} else {
} else if (caseNode.test === null) {
name = 'default'
} else {
name = sourceCode.text.slice(...caseNode.test.range)
}

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

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

let leftCaseGroup = [left]
let rightCaseGroup = [right]
for (let i = iteration - 1; i >= 0; i--) {
if (nodes.at(i)!.node.consequent.length === 0) {
caseGroup.unshift(nodes.at(i)!)
leftCaseGroup.unshift(nodes.at(i)!)
} else {
break
}
}
if (right.node.consequent.length === 0) {
for (let i = iteration + 1; i < nodes.length; i++) {
if (nodes.at(i)!.node.consequent.length === 0) {
rightCaseGroup.push(nodes.at(i)!)
} else {
rightCaseGroup.push(nodes.at(i)!)
break
}
}
}

if (left.name === 'default') {
if (isGroupContainsDefault(leftCaseGroup)) {
compareValue = true
} else if (right.name === 'default') {
} else if (isGroupContainsDefault(rightCaseGroup)) {
compareValue = false
} else if (isCaseGrouped) {
compareValue = isPositive(compare(caseGroup[0], right, options))
compareValue = isPositive(compare(leftCaseGroup[0], right, options))
} else {
compareValue = isPositive(compare(left, right, options))
}
Expand Down Expand Up @@ -173,8 +189,6 @@ export default createEslintRule<Options, MESSAGE_ID>({
return sortedGroup
})
.toSorted((a, b) => {
let isGroupContainsDefault = (group: SortingNode[]) =>
group.some(currentNode => currentNode.name === 'default')
if (isGroupContainsDefault(a)) {
return 1
} else if (isGroupContainsDefault(b)) {
Expand Down
190 changes: 188 additions & 2 deletions test/sort-switch-case.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,71 @@ describe(ruleName, () => {
},
],
})

ruleTester.run(
`${ruleName}(${type}): works with grouped cases with default`,
rule,
{
valid: [
{
code: dedent`
switch (operationMode) {
case wwww:
return null
case yy:
case z:
return null
case xxx:
default:
return null
}
`,
options: [options],
},
],
invalid: [
{
code: dedent`
switch (operationMode) {
case yy:
case z:
return null
case wwww:
return null
case xxx:
default:
return null
}
`,
output: dedent`
switch (operationMode) {
case wwww:
return null
case yy:
case z:
return null
case xxx:
default:
return null
}
`,
options: [options],
errors: [
{
messageId: 'unexpectedSwitchCaseOrder',
data: {
left: 'z',
right: 'wwww',
},
},
],
},
],
},
)
})

describe(`${ruleName}: sorts switch cases with return statements`, () => {
describe(`${ruleName}: sorting by natural order`, () => {
let type = 'natural-order'

let options = {
Expand Down Expand Up @@ -492,9 +554,71 @@ describe(ruleName, () => {
},
],
})

ruleTester.run(
`${ruleName}(${type}): works with grouped cases with default`,
rule,
{
valid: [
{
code: dedent`
switch (operationMode) {
case wwww:
return null
case yy:
case z:
return null
case xxx:
default:
return null
}
`,
options: [options],
},
],
invalid: [
{
code: dedent`
switch (operationMode) {
case yy:
case z:
return null
case wwww:
return null
case xxx:
default:
return null
}
`,
output: dedent`
switch (operationMode) {
case wwww:
return null
case yy:
case z:
return null
case xxx:
default:
return null
}
`,
options: [options],
errors: [
{
messageId: 'unexpectedSwitchCaseOrder',
data: {
left: 'z',
right: 'wwww',
},
},
],
},
],
},
)
})

describe(`${ruleName}: sorts switch cases with return statements`, () => {
describe(`${ruleName}: sorting by line length`, () => {
let type = 'line-length-order'

let options = {
Expand Down Expand Up @@ -729,6 +853,68 @@ describe(ruleName, () => {
},
],
})

ruleTester.run(
`${ruleName}(${type}): works with grouped cases with default`,
rule,
{
valid: [
{
code: dedent`
switch (operationMode) {
case wwww:
return null
case yy:
case z:
return null
case xxx:
default:
return null
}
`,
options: [options],
},
],
invalid: [
{
code: dedent`
switch (operationMode) {
case yy:
case z:
return null
case wwww:
return null
case xxx:
default:
return null
}
`,
output: dedent`
switch (operationMode) {
case wwww:
return null
case yy:
case z:
return null
case xxx:
default:
return null
}
`,
options: [options],
errors: [
{
messageId: 'unexpectedSwitchCaseOrder',
data: {
left: 'z',
right: 'wwww',
},
},
],
},
],
},
)
})

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

0 comments on commit 7428523

Please sign in to comment.