Skip to content

Commit

Permalink
fix: report when required props have default value
Browse files Browse the repository at this point in the history
  • Loading branch information
akulsr0 committed Jul 18, 2024
1 parent 3c1d520 commit 0ddcd35
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 8 deletions.
31 changes: 23 additions & 8 deletions lib/rules/require-default-props.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ module.exports = {
});
}

function isPropWithNoDefaulVal(prop) {
if (prop.type === 'RestElement' || prop.type === 'ExperimentalRestProperty') {
return false;

Check warning on line 111 in lib/rules/require-default-props.js

View check run for this annotation

Codecov / codecov/patch

lib/rules/require-default-props.js#L111

Added line #L111 was not covered by tests
}
return prop.value.type !== 'AssignmentPattern';
}

/**
* If functions option is 'defaultArguments', reports defaultProps is used and all params that doesn't initialized.
* @param {Object} componentNode Node of component.
Expand Down Expand Up @@ -134,15 +141,23 @@ module.exports = {
});
}
} else if (props.type === 'ObjectPattern') {
// Filter required props with default value and report error
props.properties.filter((prop) => {
if (prop.type === 'RestElement' || prop.type === 'ExperimentalRestProperty') {
return false;
}
const propType = propTypes[prop.key.name];
if (!propType || propType.isRequired) {
return false;
}
return prop.value.type !== 'AssignmentPattern';
const propName = prop && prop.key && prop.key.name;
const isPropRequired = propTypes[propName] && propTypes[propName].isRequired;
return propTypes[propName] && isPropRequired && !isPropWithNoDefaulVal(prop);
}).forEach((prop) => {
report(context, messages.noDefaultWithRequired, 'noDefaultWithRequired', {
node: prop,
data: { name: prop.key.name },
});
});

// Filter non required props with no default value and report error
props.properties.filter((prop) => {
const propName = prop && prop.key && prop.key.name;
const isPropRequired = propTypes[propName] && propTypes[propName].isRequired;
return propTypes[propName] && !isPropRequired && isPropWithNoDefaulVal(prop);
}).forEach((prop) => {
report(context, messages.shouldAssignObjectDefault, 'shouldAssignObjectDefault', {
node: prop,
Expand Down
42 changes: 42 additions & 0 deletions tests/lib/rules/require-default-props.js
Original file line number Diff line number Diff line change
Expand Up @@ -3066,5 +3066,47 @@ ruleTester.run('require-default-props', rule, {
propWrapperFunctions: ['forbidExtraProps'],
},
},
{
code: `
function MyStatelessComponent({ foo = 'foo' }) {
return <div>{foo}{bar}</div>;
}
MyStatelessComponent.propTypes = {
foo: PropTypes.string.isRequired,
};
`,
options: [{ functions: 'defaultArguments' }],
errors: [
{
messageId: 'noDefaultWithRequired',
data: { name: 'foo' },
line: 2,
},
],
},
{
code: `
function MyStatelessComponent({ foo = 'foo', bar }) {
return <div>{foo}{bar}</div>;
}
MyStatelessComponent.propTypes = {
foo: PropTypes.string.isRequired,
bar: PropTypes.string
};
`,
options: [{ functions: 'defaultArguments' }],
errors: [
{
messageId: 'noDefaultWithRequired',
data: { name: 'foo' },
line: 2,
},
{
messageId: 'shouldAssignObjectDefault',
data: { name: 'bar' },
line: 2,
},
],
},
]),
});

0 comments on commit 0ddcd35

Please sign in to comment.