Repository: azat-io/eslint-plugin-perfectionist
Pull request #377 (2024-11-19 13:28:36)

fix(sort-modules): disables sorting for `export decorated` classes
Will fix temporarily #376 

### Description

The actual fix requires computing and detecting decorators similarly to how comments are detected, but it's not straightforward.

In the meantime, we can simply ignore `export decorated classes`.

### Tests impacted

- 2 tests commented: sorting is disabled in those cases.
- 1 test added.

### What is the purpose of this pull request?

- [x] Bug fix



Patch:
diff --git a/package.json b/package.json
index 9a8350f..09f11b1 100644
--- a/package.json
+++ b/package.json
@@ -50,7 +50,6 @@
     "test:unit": "vitest --run --coverage"
   },
   "dependencies": {
-    "@azat-io/eslint-config": "^2.1.2",
     "@typescript-eslint/types": "^8.15.0",
     "@typescript-eslint/utils": "^8.15.0",
     "natural-orderby": "^5.0.0"
@@ -60,6 +59,7 @@
     "@astrojs/mdx": "^3.1.9",
     "@astrojs/sitemap": "^3.2.1",
     "@astrojs/svelte": "^6.0.1",
+    "@azat-io/eslint-config": "^2.1.2",
     "@azat-io/stylelint-config": "^0.1.1",
     "@commitlint/cli": "^19.6.0",
     "@commitlint/config-conventional": "^19.6.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 28002e5..21bb82a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,9 +8,6 @@ importers:
 
   .:
     dependencies:
-      '@azat-io/eslint-config':
-        specifier: ^2.1.2
-        version: 2.1.2(@typescript-eslint/parser@8.15.0(eslint@9.15.0(jiti@2.4.0))(typescript@5.6.3))(@typescript-eslint/utils@8.15.0(eslint@9.15.0(jiti@2.4.0))(typescript@5.6.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.15.0(eslint@9.15.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.15.0(jiti@2.4.0)))(eslint@9.15.0(jiti@2.4.0))(svelte@5.0.0-next.221)(typescript@5.6.3)(vitest@2.1.5(@types/node@22.9.0)(lightningcss@1.28.1)(terser@5.36.0))
       '@typescript-eslint/types':
         specifier: ^8.15.0
         version: 8.15.0
@@ -33,6 +30,9 @@ importers:
       '@astrojs/svelte':
         specifier: ^6.0.1
         version: 6.0.1(astro@4.16.13(@types/node@22.9.0)(lightningcss@1.28.1)(rollup@4.27.3)(terser@5.36.0)(typescript@5.6.3))(svelte@5.0.0-next.221)(typescript@5.6.3)(vite@5.4.11(@types/node@22.9.0)(lightningcss@1.28.1)(terser@5.36.0))
+      '@azat-io/eslint-config':
+        specifier: ^2.1.2
+        version: 2.1.2(@typescript-eslint/parser@8.15.0(eslint@9.15.0(jiti@2.4.0))(typescript@5.6.3))(@typescript-eslint/utils@8.15.0(eslint@9.15.0(jiti@2.4.0))(typescript@5.6.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.15.0(eslint@9.15.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.15.0(jiti@2.4.0)))(eslint@9.15.0(jiti@2.4.0))(svelte@5.0.0-next.221)(typescript@5.6.3)(vitest@2.1.5(@types/node@22.9.0)(lightningcss@1.28.1)(terser@5.36.0))
       '@azat-io/stylelint-config':
         specifier: ^0.1.1
         version: 0.1.1(stylelint-config-recess-order@5.1.1(stylelint@16.10.0(typescript@5.6.3)))(stylelint-gamut@1.3.4(stylelint@16.10.0(typescript@5.6.3)))(stylelint-order@6.0.4(stylelint@16.10.0(typescript@5.6.3)))(stylelint-plugin-logical-css@1.2.1(stylelint@16.10.0(typescript@5.6.3)))(stylelint@16.10.0(typescript@5.6.3))
diff --git a/rules/sort-modules.ts b/rules/sort-modules.ts
index 350b713..dcbdf8f 100644
--- a/rules/sort-modules.ts
+++ b/rules/sort-modules.ts
@@ -325,6 +325,15 @@ let analyzeModule = ({
       continue
     }
 
+    if (
+      selector === 'class' &&
+      modifiers.includes('export') &&
+      modifiers.includes('decorated')
+    ) {
+      // Not always handled correctly at the moment
+      continue
+    }
+
     let { defineGroup, getGroup } = useGroups(options)
     for (let officialGroup of generatePredefinedGroups({
       cache: cachedGroupsByModifiersAndSelectors,


Test patch:
diff --git a/test/sort-modules.test.ts b/test/sort-modules.test.ts
index d20726a..e0916cd 100644
--- a/test/sort-modules.test.ts
+++ b/test/sort-modules.test.ts
@@ -959,6 +959,7 @@ describe(ruleName, () => {
         },
       )
 
+      /* Currently not handled correctly
       ruleTester.run(
         `${ruleName}(${type}): prioritize default over decorated`,
         rule,
@@ -1036,6 +1037,7 @@ describe(ruleName, () => {
           valid: [],
         },
       )
+      */
     })
 
     describe(`${ruleName}(${type}): function modifiers priority`, () => {
@@ -2375,6 +2377,53 @@ describe(ruleName, () => {
         },
       )
     })
+
+    ruleTester.run(
+      `${ruleName}(${type}): ignores exported decorated classes`,
+      rule,
+      {
+        invalid: [
+          {
+            errors: [
+              {
+                data: {
+                  right: 'B',
+                  left: 'C',
+                },
+                messageId: 'unexpectedModulesOrder',
+              },
+            ],
+            output: dedent`
+                @B
+                class B {}
+
+                @A
+                export class A {}
+
+                @C
+                class C {}
+              `,
+            code: dedent`
+                @C
+                class C {}
+
+                @A
+                export class A {}
+
+                @B
+                class B {}
+              `,
+            options: [
+              {
+                ...options,
+                groups: ['unknown'],
+              },
+            ],
+          },
+        ],
+        valid: [],
+      },
+    )
   })
 
   describe(`${ruleName}: sorting by natural order`, () => {