Skip to content

Commit

Permalink
[Fix] prop-types: Does not validate missing propTypes for LogicalEx…
Browse files Browse the repository at this point in the history
…pression
  • Loading branch information
toshi-toma authored and ljharb committed Dec 23, 2019
1 parent 8df4943 commit 6eab9e1
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 12 deletions.
42 changes: 30 additions & 12 deletions lib/util/Components.js
Expand Up @@ -46,6 +46,31 @@ function mergeUsedPropTypes(propsList, newPropsList) {
return propsList.concat(propsToAdd);
}

function isReturnsConditionalJSX(node, property, strict) {
const returnsConditionalJSXConsequent = node[property] &&
node[property].type === 'ConditionalExpression' &&
jsxUtil.isJSX(node[property].consequent);
const returnsConditionalJSXAlternate = node[property] &&
node[property].type === 'ConditionalExpression' &&
jsxUtil.isJSX(node[property].alternate);
return strict ?
(returnsConditionalJSXConsequent && returnsConditionalJSXAlternate) :
(returnsConditionalJSXConsequent || returnsConditionalJSXAlternate);
}

function isReturnsLogicalJSX(node, property, strict) {
const returnsLogicalJSXLeft = node[property] &&
node[property].type === 'LogicalExpression' &&
jsxUtil.isJSX(node[property].left);
const returnsLogicalJSXRight = node[property] &&
node[property].type === 'LogicalExpression' &&
jsxUtil.isJSX(node[property].right);
return strict ?
(returnsLogicalJSXLeft && returnsLogicalJSXRight) :
(returnsLogicalJSXLeft || returnsLogicalJSXRight);
}


const Lists = new WeakMap();

/**
Expand Down Expand Up @@ -373,22 +398,15 @@ function componentRule(rule, context) {
return false;
}

const returnsConditionalJSXConsequent = node[property] &&
node[property].type === 'ConditionalExpression' &&
jsxUtil.isJSX(node[property].consequent);
const returnsConditionalJSXAlternate = node[property] &&
node[property].type === 'ConditionalExpression' &&
jsxUtil.isJSX(node[property].alternate);
const returnsConditionalJSX = strict ?
(returnsConditionalJSXConsequent && returnsConditionalJSXAlternate) :
(returnsConditionalJSXConsequent || returnsConditionalJSXAlternate);
const returnsConditionalJSX = isReturnsConditionalJSX(node, property, strict);
const returnsLogicalJSX = isReturnsLogicalJSX(node, property, strict);

const returnsJSX = node[property] &&
jsxUtil.isJSX(node[property]);
const returnsJSX = node[property] && jsxUtil.isJSX(node[property]);
const returnsPragmaCreateElement = this.isCreateElement(node[property]);

return Boolean(
return !!(
returnsConditionalJSX ||
returnsLogicalJSX ||
returnsJSX ||
returnsPragmaCreateElement
);
Expand Down
28 changes: 28 additions & 0 deletions tests/lib/rules/prop-types.js
Expand Up @@ -2465,6 +2465,19 @@ ruleTester.run('prop-types', rule, {
pragma: 'Foo'
}
}
},
{
code: `
const Foo = ({length, ordering}) => (
length > 0 && (
<Paginator items={ordering} pageSize={10} />
)
);
Foo.propTypes = {
length: PropTypes.number,
ordering: PropTypes.array
};
`
}
],

Expand Down Expand Up @@ -4895,6 +4908,21 @@ ruleTester.run('prop-types', rule, {
errors: [{
message: '\'foo.baz\' is missing in props validation'
}]
},
{
code: `
const Foo = ({length, ordering}) => (
length > 0 && (
<Paginator items={ordering} pageSize={10} />
)
);
`,
errors: [{
message: '\'length\' is missing in props validation'
},
{
message: '\'ordering\' is missing in props validation'
}]
}
]
});

0 comments on commit 6eab9e1

Please sign in to comment.