Skip to content

Commit

Permalink
[New]: jsx-no-literals: add validateProps option to ignore props …
Browse files Browse the repository at this point in the history
…validation
  • Loading branch information
shospodarets committed Mar 8, 2020
1 parent 6dd14b9 commit 122721f
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 58 deletions.
4 changes: 2 additions & 2 deletions docs/rules/jsx-no-literals.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ There are two options:

* `noStrings`(`false` default) - Enforces no string literals used as children, wrapped or unwrapped.
* `allowedStrings` - An array of unique string values that would otherwise warn, but will be ignored.
* `validateProps`(`false` default) - Enforces no literals used in props, wrapped or unwrapped.
* `ignoreProps`(`false` default) - When `true` the rule ignores literals used in props, wrapped or unwrapped.

To use, you can specify as follows:

```js
"react/jsx-no-literals": [<enabled>, {"noStrings": true, "allowedStrings": ["allowed"], "validateProps": true}]
"react/jsx-no-literals": [<enabled>, {"noStrings": true, "allowedStrings": ["allowed"], "ignoreProps": false}]
```

In this configuration, the following are considered warnings:
Expand Down
12 changes: 6 additions & 6 deletions lib/rules/jsx-no-literals.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ module.exports = {
type: 'string'
}
},
validateProps: {
ignoreProps: {
type: 'boolean'
}
},
Expand All @@ -47,7 +47,7 @@ module.exports = {
},

create(context) {
const defaults = {noStrings: false, allowedStrings: [], validateProps: false};
const defaults = {noStrings: false, allowedStrings: [], ignoreProps: false};
const config = Object.assign({}, defaults, context.options[0] || {});
config.allowedStrings = new Set(config.allowedStrings.map(trimIfString));

Expand Down Expand Up @@ -114,16 +114,16 @@ module.exports = {

return {
Literal(node) {
if (getValidation(node) && (hasJSXElementParentOrGrandParent(node) || config.validateProps)) {
if (getValidation(node) && (hasJSXElementParentOrGrandParent(node) || !config.ignoreProps)) {
reportLiteralNode(node);
}
},

JSXAttribute(node) {
const isNodeValueString = node.value && node.value && node.value.type === 'Literal' && typeof node.value.value === 'string';

if (config.noStrings && config.validateProps && isNodeValueString) {
const customMessage = 'Invalid attribute value';
if (config.noStrings && !config.ignoreProps && isNodeValueString) {
const customMessage = 'Invalid prop value';
reportLiteralNode(node, customMessage);
}
},
Expand All @@ -141,7 +141,7 @@ module.exports = {
const isParentJSXExpressionCont = parentType === 'JSXExpressionContainer';
const isParentJSXElement = parentType === 'JSXElement' || grandParentType === 'JSXElement';

if (isParentJSXExpressionCont && config.noStrings && (isParentJSXElement || config.validateProps)) {
if (isParentJSXExpressionCont && config.noStrings && (isParentJSXElement || !config.ignoreProps)) {
reportLiteralNode(node);
}
}
Expand Down
83 changes: 33 additions & 50 deletions tests/lib/rules/jsx-no-literals.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ function jsxMessage(str) {
return `Missing JSX expression container around literal string: “${str}”`;
}

function invalidProp(str) {
return `Invalid prop value: “${str}”`;
}

const ruleTester = new RuleTester({parserOptions});
ruleTester.run('jsx-no-literals', rule, {

Expand Down Expand Up @@ -140,29 +144,29 @@ ruleTester.run('jsx-no-literals', rule, {
</Foo>
`,
parser: parsers.BABEL_ESLINT,
options: [{noStrings: true}]
options: [{noStrings: true, ignoreProps: true}]
}, {
code: `
<Foo bar="test">
{translate('my.translate.key')}
</Foo>
`,
parser: parsers.BABEL_ESLINT,
options: [{noStrings: true}]
options: [{noStrings: true, ignoreProps: true}]
}, {
code: `
<Foo bar="test">
{intl.formatText(message)}
</Foo>
`,
options: [{noStrings: true}]
options: [{noStrings: true, ignoreProps: true}]
}, {
code: `
<Foo bar="test">
{translate('my.translate.key')}
</Foo>
`,
options: [{noStrings: true}]
options: [{noStrings: true, ignoreProps: true}]
}, {
code: '<Foo bar={true} />',
options: [{noStrings: true}]
Expand All @@ -187,7 +191,7 @@ ruleTester.run('jsx-no-literals', rule, {
}
}
`,
options: [{noStrings: true}]
options: [{noStrings: true, ignoreProps: true}]
}, {
code: `
class Comp1 extends Component {
Expand Down Expand Up @@ -271,7 +275,7 @@ ruleTester.run('jsx-no-literals', rule, {
}
} `,
parser: parsers.BABEL_ESLINT,
options: [{noStrings: true, validateProps: true}]
options: [{noStrings: true, ignoreProps: false}]
}
],

Expand Down Expand Up @@ -381,42 +385,33 @@ ruleTester.run('jsx-no-literals', rule, {
{'Test'}
</Foo>
`,
parser: parsers.BABEL_ESLINT,
options: [{noStrings: true}],
errors: [{message: stringsMessage('\'Test\'')}]
}, {
code: `
<Foo bar="test">
{'Test'}
</Foo>
`,
options: [{noStrings: true}],
errors: [{message: stringsMessage('\'Test\'')}]
options: [{noStrings: true, ignoreProps: false}],
errors: [
{message: invalidProp('bar="test"')},
{message: stringsMessage('\'Test\'')}
]
}, {
code: `
<Foo bar="test">
{'Test' + name}
</Foo>
`,
options: [{noStrings: true}],
errors: [{message: stringsMessage('\'Test\'')}]
}, {
code: `
<Foo bar="test">
Test
</Foo>
`,
parser: parsers.BABEL_ESLINT,
options: [{noStrings: true}],
errors: [{message: stringsMessage('Test')}]
options: [{noStrings: true, ignoreProps: false}],
errors: [
{message: invalidProp('bar="test"')},
{message: stringsMessage('\'Test\'')}
]
}, {
code: `
<Foo bar="test">
Test
</Foo>
`,
options: [{noStrings: true}],
errors: [{message: stringsMessage('Test')}]
options: [{noStrings: true, ignoreProps: false}],
errors: [
{message: invalidProp('bar="test"')},
{message: stringsMessage('Test')}
]
}, {
code: `
<Foo>
Expand All @@ -427,33 +422,33 @@ ruleTester.run('jsx-no-literals', rule, {
errors: [{message: stringsMessage('`Test`')}]
}, {
code: '<Foo bar={`Test`} />',
options: [{noStrings: true, validateProps: true}],
options: [{noStrings: true, ignoreProps: false}],
errors: [{message: stringsMessage('`Test`')}]
}, {
code: '<Foo bar={`${baz}`} />',
options: [{noStrings: true, validateProps: true}],
options: [{noStrings: true, ignoreProps: false}],
errors: [{message: stringsMessage('`${baz}`')}]
}, {
code: '<Foo bar={`Test ${baz}`} />',
options: [{noStrings: true, validateProps: true}],
options: [{noStrings: true, ignoreProps: false}],
errors: [{message: stringsMessage('`Test ${baz}`')}]
}, {
code: '<Foo bar={`foo` + \'bar\'} />',
options: [{noStrings: true, validateProps: true}],
options: [{noStrings: true, ignoreProps: false}],
errors: [
{message: stringsMessage('`foo`')},
{message: stringsMessage('\'bar\'')}
]
}, {
code: '<Foo bar={`foo` + `bar`} />',
options: [{noStrings: true, validateProps: true}],
options: [{noStrings: true, ignoreProps: false}],
errors: [
{message: stringsMessage('`foo`')},
{message: stringsMessage('`bar`')}
]
}, {
code: '<Foo bar={\'foo\' + `bar`} />',
options: [{noStrings: true, validateProps: true}],
options: [{noStrings: true, ignoreProps: false}],
errors: [
{message: stringsMessage('\'foo\'')},
{message: stringsMessage('`bar`')}
Expand All @@ -466,26 +461,14 @@ ruleTester.run('jsx-no-literals', rule, {
}
}
`,
options: [{noStrings: true, allowedStrings: ['asd']}],
errors: [
{message: stringsMessage('asdf')}
]
}, {
code: `
class Comp1 extends Component {
render() {
return <div bar={'foo'}>asdf</div>
}
}
`,
options: [{noStrings: true, allowedStrings: ['asd'], validateProps: true}],
options: [{noStrings: true, allowedStrings: ['asd'], ignoreProps: false}],
errors: [
{message: stringsMessage('\'foo\'')},
{message: stringsMessage('asdf')}
]
}, {
code: '<Foo bar={\'bar\'} />',
options: [{noStrings: true, validateProps: true}],
options: [{noStrings: true, ignoreProps: false}],
errors: [
{message: stringsMessage('\'bar\'')}
]
Expand Down

0 comments on commit 122721f

Please sign in to comment.