Skip to content

Commit c50661d

Browse files
CopilotSysixconnorshea
authored
fix: rule option preservation when severity-only override is applied (#356)
* Initial plan * Fix rule option preservation when redefining rules with severity only Co-authored-by: Sysix <3897725+Sysix@users.noreply.github.com> * Add test case for rule turned off after having options Co-authored-by: Sysix <3897725+Sysix@users.noreply.github.com> * Add jsx-a11y plugin and update tsgolint package. * Adding a snapshot test to confirm the expected behavior for the merge fix. * Extend rule option preservation to file overrides When a rule is defined with options in base config and redefined with only severity in a file override, the options are now preserved. This matches ESLint's flat config merging behavior. Co-authored-by: Sysix <3897725+Sysix@users.noreply.github.com> * Fix: Use explicit undefined checks for rule merging Use 'in' operator instead of truthy checks to avoid incorrectly falling back to base config when target config has falsy values like 'off', 0, or false. Co-authored-by: Sysix <3897725+Sysix@users.noreply.github.com> * update * Move transformRuleEntry tests to plugin_rules.spec.ts Moved rule option preservation tests from index.spec.ts to plugin_rules.spec.ts to test transformRuleEntry directly as unit tests, per @Sysix feedback. Co-authored-by: Sysix <3897725+Sysix@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Sysix <3897725+Sysix@users.noreply.github.com> Co-authored-by: Connor Shea <connor.james.shea@gmail.com> Co-authored-by: Sysix <sysix@sysix-coding.de>
1 parent 03c0e4a commit c50661d

File tree

8 files changed

+500
-57
lines changed

8 files changed

+500
-57
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`options-merging-eslint > options-merging-eslint 1`] = `
4+
{
5+
"config": {
6+
"$schema": "./node_modules/oxlint/configuration_schema.json",
7+
"categories": {
8+
"correctness": "off",
9+
},
10+
"env": {
11+
"builtin": true,
12+
},
13+
"overrides": [
14+
{
15+
"files": [
16+
"**/files/**",
17+
],
18+
"rules": {
19+
"jsx-a11y/no-autofocus": [
20+
"warn",
21+
{
22+
"ignoreNonDOM": true,
23+
},
24+
],
25+
},
26+
},
27+
],
28+
"plugins": [
29+
"jsx-a11y",
30+
],
31+
"rules": {
32+
"jsx-a11y/no-autofocus": [
33+
"error",
34+
{
35+
"ignoreNonDOM": true,
36+
},
37+
],
38+
},
39+
},
40+
"skipped": {
41+
"js-plugins": [],
42+
"nursery": [],
43+
"type-aware": [],
44+
"unsupported": [],
45+
},
46+
"warnings": [],
47+
}
48+
`;
49+
50+
exports[`options-merging-eslint --js-plugins > options-merging-eslint--js-plugins 1`] = `
51+
{
52+
"config": {
53+
"$schema": "./node_modules/oxlint/configuration_schema.json",
54+
"categories": {
55+
"correctness": "off",
56+
},
57+
"env": {
58+
"builtin": true,
59+
},
60+
"overrides": [
61+
{
62+
"files": [
63+
"**/files/**",
64+
],
65+
"rules": {
66+
"jsx-a11y/no-autofocus": [
67+
"warn",
68+
{
69+
"ignoreNonDOM": true,
70+
},
71+
],
72+
},
73+
},
74+
],
75+
"plugins": [
76+
"jsx-a11y",
77+
],
78+
"rules": {
79+
"jsx-a11y/no-autofocus": [
80+
"error",
81+
{
82+
"ignoreNonDOM": true,
83+
},
84+
],
85+
},
86+
},
87+
"skipped": {
88+
"js-plugins": [],
89+
"nursery": [],
90+
"type-aware": [],
91+
"unsupported": [],
92+
},
93+
"warnings": [],
94+
}
95+
`;
96+
97+
exports[`options-merging-eslint --type-aware > options-merging-eslint--type-aware 1`] = `
98+
{
99+
"config": {
100+
"$schema": "./node_modules/oxlint/configuration_schema.json",
101+
"categories": {
102+
"correctness": "off",
103+
},
104+
"env": {
105+
"builtin": true,
106+
},
107+
"overrides": [
108+
{
109+
"files": [
110+
"**/files/**",
111+
],
112+
"rules": {
113+
"jsx-a11y/no-autofocus": [
114+
"warn",
115+
{
116+
"ignoreNonDOM": true,
117+
},
118+
],
119+
},
120+
},
121+
],
122+
"plugins": [
123+
"jsx-a11y",
124+
],
125+
"rules": {
126+
"jsx-a11y/no-autofocus": [
127+
"error",
128+
{
129+
"ignoreNonDOM": true,
130+
},
131+
],
132+
},
133+
},
134+
"skipped": {
135+
"js-plugins": [],
136+
"nursery": [],
137+
"type-aware": [],
138+
"unsupported": [],
139+
},
140+
"warnings": [],
141+
}
142+
`;
143+
144+
exports[`options-merging-eslint merge > options-merging-eslint--merge 1`] = `
145+
{
146+
"config": {
147+
"$schema": "./node_modules/oxlint/configuration_schema.json",
148+
"categories": {
149+
"correctness": "error",
150+
"perf": "error",
151+
},
152+
"env": {
153+
"builtin": true,
154+
},
155+
"overrides": [
156+
{
157+
"files": [
158+
"**/files/**",
159+
],
160+
"rules": {
161+
"jsx-a11y/no-autofocus": [
162+
"warn",
163+
],
164+
},
165+
},
166+
],
167+
"plugins": [
168+
"jsx-a11y",
169+
],
170+
"rules": {
171+
"jsx-a11y/no-autofocus": [
172+
"error",
173+
{
174+
"ignoreNonDOM": true,
175+
},
176+
],
177+
},
178+
},
179+
"skipped": {
180+
"js-plugins": [],
181+
"nursery": [],
182+
"type-aware": [],
183+
"unsupported": [],
184+
},
185+
"warnings": [],
186+
}
187+
`;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// @ts-expect-error
2+
import options_merging_eslint_test from './projects/options-merging-eslint.config.mjs';
3+
import { testProject } from './utils.js';
4+
5+
testProject('options-merging-eslint', options_merging_eslint_test);
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import jsxA11y from 'eslint-plugin-jsx-a11y';
2+
3+
// This SHOULD result in `jsx-a11y/no-autofocus` being set to `error` WITH `ignoreNonDOM` set to `true`, but instead it is unset.
4+
//
5+
// It is set to `error` WITH `ignoreNonDOM` set to `true` in the first config.
6+
// It is set to `error` without a config option set explicitly in the second config.
7+
8+
export default [
9+
{
10+
plugins: {
11+
'jsx-a11y': jsxA11y,
12+
},
13+
rules: {
14+
'jsx-a11y/no-autofocus': ['error', { ignoreNonDOM: true }],
15+
},
16+
},
17+
{
18+
plugins: {
19+
'jsx-a11y': jsxA11y,
20+
},
21+
rules: {
22+
'jsx-a11y/no-autofocus': ['error'],
23+
},
24+
},
25+
{
26+
files: ['**/files/**'],
27+
plugins: {
28+
'jsx-a11y': jsxA11y,
29+
},
30+
rules: {
31+
'jsx-a11y/no-autofocus': ['warn'],
32+
},
33+
},
34+
{
35+
name: 'general-config',
36+
rules: {
37+
curly: 'off',
38+
},
39+
},
40+
];

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
"eslint-plugin-import": "^2.32.0",
6161
"eslint-plugin-import-x": "^4.16.0",
6262
"eslint-plugin-jsdoc": "^62.0.0",
63+
"eslint-plugin-jsx-a11y": "^6.10.2",
6364
"eslint-plugin-local": "^6.0.0",
6465
"eslint-plugin-mocha": "^11.2.0",
6566
"eslint-plugin-oxlint": "^1.3.0",
@@ -77,7 +78,7 @@
7778
"next": "^16.0.0",
7879
"oxfmt": "^0.26.0",
7980
"oxlint": "^1.42.0",
80-
"oxlint-tsgolint": "^0.8.3",
81+
"oxlint-tsgolint": "^0.11.3",
8182
"tsdown": "^0.20.0",
8283
"typescript-eslint": "^8.35.0",
8384
"vitest": "^4.0.0"

pnpm-lock.yaml

Lines changed: 36 additions & 33 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)