fix(linter): Fix default behavior of the eslint/eqeqeq rule, and also the config option docs for it#16560
Merged
camchenry merged 6 commits intohandle-tuple-rules-betterfrom Dec 10, 2025
Merged
Conversation
CodSpeed Performance ReportMerging #16560 will not alter performanceComparing Summary
Footnotes
|
ca59885 to
962bfe2
Compare
…rect config structure.
The test only worked because the fallback logic was bad previously. This config object was always wrong, and never should have worked. This is, however, technically a breaking change. If any users were reliant on the behavior of the rule defaulting to `ignore` if you gave it a bad value, this fix may break things?
2bd16cd to
2ba5292
Compare
camchenry
approved these changes
Dec 10, 2025
graphite-app bot
pushed a commit
that referenced
this pull request
Jan 22, 2026
…uple config options. (#18372) This was built out of the ashes of #16555. Implements necessary work for #16023. This introduces a new TupleRuleConfig. Rather than forcing DefaultRuleConfig to bend to our will as attempted previously, this PR adds a distinct rule config setup that is built to handle tuple-based rule configs. This PR updates 3 rules to use TupleRuleConfig: - `eslint/eqeqeq` - `eslint/sort_keys` - `eslint/yoda` It also adds snapshot validation tests to ensure that they error as-expected when given an invalid config option. The only real change here is in `eslint/eqeqeq`. We previously allowed passing _only_ an object to the rule config (due to #8790), but that is not valid in the original rule, and also makes implementing proper config option validation quite a bit more difficult. I had removed support for this in #16560, but that was part of the previous, doomed attempt at using DefaultRuleConfig with tuples. So it never got merged, and I'm redoing it here. This is a necessary part of the change for this PR, as the alternative is to make the config options parsing/validation implementation _considerably_ more complex. This also brings us back in line with ESLint's behavior for this rule. --- AI Disclosure: I used the code and tests from #16555 as the basis for the changes in `rule.rs`, then let Claude Opus 4.5 run with it and guided it toward the TupleRuleConfig concept. After I got a satisfactory TupleRuleConfig implementation, I then manually implemented the rest of the changes in this PR by copying the files over from #16555, applying the TupleRuleConfig rename, and then carefully going through the diffs to make sure nothing was deleted that shouldn't have been. I have added tests to ensure that the config validation for tuple rules works, and have entirely avoided changing the unit tests in any of the 3 modified rules (other than the one change for eqeqeq I noted above). --- <details> <summary>Updated docs for the changed rules</summary> Note that the sort-keys docs are entirely unchanged as they were correct prior to this, so I've excluded them. yoda: ```md ## Configuration ### The 1st option type: `"never" | "always"` #### `"never"` The default `"never"` option can have exception options in an object literal, via `exceptRange` and `onlyEquality`. #### `"always"` The `"always"` option requires that literal values must always come first in comparisons. ### The 2nd option This option is an object with the following properties: #### exceptRange type: `boolean` default: `false` If the `"exceptRange"` property is `true`, the rule _allows_ yoda conditions in range comparisons which are wrapped directly in parentheses, including the parentheses of an `if` or `while` condition. A _range_ comparison tests whether a variable is inside or outside the range between two literal values. #### onlyEquality type: `boolean` default: `false` If the `"onlyEquality"` property is `true`, the rule reports yoda conditions _only_ for the equality operators `==` and `===`. The `onlyEquality` option allows a superset of the exceptions which `exceptRange` allows, thus both options are not useful together. ``` eqeqeq: ```md ## Configuration ### The 1st option type: `"always" | "smart"` #### `"always"` Always require triple-equal comparisons, `===`/`!==`. This is the default. #### `"smart"` Allow certain safe comparisons to use `==`/`!=` (`typeof`, literals, nullish). ### The 2nd option This option is an object with the following properties: #### null type: `"always" | "never" | "ignore"` ##### `"always"` Always require triple-equals when comparing with null, `=== null`/`!== null`. This is the default. ##### `"never"` Never require triple-equals when comparing with null, always use `== null`/`!= null`. ##### `"ignore"` Ignore null comparisons, allow either `== null`/`!= null` or `=== null`/`!== null`. ``` </details>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is part of #16023.
See the tests for the original rule.
We have a test in the eqeqeq.rs implementation like so:
The problem is that this test has an incorrect shape for the config object, see here:
The problem is that the code did previously handle this config array as invalid. However, because the implementation of
fromon NullType would fall back toignoreif it received bad data, it looked like it worked:Because
alwaysis marked as the default value (and is also the default value in the original ESLint rule), and so should be the default case. The test was just hitting the fallback value, so it looked like it worked, but really the fallback value was incorrect previously and did not match the docs or the ESLint behavior.This fixes that issue by correcting the fallback value, and also fixes the auto-generated config shape/docs, so it correctly represents itself as taking a tuple.
Generated docs: