-
Notifications
You must be signed in to change notification settings - Fork 457
prefer-number-isnan: treat ESM import bindings as local shadows #43500
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d5c8615
69d37b5
1e59acd
7857489
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,9 +34,13 @@ describe("prefer-number-isnan", () => { | |
| valid: [ | ||
| `function isNaN(value) { return false; } isNaN(value);`, | ||
| `const isNaN = Number.isNaN; isNaN(value);`, | ||
| `import { isNaN } from "lodash"; isNaN(value);`, | ||
| `const globalThis = { isNaN(value) { return value; } }; globalThis.isNaN(value);`, | ||
| `const window = { isNaN(value) { return value; } }; window["isNaN"](value);`, | ||
| `const global = { isNaN(value) { return value; } }; global.isNaN(value);`, | ||
| `import { globalThis } from "./global-shim"; globalThis.isNaN(value);`, | ||
| `import { window } from "./browser-shim"; window.isNaN(value);`, | ||
| `import { global } from "./server-shim"; global["isNaN"](value);`, | ||
| // Dynamic computed access — identifier property reference, not string literal "isNaN" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Incomplete test symmetry: 💡 Suggested additionThe three new valid ESM tests cover Consider adding: `import { globalThis } from "./global-shim"; globalThis.isNaN(value);`,Low risk by itself, but the gap creates a mental model mismatch between the rule's constant and the test suite. |
||
| `globalThis[isNaN](value);`, | ||
| ], | ||
|
|
@@ -99,4 +103,20 @@ describe("prefer-number-isnan", () => { | |
| ], | ||
| }); | ||
| }); | ||
|
|
||
| it("invalid: global isNaN() is still flagged in ESM mode without a shadow", () => { | ||
| esmRuleTester.run("prefer-number-isnan", preferNumberIsNanRule, { | ||
| valid: [], | ||
| invalid: [ | ||
| { | ||
| code: `isNaN(value);`, | ||
| errors: [{ messageId: "preferNumberIsNaN", suggestions: [{ messageId: "replaceWithNumberIsNaN", output: `Number.isNaN(value);` }] }], | ||
| }, | ||
| { | ||
| code: `window.isNaN(value);`, | ||
| errors: [{ messageId: "preferNumberIsNaN", suggestions: [{ messageId: "replaceWithNumberIsNaN", output: `Number.isNaN(value);` }] }], | ||
| }, | ||
| ], | ||
| }); | ||
| }); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing ESM invalid test: no test proves the rule still flags
isNaN()in ESM modules after this change, leaving a correctness regression undetectable.💡 Explanation and suggested fix
All
invalid:test cases usecjsRuleTester. The fix changes scope-walking behavior, which is determined persourceType. If the newvariable && variable.defs.length > 0branch misbehaves in ESM mode (e.g., due to how eslint scope analysis treats globals undersourceType: "module"), no test would catch it.Consider adding to the new
esmRuleTester.runblock:Without this, the PR's test coverage only validates the non-regression path (valid cases), not that the rule still fires in ESM when no import shadowing is present.