Skip to content

Commit

Permalink
Update: Add catchNoFixerButFixableProperty option (default false) t…
Browse files Browse the repository at this point in the history
…o catch non-fixable rules that enable the fixable property in `require-meta-fixable` rule (#165)

* New: Add `catchNoFixerButFixableProperty` option (default false) to catch non-fixable rules that enable the fixable property in `require-meta-fixable` rule

* add tests

* fix variable name
  • Loading branch information
bmish authored Jul 27, 2021
1 parent 95021dd commit da652aa
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 9 deletions.
17 changes: 17 additions & 0 deletions docs/rules/require-meta-fixable.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ module.exports = {
};
```

```js
/* eslint eslint-plugin/require-meta-fixable: ["error", { catchNoFixerButFixableProperty: true }] */

module.exports = {
meta: { fixable: 'code' }, // property enabled but no fixer detected
create (context) {
context.report({ node, message: 'foo' });
},
};
```

Examples of **correct** code for this rule:

```js
Expand Down Expand Up @@ -77,6 +88,12 @@ module.exports = {
};
```

## Options

This rule takes an optional object containing:

* `boolean``catchNoFixerButFixableProperty` — default `false` - Whether the rule should attempt to detect rules that do not have a fixer but enable the `meta.fixable` property. This option is off by default because it increases the chance of false positives since fixers can't always be detected when helper functions are used.

## Further Reading

* [ESLint's autofix API](http://eslint.org/docs/developer-guide/working-with-rules#applying-fixes)
Expand Down
19 changes: 18 additions & 1 deletion lib/rules/require-meta-fixable.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,28 @@ module.exports = {
category: 'Rules',
recommended: true,
},
schema: [],
schema: [
{
type: 'object',
properties: {
catchNoFixerButFixableProperty: {
type: 'boolean',
default: false,
},
},
additionalProperties: false,
},
],
messages: {
invalid: '`meta.fixable` must be either `code`, `whitespace`, or `null`.',
missing: '`meta.fixable` must be either `code` or `whitespace` for fixable rules.',
noFixerButFixableValue: '`meta.fixable` is enabled but no fixer detected.',
},
},

create (context) {
const catchNoFixerButFixableProperty = context.options[0] && context.options[0].catchNoFixerButFixableProperty;

const sourceCode = context.getSourceCode();
const ruleInfo = utils.getRuleInfo(sourceCode);
let contextIdentifiers;
Expand Down Expand Up @@ -82,6 +96,9 @@ module.exports = {
if (usesFixFunctions && !['code', 'whitespace'].includes(staticValue.value)) {
// Rule is fixable but `fixable` property does not have a fixable value.
context.report({ node: metaFixableProp.value, messageId: 'missing' });
} else if (catchNoFixerButFixableProperty && !usesFixFunctions && ['code', 'whitespace'].includes(staticValue.value)) {
// Rule is NOT fixable but `fixable` property has a fixable value.
context.report({ node: metaFixableProp.value, messageId: 'noFixerButFixableValue' });
}
} else if (!metaFixableProp && usesFixFunctions) {
// Rule is fixable but is missing the `fixable` property.
Expand Down
87 changes: 79 additions & 8 deletions tests/lib/rules/require-meta-fixable.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,6 @@ ruleTester.run('require-meta-fixable', rule, {
}
};
`,
`
module.exports = {
meta: { fixable: 'code' },
create(context) {
context.report({node, message});
}
};
`,
`
module.exports = {
meta: { fixable: null },
Expand Down Expand Up @@ -132,6 +124,53 @@ ruleTester.run('require-meta-fixable', rule, {
ecmaVersion: 9,
},
},

// catchNoFixerButFixableProperty = false (implicitly)
`
module.exports = {
meta: { fixable: 'code' },
create(context) { context.report({node, message}); }
};
`,
`
module.exports = {
meta: { fixable: 'whitespace' },
create(context) { context.report({node, message}); }
};
`,
// catchNoFixerButFixableProperty = false (explicitly)
{
code: `
module.exports = {
meta: { fixable: 'code' },
create(context) { context.report({node, message}); }
};
`,
options: [{ catchNoFixerButFixableProperty: false }],
},
{
code: `
module.exports = {
meta: { fixable: 'whitespace' },
create(context) { context.report({node, message}); }
};
`,
options: [{ catchNoFixerButFixableProperty: false }],
},
// catchNoFixerButFixableProperty = true
{
code: `
module.exports = {
meta: { fixable: 'code' },
create(context) {
foo
? context.report({ node, message })
: context.report({ node, message, fix });
}
};
`,
options: [{ catchNoFixerButFixableProperty: true }],
},
],

invalid: [
Expand Down Expand Up @@ -207,5 +246,37 @@ ruleTester.run('require-meta-fixable', rule, {
`,
errors: [{ messageId: 'missing', type: 'Identifier' }],
},

// catchNoFixerButFixableProperty = true
{
code: `
module.exports = {
meta: { fixable: 'code' },
create(context) { context.report({node, message}); }
};
`,
options: [{ catchNoFixerButFixableProperty: true }],
errors: [{ messageId: 'noFixerButFixableValue', type: 'Literal' }],
},
{
code: `
module.exports = {
meta: { fixable: 'whitespace' },
create(context) { context.report({node, message}); }
};
`,
options: [{ catchNoFixerButFixableProperty: true }],
errors: [{ messageId: 'noFixerButFixableValue', type: 'Literal' }],
},
{
code: `
module.exports = {
meta: { fixable: null },
create(context) { context.report({node, message, fix}); }
};
`,
options: [{ catchNoFixerButFixableProperty: true }],
errors: [{ messageId: 'missing', type: 'Literal' }],
},
],
});

0 comments on commit da652aa

Please sign in to comment.