Repository: azat-io/eslint-plugin-perfectionist
Pull request #484 (2025-03-09 14:40:20)

fix: fix false positive eslint-disable errors raised
- Issue: https://github.com/azat-io/eslint-plugin-perfectionist/issues/483 (one of the two bugs of that issue)

### Description

Some `eslint-disable` errors are raised when they should not in specific situations due to a missing condition.

### Bug severity

Low:
- Not related to a new feature.
- Only happens in specific situations.
- Can be bypassed by moving elements around in the worst case.

### Code example

```ts
interface Test {
  b: string;
  c: string;
  // eslint-disable-next-line
  a: string;
}
```

This currently raises an unfixable error.

### What is the purpose of this pull request?

- [x] Bug fix


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/azat-io/eslint-plugin-perfectionist/pull/484?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Azat+S.) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 100.00%. Comparing base [(`8d4ad4f`)](https://app.codecov.io/gh/azat-io/eslint-plugin-perfectionist/commit/8d4ad4f9e492c5db08524bd7657371671e439e9e?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Azat+S.) to head [(`40e8df3`)](https://app.codecov.io/gh/azat-io/eslint-plugin-perfectionist/commit/40e8df3c6a18dbb2c9308867a40876815916ba04?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Azat+S.).

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff            @@
##              main      #484   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           94        94           
  Lines         7617      7618    +1     
  Branches      1632      1633    +1     
=========================================
+ Hits          7617      7618    +1     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/azat-io/eslint-plugin-perfectionist/pull/484?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Azat+S.).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Azat+S.).

<details><summary>🚀 New features to boost your workflow: </summary>

- ❄ [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- 📦 [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>

Patch:
diff --git a/utils/compare.ts b/utils/compare.ts
index 1f47091..9a2d76a 100644
--- a/utils/compare.ts
+++ b/utils/compare.ts
@@ -50,9 +50,6 @@ export let compare = <T extends SortingNode>({
   return computeCompareValue({
     options: {
       ...options,
-      fallbackSort: {
-        type: 'unsorted',
-      },
       order: fallbackSort.order ?? order,
       type: fallbackSort.type,
     },
diff --git a/utils/report-all-errors.ts b/utils/report-all-errors.ts
index 239182f..a7e86e6 100644
--- a/utils/report-all-errors.ts
+++ b/utils/report-all-errors.ts
@@ -76,7 +76,8 @@ export let reportAllErrors = <
     if (
       firstUnorderedNodeDependentOnRight ||
       leftIndex > rightIndex ||
-      leftIndex >= indexOfRightExcludingEslintDisabled
+      (left.isEslintDisabled &&
+        leftIndex >= indexOfRightExcludingEslintDisabled)
     ) {
       if (firstUnorderedNodeDependentOnRight) {
         messageIds.push(availableMessageIds.unexpectedDependencyOrder!)


Test patch:
diff --git a/test/rules/sort-array-includes.test.ts b/test/rules/sort-array-includes.test.ts
index a72cd56..5942f1d 100644
--- a/test/rules/sort-array-includes.test.ts
+++ b/test/rules/sort-array-includes.test.ts
@@ -3221,7 +3221,18 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            [
+              'b',
+              'c',
+              // eslint-disable-next-line
+              'a',
+            ].includes(value)
+          `,
+        },
+      ],
     })
 
     eslintRuleTester.run(
diff --git a/test/rules/sort-classes.test.ts b/test/rules/sort-classes.test.ts
index 7c9ea52..143d2d5 100644
--- a/test/rules/sort-classes.test.ts
+++ b/test/rules/sort-classes.test.ts
@@ -9850,7 +9850,18 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            class Class {
+              b
+              c
+              // eslint-disable-next-line
+              a
+            }
+          `,
+        },
+      ],
     })
 
     eslintRuleTester.run(
diff --git a/test/rules/sort-decorators.test.ts b/test/rules/sort-decorators.test.ts
index f7bd254..6113e03 100644
--- a/test/rules/sort-decorators.test.ts
+++ b/test/rules/sort-decorators.test.ts
@@ -5066,7 +5066,41 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            @B
+            @C
+            // eslint-disable-next-line
+            @A
+            class Class {
+
+              @B
+              @C
+              // eslint-disable-next-line
+              @A
+              property
+
+              @B
+              @C
+              // eslint-disable-next-line
+              @A
+              accessor field
+
+              @B
+              @C
+              // eslint-disable-next-line
+              @A
+              method(
+                @B
+                @C
+                // eslint-disable-next-line
+                @A
+                parameter) {}
+            }
+          `,
+        },
+      ],
     })
 
     eslintRuleTester.run(
diff --git a/test/rules/sort-enums.test.ts b/test/rules/sort-enums.test.ts
index dfed469..d622cb0 100644
--- a/test/rules/sort-enums.test.ts
+++ b/test/rules/sort-enums.test.ts
@@ -4074,7 +4074,18 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            enum Enum {
+              B = 'B',
+              C = 'C',
+              // eslint-disable-next-line
+              A = 'A',
+            }
+          `,
+        },
+      ],
     })
   })
 })
diff --git a/test/rules/sort-exports.test.ts b/test/rules/sort-exports.test.ts
index 97c2a39..c723dae 100644
--- a/test/rules/sort-exports.test.ts
+++ b/test/rules/sort-exports.test.ts
@@ -1762,7 +1762,16 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            export { b } from "./b"
+            export { c } from "./c"
+            // eslint-disable-next-line
+            export { a } from "./a"
+          `,
+        },
+      ],
     })
 
     eslintRuleTester.run(
diff --git a/test/rules/sort-heritage-clauses.test.ts b/test/rules/sort-heritage-clauses.test.ts
index 5a69b26..3309a35 100644
--- a/test/rules/sort-heritage-clauses.test.ts
+++ b/test/rules/sort-heritage-clauses.test.ts
@@ -1917,7 +1917,18 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            class Class implements
+              B,
+              C,
+              // eslint-disable-next-line
+              A
+            {}
+          `,
+        },
+      ],
     })
 
     eslintRuleTester.run(
diff --git a/test/rules/sort-imports.test.ts b/test/rules/sort-imports.test.ts
index baa2758..a2731ff 100644
--- a/test/rules/sort-imports.test.ts
+++ b/test/rules/sort-imports.test.ts
@@ -7184,7 +7184,16 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            import { b } from "./b"
+            import { c } from "./c"
+            // eslint-disable-next-line
+            import { a } from "./a"
+          `,
+        },
+      ],
     })
 
     eslintRuleTester.run(
diff --git a/test/rules/sort-interfaces.test.ts b/test/rules/sort-interfaces.test.ts
index 4ec0c38..8f8811c 100644
--- a/test/rules/sort-interfaces.test.ts
+++ b/test/rules/sort-interfaces.test.ts
@@ -5687,7 +5687,18 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            interface Interface {
+              b: string;
+              c: string;
+              // eslint-disable-next-line
+              a: string;
+            }
+          `,
+        },
+      ],
     })
   })
 })
diff --git a/test/rules/sort-intersection-types.test.ts b/test/rules/sort-intersection-types.test.ts
index f1504af..51540b0 100644
--- a/test/rules/sort-intersection-types.test.ts
+++ b/test/rules/sort-intersection-types.test.ts
@@ -2780,7 +2780,17 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            type Type =
+              & B
+              & C
+              // eslint-disable-next-line
+              & A
+          `,
+        },
+      ],
     })
   })
 })
diff --git a/test/rules/sort-jsx-props.test.ts b/test/rules/sort-jsx-props.test.ts
index f8ac3ed..a970659 100644
--- a/test/rules/sort-jsx-props.test.ts
+++ b/test/rules/sort-jsx-props.test.ts
@@ -2810,7 +2810,18 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            <Element
+              b="b"
+              c="c"
+              // eslint-disable-next-line
+              a="a"
+            />
+          `,
+        },
+      ],
     })
   })
 })
diff --git a/test/rules/sort-maps.test.ts b/test/rules/sort-maps.test.ts
index 71b4492..5159ba8 100644
--- a/test/rules/sort-maps.test.ts
+++ b/test/rules/sort-maps.test.ts
@@ -2851,7 +2851,18 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            new Map([
+              [b, 'b'],
+              [c, 'c'],
+              // eslint-disable-next-line
+              [a, 'a'],
+            ])
+          `,
+        },
+      ],
     })
 
     eslintRuleTester.run(
diff --git a/test/rules/sort-modules.test.ts b/test/rules/sort-modules.test.ts
index 5f75539..092e753 100644
--- a/test/rules/sort-modules.test.ts
+++ b/test/rules/sort-modules.test.ts
@@ -4350,7 +4350,16 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            function b() {}
+            function c() {}
+            // eslint-disable-next-line
+            function a() {}
+          `,
+        },
+      ],
     })
 
     eslintRuleTester.run(
diff --git a/test/rules/sort-named-exports.test.ts b/test/rules/sort-named-exports.test.ts
index f548d28..87ff591 100644
--- a/test/rules/sort-named-exports.test.ts
+++ b/test/rules/sort-named-exports.test.ts
@@ -1647,7 +1647,18 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            export {
+              b,
+              c,
+              // eslint-disable-next-line
+              a
+            }
+          `,
+        },
+      ],
     })
 
     eslintRuleTester.run(
diff --git a/test/rules/sort-named-imports.test.ts b/test/rules/sort-named-imports.test.ts
index 2726d7b..9518bd1 100644
--- a/test/rules/sort-named-imports.test.ts
+++ b/test/rules/sort-named-imports.test.ts
@@ -2191,7 +2191,18 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            import {
+              b,
+              c,
+              // eslint-disable-next-line
+              a
+            } from 'module'
+          `,
+        },
+      ],
     })
 
     eslintRuleTester.run(
diff --git a/test/rules/sort-object-types.test.ts b/test/rules/sort-object-types.test.ts
index 3b15323..5afef70 100644
--- a/test/rules/sort-object-types.test.ts
+++ b/test/rules/sort-object-types.test.ts
@@ -4993,7 +4993,18 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            type Type = {
+              b: string;
+              c: string;
+              // eslint-disable-next-line
+              a: string;
+            }
+          `,
+        },
+      ],
     })
   })
 })
diff --git a/test/rules/sort-objects.test.ts b/test/rules/sort-objects.test.ts
index bc4339a..e4dd196 100644
--- a/test/rules/sort-objects.test.ts
+++ b/test/rules/sort-objects.test.ts
@@ -6531,7 +6531,18 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            let obj = {
+              b = 'b',
+              c = 'c',
+              // eslint-disable-next-line
+              a = 'a',
+            }
+          `,
+        },
+      ],
     })
 
     eslintRuleTester.run(
diff --git a/test/rules/sort-sets.test.ts b/test/rules/sort-sets.test.ts
index 3edb10c..5dfd768 100644
--- a/test/rules/sort-sets.test.ts
+++ b/test/rules/sort-sets.test.ts
@@ -3168,7 +3168,18 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            new Set([
+              'b',
+              'c',
+              // eslint-disable-next-line
+              'a',
+            ])
+          `,
+        },
+      ],
     })
 
     eslintRuleTester.run(
diff --git a/test/rules/sort-union-types.test.ts b/test/rules/sort-union-types.test.ts
index e13d4b6..ae9bc0b 100644
--- a/test/rules/sort-union-types.test.ts
+++ b/test/rules/sort-union-types.test.ts
@@ -2812,7 +2812,17 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            type Type =
+              | B
+              | C
+              // eslint-disable-next-line
+              | A
+          `,
+        },
+      ],
     })
   })
 })
diff --git a/test/rules/sort-variable-declarations.test.ts b/test/rules/sort-variable-declarations.test.ts
index 495f8ff..789eec6 100644
--- a/test/rules/sort-variable-declarations.test.ts
+++ b/test/rules/sort-variable-declarations.test.ts
@@ -2106,7 +2106,17 @@ describe(ruleName, () => {
           options: [{}],
         },
       ],
-      valid: [],
+      valid: [
+        {
+          code: dedent`
+            let
+              b,
+              c,
+              // eslint-disable-next-line
+              a
+          `,
+        },
+      ],
     })
 
     eslintRuleTester.run(