Skip to content

Commit a0a39c6

Browse files
authored
Update: Add autofixer to require-meta-has-suggestions rule (#168)
If suggestions are detected, add `hasSuggestions: true`.
1 parent 639da89 commit a0a39c6

File tree

4 files changed

+98
-4
lines changed

4 files changed

+98
-4
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Name | ✔️ | 🛠 | 💡 | Description
6565
[require-meta-docs-description](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/require-meta-docs-description.md) | | | | require rules to implement a `meta.docs.description` property with the correct format
6666
[require-meta-docs-url](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/require-meta-docs-url.md) | | 🛠 | | require rules to implement a `meta.docs.url` property
6767
[require-meta-fixable](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/require-meta-fixable.md) | ✔️ | | | require rules to implement a `meta.fixable` property
68-
[require-meta-has-suggestions](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/require-meta-has-suggestions.md) | | | | require suggestable rules to implement a `meta.hasSuggestions` property
68+
[require-meta-has-suggestions](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/require-meta-has-suggestions.md) | | 🛠 | | require suggestable rules to implement a `meta.hasSuggestions` property
6969
[require-meta-schema](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/require-meta-schema.md) | | 🛠 | | require rules to implement a `meta.schema` property
7070
[require-meta-type](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/require-meta-type.md) | | | | require rules to implement a `meta.type` property
7171
[test-case-property-ordering](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/test-case-property-ordering.md) | | 🛠 | | require the properties of a test case to be placed in a consistent order

docs/rules/require-meta-has-suggestions.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Require suggestable rules to implement a `meta.hasSuggestions` property (require-meta-has-suggestions)
22

3+
⚒️ The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#--fix) can automatically fix some of the problems reported by this rule.
4+
35
A suggestable ESLint rule should specify the `meta.hasSuggestions` property with a value of `true`. This makes it easier for both humans and tooling to tell whether a rule provides suggestions. [As of ESLint 8](https://eslint.org/blog/2021/06/whats-coming-in-eslint-8.0.0#rules-with-suggestions-now-require-the-metahassuggestions-property), an exception will be thrown if a suggestable rule is missing this property.
46

57
Likewise, rules that do not report suggestions should not enable the `meta.hasSuggestions` property.

lib/rules/require-meta-has-suggestions.js

+24-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ module.exports = {
1515
category: 'Rules',
1616
recommended: false,
1717
},
18+
fixable: 'code',
1819
schema: [],
1920
messages: {
2021
shouldBeSuggestable: 'Suggestable rules should specify a `meta.hasSuggestions` property with value `true`.',
@@ -64,10 +65,31 @@ module.exports = {
6465
if (ruleReportsSuggestions) {
6566
if (!hasSuggestionsProperty) {
6667
// Rule reports suggestions but is missing the `meta.hasSuggestions` property altogether.
67-
context.report({ node: metaNode ? metaNode : ruleInfo.create, messageId: 'shouldBeSuggestable' });
68+
context.report({
69+
node: metaNode ? metaNode : ruleInfo.create,
70+
messageId: 'shouldBeSuggestable',
71+
fix (fixer) {
72+
if (metaNode && metaNode.type === 'ObjectExpression') {
73+
if (metaNode.properties.length === 0) {
74+
// If object is empty, just replace entire object.
75+
return fixer.replaceText(metaNode, '{ hasSuggestions: true }');
76+
}
77+
// Add new property to start of property list.
78+
return fixer.insertTextBefore(metaNode.properties[0], 'hasSuggestions: true, ');
79+
}
80+
},
81+
});
6882
} else if (hasSuggestionsStaticValue && hasSuggestionsStaticValue.value !== true) {
6983
// Rule reports suggestions but does not have `meta.hasSuggestions` property enabled.
70-
context.report({ node: hasSuggestionsProperty.value, messageId: 'shouldBeSuggestable' });
84+
context.report({
85+
node: hasSuggestionsProperty.value,
86+
messageId: 'shouldBeSuggestable',
87+
fix (fixer) {
88+
if (hasSuggestionsProperty.value.type === 'Literal' || (hasSuggestionsProperty.value.type === 'Identifier' && hasSuggestionsProperty.value.name === 'undefined')) {
89+
return fixer.replaceText(hasSuggestionsProperty.value, 'true');
90+
}
91+
},
92+
});
7193
}
7294
} else if (!ruleReportsSuggestions && hasSuggestionsProperty && hasSuggestionsStaticValue && hasSuggestionsStaticValue.value === true) {
7395
// Rule does not report suggestions but has the `meta.hasSuggestions` property enabled.

tests/lib/rules/require-meta-has-suggestions.js

+71-1
Original file line numberDiff line numberDiff line change
@@ -164,18 +164,41 @@ ruleTester.run('require-meta-has-suggestions', rule, {
164164
create(context) { context.report({node, message, suggest: [{}]}); }
165165
};
166166
`,
167+
output: null,
167168
errors: [{ messageId: 'shouldBeSuggestable', type: 'FunctionExpression', line: 3, column: 17, endLine: 3, endColumn: 78 }],
168169
},
169170
{
170-
// Reports suggestions, no hasSuggestions property, violation should be on `meta` object.
171+
// Reports suggestions, no hasSuggestions property, violation should be on `meta` object, empty meta object.
171172
code: `
172173
module.exports = {
173174
meta: {},
174175
create(context) { context.report({node, message, suggest: [{}]}); }
175176
};
176177
`,
178+
output: `
179+
module.exports = {
180+
meta: { hasSuggestions: true },
181+
create(context) { context.report({node, message, suggest: [{}]}); }
182+
};
183+
`,
177184
errors: [{ messageId: 'shouldBeSuggestable', type: 'ObjectExpression', line: 3, column: 17, endLine: 3, endColumn: 19 }],
178185
},
186+
{
187+
// Reports suggestions, no hasSuggestions property, violation should be on `meta` object, non-empty meta object.
188+
code: `
189+
module.exports = {
190+
meta: { foo: 'bar' },
191+
create(context) { context.report({node, message, suggest: [{}]}); }
192+
};
193+
`,
194+
output: `
195+
module.exports = {
196+
meta: { hasSuggestions: true, foo: 'bar' },
197+
create(context) { context.report({node, message, suggest: [{}]}); }
198+
};
199+
`,
200+
errors: [{ messageId: 'shouldBeSuggestable', type: 'ObjectExpression', line: 3, column: 17, endLine: 3, endColumn: 31 }],
201+
},
179202
{
180203
// Reports suggestions (in variable), no hasSuggestions property, violation should be on `meta` object.
181204
code: `
@@ -185,6 +208,13 @@ ruleTester.run('require-meta-has-suggestions', rule, {
185208
create(context) { context.report({node, message, suggest: SUGGESTIONS}); }
186209
};
187210
`,
211+
output: `
212+
const SUGGESTIONS = [{}];
213+
module.exports = {
214+
meta: { hasSuggestions: true },
215+
create(context) { context.report({node, message, suggest: SUGGESTIONS}); }
216+
};
217+
`,
188218
errors: [{ messageId: 'shouldBeSuggestable', type: 'ObjectExpression', line: 4, column: 17, endLine: 4, endColumn: 19 }],
189219
},
190220
{
@@ -195,8 +225,46 @@ ruleTester.run('require-meta-has-suggestions', rule, {
195225
create(context) { context.report({node, message, suggest: [{}]}); }
196226
};
197227
`,
228+
output: `
229+
module.exports = {
230+
meta: { hasSuggestions: true },
231+
create(context) { context.report({node, message, suggest: [{}]}); }
232+
};
233+
`,
198234
errors: [{ messageId: 'shouldBeSuggestable', type: 'Literal', line: 3, column: 35, endLine: 3, endColumn: 40 }],
199235
},
236+
{
237+
// Reports suggestions, hasSuggestions property set to `null`, violation should be on `null`
238+
code: `
239+
module.exports = {
240+
meta: { hasSuggestions: null },
241+
create(context) { context.report({node, message, suggest: [{}]}); }
242+
};
243+
`,
244+
output: `
245+
module.exports = {
246+
meta: { hasSuggestions: true },
247+
create(context) { context.report({node, message, suggest: [{}]}); }
248+
};
249+
`,
250+
errors: [{ messageId: 'shouldBeSuggestable', type: 'Literal', line: 3, column: 35, endLine: 3, endColumn: 39 }],
251+
},
252+
{
253+
// Reports suggestions, hasSuggestions property set to `undefined`, violation should be on `undefined`
254+
code: `
255+
module.exports = {
256+
meta: { hasSuggestions: undefined },
257+
create(context) { context.report({node, message, suggest: [{}]}); }
258+
};
259+
`,
260+
output: `
261+
module.exports = {
262+
meta: { hasSuggestions: true },
263+
create(context) { context.report({node, message, suggest: [{}]}); }
264+
};
265+
`,
266+
errors: [{ messageId: 'shouldBeSuggestable', type: 'Identifier', line: 3, column: 35, endLine: 3, endColumn: 44 }],
267+
},
200268
{
201269
// Reports suggestions, hasSuggestions property set to false (as variable), violation should be on variable
202270
code: `
@@ -206,6 +274,7 @@ ruleTester.run('require-meta-has-suggestions', rule, {
206274
create(context) { context.report({node, message, suggest: [{}]}); }
207275
};
208276
`,
277+
output: null,
209278
errors: [{ messageId: 'shouldBeSuggestable', type: 'Identifier', line: 4, column: 19, endLine: 4, endColumn: 33 }],
210279
},
211280
{
@@ -216,6 +285,7 @@ ruleTester.run('require-meta-has-suggestions', rule, {
216285
create(context) { context.report({node, message}); }
217286
};
218287
`,
288+
output: null,
219289
errors: [{ messageId: 'shouldNotBeSuggestable', type: 'Literal', line: 3, column: 35, endLine: 3, endColumn: 39 }],
220290
},
221291
],

0 commit comments

Comments
 (0)