From defd3703aede0b179aab3d26f64dc0c02cb67b1e Mon Sep 17 00:00:00 2001 From: Hugo <60015232+hugop95@users.noreply.github.com> Date: Mon, 23 Sep 2024 20:28:43 +0200 Subject: [PATCH] feat: add partition by new line option in sort-enums --- docs/content/rules/sort-enums.mdx | 29 ++++++++- rules/sort-enums.ts | 44 ++++++++----- test/sort-enums.test.ts | 104 +++++++++++++++++++++++------- 3 files changed, 135 insertions(+), 42 deletions(-) diff --git a/docs/content/rules/sort-enums.mdx b/docs/content/rules/sort-enums.mdx index ad930d39..1d8e40f9 100644 --- a/docs/content/rules/sort-enums.mdx +++ b/docs/content/rules/sort-enums.mdx @@ -140,7 +140,29 @@ Allows you to use comments to separate the members of enums into logical groups. - `true` — All comments will be treated as delimiters, creating partitions. - `false` — Comments will not be used as delimiters. -- string — A glob pattern to specify which comments should act as delimiters. +- `string` — A glob pattern to specify which comments should act as delimiters. +- `string[]` — A list of glob patterns to specify which comments should act as delimiters. + +### partitionByNewLine + +default: `false` + +When `true`, the rule will not sort the members of an enum if there is an empty line between them. This can be useful for keeping logically separated groups of members in their defined order. + +```ts +enum Enum { + // Group 1 + C = 'C', + D = 'D', + + // Group 2 + B = 'B', + + // Group 3 + A = 'A', + E = 'E', +} +``` ## Usage @@ -164,7 +186,9 @@ Allows you to use comments to separate the members of enums into logical groups. order: 'asc', ignoreCase: true, partitionByComment: false, - sortByValue: false + partitionByNewLine: false, + sortByValue: false, + forceNumericSort: false }, ], }, @@ -189,6 +213,7 @@ Allows you to use comments to separate the members of enums into logical groups. order: 'asc', ignoreCase: true, partitionByComment: false, + partitionByNewLine: false, sortByValue: false, forceNumericSort: false }, diff --git a/rules/sort-enums.ts b/rules/sort-enums.ts index 4d4a7ccd..4519ad6e 100644 --- a/rules/sort-enums.ts +++ b/rules/sort-enums.ts @@ -10,6 +10,7 @@ import { import { hasPartitionComment } from '../utils/is-partition-comment' import { getCommentsBefore } from '../utils/get-comments-before' import { createEslintRule } from '../utils/create-eslint-rule' +import { getLinesBetween } from '../utils/get-lines-between' import { getSourceCode } from '../utils/get-source-code' import { toSingleLine } from '../utils/to-single-line' import { rangeToDiff } from '../utils/range-to-diff' @@ -25,6 +26,7 @@ export type Options = [ Partial<{ type: 'alphabetical' | 'line-length' | 'natural' partitionByComment: string[] | boolean | string + partitionByNewLine: boolean forceNumericSort: boolean order: 'desc' | 'asc' sortByValue: boolean @@ -87,6 +89,11 @@ export default createEslintRule({ }, ], }, + partitionByNewLine: { + description: + 'Allows to use spaces to separate the nodes into logical groups.', + type: 'boolean', + }, }, additionalProperties: false, }, @@ -104,6 +111,7 @@ export default createEslintRule({ ignoreCase: true, sortByValue: false, partitionByComment: false, + partitionByNewLine: false, forceNumericSort: false, }, ], @@ -122,6 +130,7 @@ export default createEslintRule({ let options = complete(context.options.at(0), settings, { partitionByComment: false, + partitionByNewLine: false, type: 'alphabetical', ignoreCase: true, order: 'asc', @@ -181,20 +190,6 @@ export default createEslintRule({ let formattedMembers: SortingNodeWithDependencies[][] = members.reduce( (accumulator: SortingNodeWithDependencies[][], member) => { - let comments = getCommentsBefore(member, sourceCode) - - if ( - partitionComment && - hasPartitionComment(partitionComment, comments) - ) { - accumulator.push([]) - } - - let name = - member.id.type === 'Literal' - ? `${member.id.value}` - : `${sourceCode.text.slice(...member.id.range)}` - let dependencies: string[] = [] if (member.initializer) { dependencies = extractDependencies( @@ -202,13 +197,30 @@ export default createEslintRule({ node.id.name, ) } - + let lastSortingNode = accumulator.at(-1)?.at(-1) let sortingNode: SortingNodeWithDependencies = { size: rangeToDiff(member.range), node: member, dependencies, - name, + name: + member.id.type === 'Literal' + ? `${member.id.value}` + : `${sourceCode.text.slice(...member.id.range)}`, } + + if ( + (partitionComment && + hasPartitionComment( + partitionComment, + getCommentsBefore(member, sourceCode), + )) || + (options.partitionByNewLine && + lastSortingNode && + getLinesBetween(sourceCode, lastSortingNode, sortingNode)) + ) { + accumulator.push([]) + } + accumulator.at(-1)!.push(sortingNode) return accumulator }, diff --git a/test/sort-enums.test.ts b/test/sort-enums.test.ts index 6ce20e6c..be982ed2 100644 --- a/test/sort-enums.test.ts +++ b/test/sort-enums.test.ts @@ -1977,12 +1977,15 @@ describe(ruleName, () => { ) }) - describe('handles complex comment cases', () => { - ruleTester.run(`keeps comments associated to their node`, rule, { - valid: [], - invalid: [ - { - code: dedent` + describe(`${ruleName}: handles complex comment cases`, () => { + ruleTester.run( + `${ruleName}: keeps comments associated to their node`, + rule, + { + valid: [], + invalid: [ + { + code: dedent` enum Enum { // Ignore this comment @@ -2002,7 +2005,7 @@ describe(ruleName, () => { A = 'A', } `, - output: dedent` + output: dedent` enum Enum { // Ignore this comment @@ -2022,25 +2025,26 @@ describe(ruleName, () => { B = 'B', } `, - options: [ - { - type: 'alphabetical', - }, - ], - errors: [ - { - messageId: 'unexpectedEnumsOrder', - data: { - left: 'B', - right: 'A', + options: [ + { + type: 'alphabetical', }, - }, - ], - }, - ], - }) + ], + errors: [ + { + messageId: 'unexpectedEnumsOrder', + data: { + left: 'B', + right: 'A', + }, + }, + ], + }, + ], + }, + ) - ruleTester.run(`handles partition comments`, rule, { + ruleTester.run(`${ruleName}: handles partition comments`, rule, { valid: [], invalid: [ { @@ -2120,5 +2124,57 @@ describe(ruleName, () => { ], }) }) + + ruleTester.run(`${ruleName}: allows to use new line as partition`, rule, { + valid: [], + invalid: [ + { + code: dedent` + enum Enum { + D = 'D', + C = 'C', + + B = 'B', + + E = 'E', + A = 'A', + } + `, + output: dedent` + enum Enum { + C = 'C', + D = 'D', + + B = 'B', + + A = 'A', + E = 'E', + } + `, + options: [ + { + type: 'alphabetical', + partitionByNewLine: true, + }, + ], + errors: [ + { + messageId: 'unexpectedEnumsOrder', + data: { + left: 'D', + right: 'C', + }, + }, + { + messageId: 'unexpectedEnumsOrder', + data: { + left: 'E', + right: 'A', + }, + }, + ], + }, + ], + }) }) })