Skip to content

Commit f9aa163

Browse files
authored
refactor: improve error messages (#937)
1 parent d10f63b commit f9aa163

File tree

8 files changed

+357
-127
lines changed

8 files changed

+357
-127
lines changed

packages/plugins/eslint-plugin-react-naming-convention/src/rules/filename.spec.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ ruleTester.run(RULE_NAME, rule, {
99
code,
1010
errors: [
1111
{
12-
messageId: "filenameCaseMismatchSuggestion",
12+
messageId: "filenameCaseMismatch",
1313
data: {
1414
name: "PascalCase.tsx",
1515
rule: "kebab-case",
@@ -24,7 +24,7 @@ ruleTester.run(RULE_NAME, rule, {
2424
code,
2525
errors: [
2626
{
27-
messageId: "filenameCaseMismatchSuggestion",
27+
messageId: "filenameCaseMismatch",
2828
data: {
2929
name: "camelCase.tsx",
3030
rule: "PascalCase",
@@ -39,7 +39,7 @@ ruleTester.run(RULE_NAME, rule, {
3939
code,
4040
errors: [
4141
{
42-
messageId: "filenameCaseMismatchSuggestion",
42+
messageId: "filenameCaseMismatch",
4343
data: {
4444
name: "kebab-case.tsx",
4545
rule: "PascalCase",
@@ -54,7 +54,7 @@ ruleTester.run(RULE_NAME, rule, {
5454
code,
5555
errors: [
5656
{
57-
messageId: "filenameCaseMismatchSuggestion",
57+
messageId: "filenameCaseMismatch",
5858
data: {
5959
name: "snake_case.tsx",
6060
rule: "PascalCase",
@@ -69,7 +69,7 @@ ruleTester.run(RULE_NAME, rule, {
6969
code,
7070
errors: [
7171
{
72-
messageId: "filenameCaseMismatchSuggestion",
72+
messageId: "filenameCaseMismatch",
7373
data: {
7474
name: "PascalCase.tsx",
7575
rule: "camelCase",
@@ -84,7 +84,7 @@ ruleTester.run(RULE_NAME, rule, {
8484
code,
8585
errors: [
8686
{
87-
messageId: "filenameCaseMismatchSuggestion",
87+
messageId: "filenameCaseMismatch",
8888
data: {
8989
name: "kebab-case.tsx",
9090
rule: "camelCase",
@@ -99,7 +99,7 @@ ruleTester.run(RULE_NAME, rule, {
9999
code,
100100
errors: [
101101
{
102-
messageId: "filenameCaseMismatchSuggestion",
102+
messageId: "filenameCaseMismatch",
103103
data: {
104104
name: "snake_case.tsx",
105105
rule: "camelCase",

packages/plugins/eslint-plugin-react-naming-convention/src/rules/filename.ts

+3-6
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ export const RULE_FEATURES = [
1616
] as const satisfies RuleFeature[];
1717

1818
export type MessageID =
19-
// | "filenameCaseMismatch"
20-
| "filenameCaseMismatchSuggestion"
19+
| "filenameCaseMismatch"
2120
| "filenameEmpty";
2221

2322
type Case = "camelCase" | "kebab-case" | "PascalCase" | "snake_case";
@@ -86,9 +85,7 @@ export default createRule<Options, MessageID>({
8685
description: "enforce naming convention for JSX filenames",
8786
},
8887
messages: {
89-
// filenameCaseMismatch: "A file with name '{{name}}' does not match {{rule}}.",
90-
filenameCaseMismatchSuggestion:
91-
"A file with name '{{name}}' does not match {{rule}}. Should rename to '{{suggestion}}'.",
88+
filenameCaseMismatch: "A file with name '{{name}}' does not match {{rule}}. Should rename to '{{suggestion}}'.",
9289
filenameEmpty: "A file must have non-empty name.",
9390
},
9491
schema,
@@ -138,7 +135,7 @@ export default createRule<Options, MessageID>({
138135
return;
139136
}
140137
context.report({
141-
messageId: "filenameCaseMismatchSuggestion",
138+
messageId: "filenameCaseMismatch",
142139
node,
143140
data: {
144141
name: context.filename,

packages/plugins/eslint-plugin-react-x/src/rules/no-missing-key.spec.ts

+28-28
Original file line numberDiff line numberDiff line change
@@ -5,73 +5,73 @@ ruleTester.run(RULE_NAME, rule, {
55
invalid: [
66
{
77
code: /* tsx */ `[<App />];`,
8-
errors: [{ messageId: "noMissingKey" }],
8+
errors: [{ messageId: "missingKey" }],
99
},
1010
{
1111
code: /* tsx */ `[<App {...key} />];`,
12-
errors: [{ messageId: "noMissingKey" }],
12+
errors: [{ messageId: "missingKey" }],
1313
},
1414
{
1515
code: /* tsx */ `[<App key={0}/>, <App />];`,
16-
errors: [{ messageId: "noMissingKey" }],
16+
errors: [{ messageId: "missingKey" }],
1717
},
1818
{
1919
code: /* tsx */ `[1, 2 ,3].map(function(x) { return <App /> });`,
20-
errors: [{ messageId: "noMissingKey" }],
20+
errors: [{ messageId: "missingKey" }],
2121
},
2222
{
2323
code: /* tsx */ `[1, 2 ,3].map(x => <App />);`,
24-
errors: [{ messageId: "noMissingKey" }],
24+
errors: [{ messageId: "missingKey" }],
2525
},
2626
{
2727
code: /* tsx */ `[1, 2 ,3].map(x => x && <App x={x} />);`,
28-
errors: [{ messageId: "noMissingKey" }],
28+
errors: [{ messageId: "missingKey" }],
2929
},
3030
{
3131
code: '[1, 2 ,3].map(x => x ? <App x={x} key="1" /> : <OtherApp x={x} />);',
32-
errors: [{ messageId: "noMissingKey" }],
32+
errors: [{ messageId: "missingKey" }],
3333
},
3434
{
3535
code: '[1, 2 ,3].map(x => x ? <App x={x} /> : <OtherApp x={x} key="2" />);',
36-
errors: [{ messageId: "noMissingKey" }],
36+
errors: [{ messageId: "missingKey" }],
3737
},
3838
{
3939
code: /* tsx */ `[1, 2 ,3].map(x => { return <App /> });`,
40-
errors: [{ messageId: "noMissingKey" }],
40+
errors: [{ messageId: "missingKey" }],
4141
},
4242
{
4343
code: /* tsx */ `Array.from([1, 2 ,3], function(x) { return <App /> });`,
44-
errors: [{ messageId: "noMissingKey" }],
44+
errors: [{ messageId: "missingKey" }],
4545
},
4646
{
4747
code: /* tsx */ `Array.from([1, 2 ,3], (x => { return <App /> }));`,
48-
errors: [{ messageId: "noMissingKey" }],
48+
errors: [{ messageId: "missingKey" }],
4949
},
5050
{
5151
code: /* tsx */ `Array.from([1, 2 ,3], (x => <App />));`,
52-
errors: [{ messageId: "noMissingKey" }],
52+
errors: [{ messageId: "missingKey" }],
5353
},
5454
{
5555
code: /* tsx */ `[1, 2, 3]?.map(x => <BabelEslintApp />)`,
56-
errors: [{ messageId: "noMissingKey" }],
56+
errors: [{ messageId: "missingKey" }],
5757
},
5858
{
5959
code: /* tsx */ `[1, 2, 3]?.map(x => <TypescriptEslintApp />)`,
60-
errors: [{ messageId: "noMissingKey" }],
60+
errors: [{ messageId: "missingKey" }],
6161
},
6262
{
6363
code: /* tsx */ `[1, 2, 3].map(x => <>{x}</>);`,
6464
errors: [
6565
{
66-
messageId: "noMissingKeyWithFragment",
66+
messageId: "unexpectedFragmentSyntax",
6767
},
6868
],
6969
},
7070
{
7171
code: /* tsx */ `[<></>];`,
7272
errors: [
7373
{
74-
messageId: "noMissingKeyWithFragment",
74+
messageId: "unexpectedFragmentSyntax",
7575
},
7676
],
7777
},
@@ -94,8 +94,8 @@ ruleTester.run(RULE_NAME, rule, {
9494
};
9595
`,
9696
errors: [
97-
{ messageId: "noMissingKey" },
98-
{ messageId: "noMissingKey" },
97+
{ messageId: "missingKey" },
98+
{ messageId: "missingKey" },
9999
],
100100
},
101101
{
@@ -121,10 +121,10 @@ ruleTester.run(RULE_NAME, rule, {
121121
};
122122
`,
123123
errors: [
124-
{ messageId: "noMissingKey" },
125-
{ messageId: "noMissingKey" },
126-
{ messageId: "noMissingKey" },
127-
{ messageId: "noMissingKey" },
124+
{ messageId: "missingKey" },
125+
{ messageId: "missingKey" },
126+
{ messageId: "missingKey" },
127+
{ messageId: "missingKey" },
128128
],
129129
},
130130
{
@@ -144,9 +144,9 @@ ruleTester.run(RULE_NAME, rule, {
144144
};
145145
`,
146146
errors: [
147-
{ messageId: "noMissingKey" },
148-
{ messageId: "noMissingKey" },
149-
{ messageId: "noMissingKey" },
147+
{ messageId: "missingKey" },
148+
{ messageId: "missingKey" },
149+
{ messageId: "missingKey" },
150150
],
151151
},
152152
{
@@ -176,13 +176,13 @@ ruleTester.run(RULE_NAME, rule, {
176176
`,
177177
errors: [
178178
{
179-
messageId: "noMissingKeyWithFragment",
179+
messageId: "unexpectedFragmentSyntax",
180180
},
181181
{
182-
messageId: "noMissingKey",
182+
messageId: "missingKey",
183183
},
184184
{
185-
messageId: "noMissingKeyWithFragment",
185+
messageId: "unexpectedFragmentSyntax",
186186
},
187187
],
188188
},

packages/plugins/eslint-plugin-react-x/src/rules/no-missing-key.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ export const RULE_FEATURES = [
1515
] as const satisfies RuleFeature[];
1616

1717
export type MessageID =
18-
| "noMissingKey"
19-
| "noMissingKeyWithFragment";
18+
| "missingKey"
19+
| "unexpectedFragmentSyntax";
2020

2121
export default createRule<[], MessageID>({
2222
meta: {
@@ -26,8 +26,8 @@ export default createRule<[], MessageID>({
2626
[Symbol.for("rule_features")]: RULE_FEATURES,
2727
},
2828
messages: {
29-
noMissingKey: "Missing 'key' for element when rendering list.",
30-
noMissingKeyWithFragment: "Use fragment component instead of '<>' because it does not support `key`.",
29+
missingKey: "Missing 'key' for element when rendering list.",
30+
unexpectedFragmentSyntax: "Use fragment component instead of '<>' because it does not support `key`.",
3131
},
3232
schema: [],
3333
},
@@ -40,15 +40,15 @@ export default createRule<[], MessageID>({
4040
const initialScope = context.sourceCode.getScope(node);
4141
if (!JSX.hasAttribute("key", node.openingElement.attributes, initialScope)) {
4242
return {
43-
messageId: "noMissingKey",
43+
messageId: "missingKey",
4444
node,
4545
} as const;
4646
}
4747
return null;
4848
}
4949
case T.JSXFragment: {
5050
return {
51-
messageId: "noMissingKeyWithFragment",
51+
messageId: "unexpectedFragmentSyntax",
5252
node,
5353
} as const;
5454
}
@@ -104,7 +104,7 @@ export default createRule<[], MessageID>({
104104
for (const element of elements) {
105105
if (!JSX.hasAttribute("key", element.openingElement.attributes, initialScope)) {
106106
context.report({
107-
messageId: "noMissingKey",
107+
messageId: "missingKey",
108108
node: element,
109109
});
110110
}
@@ -146,7 +146,7 @@ export default createRule<[], MessageID>({
146146
}
147147
if (node.parent.type === T.ArrayExpression) {
148148
context.report({
149-
messageId: "noMissingKeyWithFragment",
149+
messageId: "unexpectedFragmentSyntax",
150150
node,
151151
});
152152
}

packages/plugins/eslint-plugin-react-x/src/rules/no-unstable-context-value.spec.ts

+27-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ ruleTester.run(RULE_NAME, rule, {
1010
return <Context.Provider value={foo}></Context.Provider>;
1111
}
1212
`,
13-
errors: [{ messageId: "noUnstableContextValueWithIdentifier" }],
13+
errors: [{
14+
messageId: "unstableContextValue",
15+
data: {
16+
type: "object expression",
17+
suggestion: "Consider wrapping it in a useMemo hook.",
18+
},
19+
}],
1420
},
1521
{
1622
code: /* tsx */ `
@@ -21,7 +27,11 @@ ruleTester.run(RULE_NAME, rule, {
2127
`,
2228
errors: [
2329
{
24-
messageId: "noUnstableContextValueWithIdentifier",
30+
messageId: "unstableContextValue",
31+
data: {
32+
type: "array expression",
33+
suggestion: "Consider wrapping it in a useMemo hook.",
34+
},
2535
},
2636
],
2737
},
@@ -34,7 +44,11 @@ ruleTester.run(RULE_NAME, rule, {
3444
`,
3545
errors: [
3646
{
37-
messageId: "noUnstableContextValueWithIdentifier",
47+
messageId: "unstableContextValue",
48+
data: {
49+
type: "new expression",
50+
suggestion: "Consider wrapping it in a useMemo hook.",
51+
},
3852
},
3953
],
4054
},
@@ -47,7 +61,11 @@ ruleTester.run(RULE_NAME, rule, {
4761
`,
4862
errors: [
4963
{
50-
messageId: "noUnstableContextValueWithFunction",
64+
messageId: "unstableContextValue",
65+
data: {
66+
type: "arrow function expression",
67+
suggestion: "Consider wrapping it in a useCallback hook.",
68+
},
5169
},
5270
],
5371
},
@@ -62,7 +80,11 @@ ruleTester.run(RULE_NAME, rule, {
6280
`,
6381
errors: [
6482
{
65-
messageId: "noUnstableContextValueWithIdentifier",
83+
messageId: "unstableContextValue",
84+
data: {
85+
type: "object expression",
86+
suggestion: "Consider wrapping it in a useMemo hook.",
87+
},
6688
},
6789
],
6890
},

0 commit comments

Comments
 (0)