Skip to content

Commit

Permalink
Validate boolean prop names nested deeper
Browse files Browse the repository at this point in the history
  • Loading branch information
pawelnvk committed Apr 10, 2019
1 parent 35de81b commit e8dc9c1
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 16 deletions.
76 changes: 60 additions & 16 deletions lib/rules/boolean-prop-naming.js
Expand Up @@ -104,6 +104,64 @@ module.exports = {
return node.key.name;
}

/**
* Checks if prop is declared in flow way
* @param {Object} prop Property object, single prop type declaration
* @returns {Boolean}
*/
function flowCheck(prop) {
return (
prop.type === 'ObjectTypeProperty' &&
prop.value.type === 'BooleanTypeAnnotation' &&
rule.test(getPropName(prop)) === false
);
}

/**
* Checks if prop is declared in regular way
* @param {Object} prop Property object, single prop type declaration
* @returns {Boolean}
*/
function regularCheck(prop) {
const propKey = getPropKey(prop);
return (
propKey &&
propTypeNames.indexOf(propKey) >= 0 &&
rule.test(getPropName(prop)) === false
);
}

/**
* Checks if prop is nested
* @param {Object} prop Property object, single prop type declaration
* @returns {Boolean}
*/
function nestedPropTypes(prop) {
return (
prop.type === 'Property' &&
prop.value.type === 'CallExpression'
);
}

/**
* Runs recursive check on all proptypes
* @param {Array} proptypes A list of Property object (for each proptype defined)
* @param {Function} addInvalidProp callback to run for each error
*/
function runCheck(proptypes, addInvalidProp) {
proptypes = proptypes || [];

proptypes.forEach(prop => {
if (nestedPropTypes(prop)) {
runCheck(prop.value.arguments[0].properties, addInvalidProp);
return;
}
if (flowCheck(prop) || regularCheck(prop)) {
addInvalidProp(prop);
}
});
}

/**
* Checks and mark props with invalid naming
* @param {Object} node The component node we're testing
Expand All @@ -113,22 +171,8 @@ module.exports = {
const component = components.get(node) || node;
const invalidProps = component.invalidProps || [];

(proptypes || []).forEach(prop => {
const propKey = getPropKey(prop);
const flowCheck = (
prop.type === 'ObjectTypeProperty' &&
prop.value.type === 'BooleanTypeAnnotation' &&
rule.test(getPropName(prop)) === false
);
const regularCheck = (
propKey &&
propTypeNames.indexOf(propKey) >= 0 &&
rule.test(getPropName(prop)) === false
);

if (flowCheck || regularCheck) {
invalidProps.push(prop);
}
runCheck(proptypes, prop => {
invalidProps.push(prop);
});

components.set(node, {
Expand Down
84 changes: 84 additions & 0 deletions tests/lib/rules/boolean-prop-naming.js
Expand Up @@ -373,6 +373,42 @@ ruleTester.run('boolean-prop-naming', rule, {
rule: '^is[A-Z]([A-Za-z0-9]?)+'
}],
parser: 'babel-eslint'
}, {
code: `
class Hello extends React.Component {
render() {
return (
<div />
);
}
}
Hello.propTypes = {
isSomething: PropTypes.bool.isRequired,
nested: PropTypes.shape({
isWorking: PropTypes.bool
})
};
`
}, {
code: `
class Hello extends React.Component {
render() {
return (
<div />
);
}
}
Hello.propTypes = {
isSomething: PropTypes.bool.isRequired,
nested: PropTypes.shape({
nested: PropTypes.shape({
isWorking: PropTypes.bool
})
})
};
`
}],

invalid: [{
Expand Down Expand Up @@ -807,5 +843,53 @@ ruleTester.run('boolean-prop-naming', rule, {
errors: [{
message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
}]
}, {
code: `
class Hello extends React.Component {
render() {
return (
<div />
);
}
}
Hello.propTypes = {
isSomething: PropTypes.bool.isRequired,
nested: PropTypes.shape({
failingItIs: PropTypes.bool
})
};
`,
options: [{
rule: '^is[A-Z]([A-Za-z0-9]?)+'
}],
errors: [{
message: 'Prop name (failingItIs) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
}]
}, {
code: `
class Hello extends React.Component {
render() {
return (
<div />
);
}
}
Hello.propTypes = {
isSomething: PropTypes.bool.isRequired,
nested: PropTypes.shape({
nested: PropTypes.shape({
failingItIs: PropTypes.bool
})
})
};
`,
options: [{
rule: '^is[A-Z]([A-Za-z0-9]?)+'
}],
errors: [{
message: 'Prop name (failingItIs) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
}]
}]
});

0 comments on commit e8dc9c1

Please sign in to comment.