Skip to content

Commit

Permalink
feat: Add auto fix capability to onClick rule when data-test-id attri…
Browse files Browse the repository at this point in the history
…bute is missing (#8)

* feat: Add auto fix capability to onClick rule when data-test-id attribute is missing (#1)

* feat: Add auto fix capability to onClick rule when data-test-id attribute is missing.

* cleaned up parserOptionsMapper from onClick rule and used the generic parserOptionMapper instead

* removed unused code

Co-authored-by: Boima Konuwa <[email protected]>

* fix: Allow multipart jsx node names

Co-authored-by: Boima Konuwa <[email protected]>
Co-authored-by: Chris Garcia <[email protected]>
  • Loading branch information
3 people authored Jan 26, 2021
1 parent 73bc12d commit 0d136bb
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 16 deletions.
17 changes: 15 additions & 2 deletions lib/rules/onClick.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module.exports = {
recommended: true,
url: 'https://github.com/davidcalhoun/eslint-plugin-test-selectors/tree/master/docs/rules/onClick.md'
},
fixable: null,
fixable: 'code',
schema: defaultRuleSchema
},

Expand All @@ -42,7 +42,20 @@ module.exports = {

context.report({
node,
message: getError(errors.onClick.message, testAttribute)
message: getError(errors.onClick.message, testAttribute),
fix: function fix(fixer) {
const { nanoid } = require('nanoid');
const suggestedId = nanoid();
const namePositionEnd = node.name.range[1];
const attributeText = `${ testAttribute }="${ suggestedId }"`;
const start = namePositionEnd - 1;
const end = start + 1;

return fixer.insertTextAfterRange(
[start, end],
` ${ attributeText }`
);
},
});
}
};
Expand Down
46 changes: 42 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@
},
"dependencies": {
"jsx-ast-utils": "^3.2.0",
"nanoid": "^3.1.18",
"requireindex": "^1.2.0"
},
"devDependencies": {
"babel-eslint": "^10.1.0",
"eslint": "^7.16.0",
"mocha": "^8.2.1"
"mocha": "^8.2.1",
"mock-require": "^3.0.3"
},
"engines": {
"node": ">=0.10.0"
Expand Down
58 changes: 51 additions & 7 deletions tests/lib/rules/onClick.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,21 @@ const {
errors
} = require('../../../lib/constants');
const { getError } = require('../../../lib/utils');
const nanoidMock = require('mock-require');

const { onClick } = errors;

const onClickError = getError(onClick.message, defaults.testAttribute);

nanoidMock('nanoid', {
nanoid: function () {
return 'AbYK0YPm2OWYiMaFPKLbp';
},
});

const id = require('nanoid');
const suggestedId = id.nanoid();

const ruleTester = new RuleTester();
ruleTester.run('onClick', rule, {
valid: [
Expand All @@ -31,12 +41,46 @@ ruleTester.run('onClick', rule, {
].map(parserOptionsMapper),

invalid: [
{ code: '<div onClick={ this.handleClick } />', errors: [onClickError] },
{ code: '<div onClick={ this.handleClick }>foo</div>', errors: [onClickError] },
{ code: '<Bar onClick={ this.handleClick } />', errors: [onClickError] },
{ code: '<Bar onClick={ this.handleClick }>foo</Bar>', errors: [onClickError] },
{ code: '<Bar onClick={ () => handleClick() }>foo</Bar>', errors: [onClickError] },
{ code: '<Bar onClick={ () => handleClick() } disabled={ foo }>foo</Bar>', errors: [onClickError] },
{ code: '<Bar onClick={ () => handleClick() } readonly={ foo }>foo</Bar>', errors: [onClickError] }
{
code: '<div onClick={ this.handleClick } />',
errors: [onClickError],
output: `<div data-test-id="${ suggestedId }" onClick={ this.handleClick } />`,
},
{
code: '<div onClick={ this.handleClick }>foo</div>',
errors: [onClickError],
output: `<div data-test-id="${ suggestedId }" onClick={ this.handleClick }>foo</div>`,
},
{
code: '<Bar onClick={ this.handleClick } />',
errors: [onClickError],
output: `<Bar data-test-id="${ suggestedId }" onClick={ this.handleClick } />`,
},
{
code: '<Bar onClick={ this.handleClick }>foo</Bar>',
errors: [onClickError],
output: `<Bar data-test-id="${ suggestedId }" onClick={ this.handleClick }>foo</Bar>`,
},
{
code: '<Bar onClick={ () => handleClick() }>foo</Bar>',
errors: [onClickError],
output: `<Bar data-test-id="${ suggestedId }" onClick={ () => handleClick() }>foo</Bar>`,
},
{
code: '<Bar onClick={ () => handleClick() } disabled={ foo }>foo</Bar>',
errors: [onClickError],
output: `<Bar data-test-id="${ suggestedId }" onClick={ () => handleClick() } disabled={ foo }>foo</Bar>`,
},
{
code: '<Bar onClick={ () => handleClick() } readonly={ foo }>foo</Bar>',
errors: [onClickError],
output: `<Bar data-test-id="${ suggestedId }" onClick={ () => handleClick() } readonly={ foo }>foo</Bar>`,
},
{
code: '<Foo.Bar onClick={ () => handleClick() } readonly={ foo }>foo</Foo.Bar>',
errors: [onClickError],
output:
`<Foo.Bar data-test-id="${ suggestedId }" onClick={ () => handleClick() } readonly={ foo }>foo</Foo.Bar>`,
},
].map(parserOptionsMapper)
});
11 changes: 9 additions & 2 deletions tests/parserOptionsMapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,23 @@ const defaultParserOptions = {
module.exports = function({
code,
errors,
output,
options = [],
parserOptions = {},
}) {
return {
const defaultOptions = {
code,
errors,
options,
parserOptions: {
...defaultParserOptions,
...parserOptions,
}
};
}

if (output) {
defaultOptions.output = output;
}

return defaultOptions;
}

0 comments on commit 0d136bb

Please sign in to comment.