From 0e976b9c10844c6754f2553f7e5c66dbec918fc7 Mon Sep 17 00:00:00 2001 From: David Petersen Date: Sun, 5 Nov 2017 19:33:00 -0600 Subject: [PATCH] Handle no-props-unused-props in custom validators When a custom prop validator is used mark props used inside the validator as used. Fixes #1068 --- lib/rules/no-unused-prop-types.js | 7 +++ tests/lib/rules/no-unused-prop-types.js | 78 ++++++++++++++++++++----- 2 files changed, 70 insertions(+), 15 deletions(-) diff --git a/lib/rules/no-unused-prop-types.js b/lib/rules/no-unused-prop-types.js index 0471913737..a5afea72af 100644 --- a/lib/rules/no-unused-prop-types.js +++ b/lib/rules/no-unused-prop-types.js @@ -791,6 +791,13 @@ module.exports = { types.name = key; types.node = value; declaredPropTypes.push(types); + // Handle custom prop validators using props inside + if ( + value.type === 'ArrowFunctionExpression' + || value.type === 'FunctionExpression' + ) { + markPropTypesAsUsed(value); + } }); break; case 'MemberExpression': diff --git a/tests/lib/rules/no-unused-prop-types.js b/tests/lib/rules/no-unused-prop-types.js index 62ef6094c0..03deb7496a 100644 --- a/tests/lib/rules/no-unused-prop-types.js +++ b/tests/lib/rules/no-unused-prop-types.js @@ -829,10 +829,10 @@ ruleTester.run('no-unused-prop-types', rule, { type PropsA = { a: string } type PropsB = { b: string } type Props = PropsA & PropsB; - + class MyComponent extends React.Component { props: Props; - + render() { return
{this.props.a} - {this.props.b}
} @@ -848,7 +848,7 @@ ruleTester.run('no-unused-prop-types', rule, { class Bar extends React.Component { props: Props & PropsC; - + render() { return
{this.props.foo} - {this.props.bar} - {this.props.zap}
} @@ -864,7 +864,7 @@ ruleTester.run('no-unused-prop-types', rule, { class Bar extends React.Component { props: Props & PropsC; - + render() { return
{this.props.foo} - {this.props.bar} - {this.props.zap}
} @@ -876,12 +876,12 @@ ruleTester.run('no-unused-prop-types', rule, { type PropsB = { foo: string }; type PropsC = { bar: string }; type Props = PropsB & { - zap: string + zap: string }; class Bar extends React.Component { props: Props & PropsC; - + render() { return
{this.props.foo} - {this.props.bar} - {this.props.zap}
} @@ -893,12 +893,12 @@ ruleTester.run('no-unused-prop-types', rule, { type PropsB = { foo: string }; type PropsC = { bar: string }; type Props = { - zap: string + zap: string } & PropsB; class Bar extends React.Component { props: Props & PropsC; - + render() { return
{this.props.foo} - {this.props.bar} - {this.props.zap}
} @@ -2208,6 +2208,54 @@ ruleTester.run('no-unused-prop-types', rule, { `, settings: {react: {flowVersion: '0.53'}}, parser: 'babel-eslint' + }, { + // Issue #1068 + code: ` + class MyComponent extends Component { + static propTypes = { + validate: PropTypes.bool, + options: PropTypes.array, + value: ({options, value, validate}) => { + if (!validate) return; + if (options.indexOf(value) < 0) + throw new Errow('oops'); + } + } + + render() { + return + } + } + `, + parser: 'babel-eslint' + }, { + // Issue #1068 + code: ` + class MyComponent extends Component { + static propTypes = { + validate: PropTypes.bool, + options: PropTypes.array, + value: function ({options, value, validate}) { + if (!validate) return; + if (options.indexOf(value) < 0) + throw new Errow('oops'); + } + } + + render() { + return + } + } + `, + parser: 'babel-eslint' } ], @@ -2796,10 +2844,10 @@ ruleTester.run('no-unused-prop-types', rule, { type PropsA = { a: string } type PropsB = { b: string } type Props = PropsA & PropsB; - + class MyComponent extends React.Component { props: Props; - + render() { return
{this.props.a}
} @@ -2818,7 +2866,7 @@ ruleTester.run('no-unused-prop-types', rule, { class Bar extends React.Component { props: Props & PropsC; - + render() { return
{this.props.foo} - {this.props.bar}
} @@ -2833,12 +2881,12 @@ ruleTester.run('no-unused-prop-types', rule, { type PropsB = { foo: string }; type PropsC = { bar: string }; type Props = PropsB & { - zap: string + zap: string }; class Bar extends React.Component { props: Props & PropsC; - + render() { return
{this.props.foo} - {this.props.bar}
} @@ -2853,12 +2901,12 @@ ruleTester.run('no-unused-prop-types', rule, { type PropsB = { foo: string }; type PropsC = { bar: string }; type Props = { - zap: string + zap: string } & PropsB; class Bar extends React.Component { props: Props & PropsC; - + render() { return
{this.props.foo} - {this.props.bar}
}