Skip to content

Commit f6e4c89

Browse files
authored
Merge pull request #1478 from jomasti/issue-1452
Support propWrapperFunctions for boolean-prop-naming
2 parents 58159c0 + fecd9a4 commit f6e4c89

File tree

2 files changed

+136
-1
lines changed

2 files changed

+136
-1
lines changed

lib/rules/boolean-prop-naming.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ module.exports = {
4646
const config = context.options[0] || {};
4747
const rule = config.rule ? new RegExp(config.rule) : null;
4848
const propTypeNames = config.propTypeNames || ['bool'];
49+
const propWrapperFunctions = new Set(context.settings.propWrapperFunctions || []);
4950

5051
// Remembers all Flowtype object definitions
5152
const objectTypeAnnotations = new Map();
@@ -138,6 +139,13 @@ module.exports = {
138139
});
139140
}
140141

142+
function checkPropWrapperArguments(node, args) {
143+
if (!node || !Array.isArray(args)) {
144+
return;
145+
}
146+
args.filter(arg => arg.type === 'ObjectExpression').forEach(object => validatePropNaming(node, object.properties));
147+
}
148+
141149
// --------------------------------------------------------------------------
142150
// Public
143151
// --------------------------------------------------------------------------
@@ -147,6 +155,9 @@ module.exports = {
147155
if (!rule || !propsUtil.isPropTypesDeclaration(node)) {
148156
return;
149157
}
158+
if (node.value && node.value.type === 'CallExpression' && propWrapperFunctions.has(sourceCode.getText(node.value.callee))) {
159+
checkPropWrapperArguments(node, node.value.arguments);
160+
}
150161
if (node.value && node.value.properties) {
151162
validatePropNaming(node, node.value.properties);
152163
}
@@ -160,7 +171,12 @@ module.exports = {
160171
return;
161172
}
162173
const component = utils.getRelatedComponent(node);
163-
if (!component || !node.parent.right.properties) {
174+
if (!component || !node.parent.right) {
175+
return;
176+
}
177+
const right = node.parent.right;
178+
if (right.type === 'CallExpression' && propWrapperFunctions.has(sourceCode.getText(right.callee))) {
179+
checkPropWrapperArguments(component.node, right.arguments);
164180
return;
165181
}
166182
validatePropNaming(component.node, node.parent.right.properties);

tests/lib/rules/boolean-prop-naming.js

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,18 @@ ruleTester.run('boolean-prop-naming', rule, {
295295
rule: '^is[A-Z]([A-Za-z0-9]?)+'
296296
}],
297297
parser: 'babel-eslint'
298+
}, {
299+
// No propWrapperFunctions setting
300+
code: `
301+
function Card(props) {
302+
return <div>{props.showScore ? 'yeh' : 'no'}</div>;
303+
}
304+
Card.propTypes = merge({}, Card.propTypes, {
305+
showScore: PropTypes.bool
306+
});`,
307+
options: [{
308+
rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+'
309+
}]
298310
}],
299311

300312
invalid: [{
@@ -515,5 +527,112 @@ ruleTester.run('boolean-prop-naming', rule, {
515527
}, {
516528
message: 'Prop name (somethingElse) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
517529
}]
530+
}, {
531+
code: `
532+
function Card(props) {
533+
return <div>{props.showScore ? 'yeh' : 'no'}</div>;
534+
}
535+
Card.propTypes = merge({}, Card.propTypes, {
536+
showScore: PropTypes.bool
537+
});`,
538+
settings: {
539+
propWrapperFunctions: ['merge']
540+
},
541+
options: [{
542+
rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+'
543+
}],
544+
errors: [{
545+
message: 'Prop name (showScore) doesn\'t match rule (^(is|has)[A-Z]([A-Za-z0-9]?)+)'
546+
}]
547+
}, {
548+
code: `
549+
function Card(props) {
550+
return <div>{props.showScore ? 'yeh' : 'no'}</div>;
551+
}
552+
Card.propTypes = Object.assign({}, Card.propTypes, {
553+
showScore: PropTypes.bool
554+
});`,
555+
settings: {
556+
propWrapperFunctions: ['Object.assign']
557+
},
558+
options: [{
559+
rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+'
560+
}],
561+
errors: [{
562+
message: 'Prop name (showScore) doesn\'t match rule (^(is|has)[A-Z]([A-Za-z0-9]?)+)'
563+
}]
564+
}, {
565+
code: `
566+
function Card(props) {
567+
return <div>{props.showScore ? 'yeh' : 'no'}</div>;
568+
}
569+
Card.propTypes = _.assign({}, Card.propTypes, {
570+
showScore: PropTypes.bool
571+
});`,
572+
settings: {
573+
propWrapperFunctions: ['_.assign']
574+
},
575+
options: [{
576+
rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+'
577+
}],
578+
errors: [{
579+
message: 'Prop name (showScore) doesn\'t match rule (^(is|has)[A-Z]([A-Za-z0-9]?)+)'
580+
}]
581+
}, {
582+
code: `
583+
function Card(props) {
584+
return <div>{props.showScore ? 'yeh' : 'no'}</div>;
585+
}
586+
Card.propTypes = forbidExtraProps({
587+
showScore: PropTypes.bool
588+
});`,
589+
settings: {
590+
propWrapperFunctions: ['forbidExtraProps']
591+
},
592+
options: [{
593+
rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+'
594+
}],
595+
errors: [{
596+
message: 'Prop name (showScore) doesn\'t match rule (^(is|has)[A-Z]([A-Za-z0-9]?)+)'
597+
}]
598+
}, {
599+
code: `
600+
class Card extends React.Component {
601+
render() {
602+
return <div>{props.showScore ? 'yeh' : 'no'}</div>;
603+
}
604+
}
605+
Card.propTypes = forbidExtraProps({
606+
showScore: PropTypes.bool
607+
});`,
608+
settings: {
609+
propWrapperFunctions: ['forbidExtraProps']
610+
},
611+
options: [{
612+
rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+'
613+
}],
614+
errors: [{
615+
message: 'Prop name (showScore) doesn\'t match rule (^(is|has)[A-Z]([A-Za-z0-9]?)+)'
616+
}]
617+
}, {
618+
code: `
619+
class Card extends React.Component {
620+
static propTypes = forbidExtraProps({
621+
showScore: PropTypes.bool
622+
});
623+
render() {
624+
return <div>{props.showScore ? 'yeh' : 'no'}</div>;
625+
}
626+
}`,
627+
parser: 'babel-eslint',
628+
settings: {
629+
propWrapperFunctions: ['forbidExtraProps']
630+
},
631+
options: [{
632+
rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+'
633+
}],
634+
errors: [{
635+
message: 'Prop name (showScore) doesn\'t match rule (^(is|has)[A-Z]([A-Za-z0-9]?)+)'
636+
}]
518637
}]
519638
});

0 commit comments

Comments
 (0)