diff --git a/lib/rules/no-unused-prop-types.js b/lib/rules/no-unused-prop-types.js index cc478ae8ec..4318c275cf 100644 --- a/lib/rules/no-unused-prop-types.js +++ b/lib/rules/no-unused-prop-types.js @@ -175,7 +175,6 @@ module.exports = { function mustBeValidated(component) { return Boolean( component && - component.usedPropTypes && !component.ignorePropsValidation ); } @@ -234,8 +233,9 @@ module.exports = { * @returns {Boolean} True if the prop is used, false if not. */ function isPropUsed(node, prop) { - for (let i = 0, l = node.usedPropTypes.length; i < l; i++) { - const usedProp = node.usedPropTypes[i]; + const usedPropTypes = node.usedPropTypes || []; + for (let i = 0, l = usedPropTypes.length; i < l; i++) { + const usedProp = usedPropTypes[i]; if ( prop.type === 'shape' || prop.name === '__ANY_KEY__' || @@ -897,6 +897,13 @@ module.exports = { } }, + JSXSpreadAttribute: function(node) { + const component = components.get(utils.getParentComponent()); + components.set(component ? component.node : node, { + ignorePropsValidation: true + }); + }, + MethodDefinition: function(node) { if (!isPropTypesDeclaration(node.key)) { return; diff --git a/tests/lib/rules/no-unused-prop-types.js b/tests/lib/rules/no-unused-prop-types.js index eff0e9c962..93960233e7 100644 --- a/tests/lib/rules/no-unused-prop-types.js +++ b/tests/lib/rules/no-unused-prop-types.js @@ -557,26 +557,6 @@ ruleTester.run('no-unused-prop-types', rule, { '});' ].join('\n'), options: [{customValidators: ['CustomValidator']}] - }, { - code: [ - 'class Comp1 extends Component {', - ' render() {', - ' return ;', - ' }', - '}', - 'Comp1.propTypes = {', - ' prop1: PropTypes.number', - '};', - 'class Comp2 extends Component {', - ' render() {', - ' return ;', - ' }', - '}', - 'Comp2.propTypes = {', - ' prop2: PropTypes.arrayOf(Comp1.propTypes.prop1)', - '};' - ].join('\n'), - parser: 'babel-eslint' }, { code: [ 'const SomeComponent = createReactClass({', @@ -782,54 +762,6 @@ ruleTester.run('no-unused-prop-types', rule, { ' }', '});' ].join('\n') - }, { - code: [ - 'const statelessComponent = (props) => {', - ' const subRender = () => {', - ' return {props.someProp};', - ' };', - ' return
{subRender()}
;', - '};', - 'statelessComponent.propTypes = {', - ' someProp: PropTypes.string', - '};' - ].join('\n') - }, { - code: [ - 'const statelessComponent = ({ someProp }) => {', - ' const subRender = () => {', - ' return {someProp};', - ' };', - ' return
{subRender()}
;', - '};', - 'statelessComponent.propTypes = {', - ' someProp: PropTypes.string', - '};' - ].join('\n') - }, { - code: [ - 'const statelessComponent = function({ someProp }) {', - ' const subRender = () => {', - ' return {someProp};', - ' };', - ' return
{subRender()}
;', - '};', - 'statelessComponent.propTypes = {', - ' someProp: PropTypes.string', - '};' - ].join('\n') - }, { - code: [ - 'function statelessComponent({ someProp }) {', - ' const subRender = () => {', - ' return {someProp};', - ' };', - ' return
{subRender()}
;', - '};', - 'statelessComponent.propTypes = {', - ' someProp: PropTypes.string', - '};' - ].join('\n') }, { code: [ 'function notAComponent({ something }) {', @@ -3215,6 +3147,49 @@ ruleTester.run('no-unused-prop-types', rule, { line: 11, column: 8 }] + }, { // None of the props are used issue #1162 + code: [ + 'import React from "react"; ', + 'var Hello = React.createReactClass({', + ' propTypes: {', + ' name: React.PropTypes.string', + ' },', + ' render: function() {', + ' return
Hello Bob
;', + ' }', + '});' + ].join('\n'), + errors: [{ + message: '\'name\' PropType is defined but prop is never used' + }] + }, { + code: [ + 'class Comp1 extends Component {', + ' render() {', + ' return ;', + ' }', + '}', + 'Comp1.propTypes = {', + ' prop1: PropTypes.number', + '};', + 'class Comp2 extends Component {', + ' render() {', + ' return ;', + ' }', + '}', + 'Comp2.propTypes = {', + ' prop2: PropTypes.arrayOf(Comp1.propTypes.prop1)', + '};' + ].join('\n'), + parser: 'babel-eslint', + errors: [{ + message: '\'prop1\' PropType is defined but prop is never used' + }, { + message: '\'prop2\' PropType is defined but prop is never used' + }, { + message: '\'prop2.*\' PropType is defined but prop is never used' + }] + } /* , { // Enable this when the following issue is fixed