From 2749cfdf8fc893ce0f068a7e41045f72a3f39cbc Mon Sep 17 00:00:00 2001 From: Alex Abenoja Date: Fri, 15 May 2015 00:14:49 -0600 Subject: [PATCH] [added] CustomPropTypes.singlePropFrom Throw an error if multiple properties in the given list have a value --- src/utils/CustomPropTypes.js | 30 +++++++++++++++++++++++++++++- test/CustomPropTypesSpec.js | 20 ++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/utils/CustomPropTypes.js b/src/utils/CustomPropTypes.js index c56a0a4e8a..5a6ae4e0fc 100644 --- a/src/utils/CustomPropTypes.js +++ b/src/utils/CustomPropTypes.js @@ -22,7 +22,17 @@ let CustomPropTypes = { * @param componentName * @returns {Error|undefined} */ - keyOf: createKeyOfChecker + keyOf: createKeyOfChecker, + /** + * Checks if only one of the listed properties is in use. An error is given + * if multiple have a value + * + * @param props + * @param propName + * @param componentName + * @returns {Error|undefined} + */ + singlePropFrom: createSinglePropFromChecker }; /** @@ -80,4 +90,22 @@ function createKeyOfChecker(obj) { return createChainableTypeChecker(validate); } +function createSinglePropFromChecker(arrOfProps) { + function validate(props, propName, componentName) { + const usedPropCount = arrOfProps + .map(listedProp => props[listedProp]) + .reduce((acc, curr) => acc + (curr !== undefined ? 1 : 0), 0); + + if (usedPropCount > 1) { + const [first, ...others] = arrOfProps; + const message = `${others.join(', ')} and ${first}`; + return new Error( + `Invalid prop '${propName}', only one of the following ` + + `may be provided: ${message}` + ); + } + } + return validate; +} + export default CustomPropTypes; diff --git a/test/CustomPropTypesSpec.js b/test/CustomPropTypesSpec.js index 9a0b94deb2..d28137f585 100644 --- a/test/CustomPropTypesSpec.js +++ b/test/CustomPropTypesSpec.js @@ -47,4 +47,24 @@ describe('CustomPropTypes', function () { assert.isUndefined(validate('bar')); }); }); + + describe('singlePropFrom', function () { + function validate(testProps) { + const propList = ['children', 'value']; + + return CustomPropTypes.singlePropFrom(propList)(testProps, 'value', 'Component'); + } + + it('Should return undefined if only one listed prop in used', function () { + const testProps = {value: 5}; + + assert.isUndefined(validate(testProps)); + }); + + it('Should return error if multiple of the listed properties have values', function () { + const testProps = {value: 5, children: 5}; + + validate(testProps).should.be.instanceOf(Error); + }); + }); });