From fd0972e08709219e2067272a000a501621bf6aca Mon Sep 17 00:00:00 2001 From: Alex Abenoja Date: Thu, 14 May 2015 14:04:50 -0600 Subject: [PATCH] DRYing ButtonInput --- src/ButtonInput.js | 16 ++++++---------- src/Input.js | 4 +--- src/utils/childrenValueInputValidation.js | 14 ++++++++++++++ test/ButtonInputSpec.js | 8 ++++---- 4 files changed, 25 insertions(+), 17 deletions(-) create mode 100644 src/utils/childrenValueInputValidation.js diff --git a/src/ButtonInput.js b/src/ButtonInput.js index 4df4c6a9f1..8667df0178 100644 --- a/src/ButtonInput.js +++ b/src/ButtonInput.js @@ -2,13 +2,7 @@ import React from 'react'; import Button from './Button'; import FormGroup from './FormGroup'; import InputBase from './InputBase'; - -function valueValidation({children, value}, propName, componentName) { - if (children && value) { - return new Error('Both value and children cannot be passed to ButtonInput'); - } - return React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]).call(null, {children, value}, propName, componentName); -} +import childrenValueValidation from './utils/childrenValueInputValidation'; class ButtonInput extends InputBase { renderFormGroup(children) { @@ -23,18 +17,20 @@ class ButtonInput extends InputBase { } } +ButtonInput.types = ['button', 'reset', 'submit']; + ButtonInput.defaultProps = { type: 'button' }; ButtonInput.propTypes = { - type: React.PropTypes.oneOf(['button', 'reset', 'submit']), + type: React.PropTypes.oneOf(ButtonInput.types), bsStyle(props) { //defer to Button propTypes of bsStyle return null; }, - children: valueValidation, - value: valueValidation + children: childrenValueValidation, + value: childrenValueValidation }; export default ButtonInput; diff --git a/src/Input.js b/src/Input.js index 61456c70c3..6cd7c47776 100644 --- a/src/Input.js +++ b/src/Input.js @@ -3,11 +3,9 @@ import InputBase from './InputBase'; import ButtonInput from './ButtonInput'; import deprecationWarning from './utils/deprecationWarning'; -const buttonTypes = ['button', 'reset', 'submit']; - class Input extends InputBase { render() { - if (buttonTypes.indexOf(this.props.type) > -1) { + if (ButtonInput.types.indexOf(this.props.type) > -1) { deprecationWarning(`Input type=${this.props.type}`, 'ButtonInput'); return ; } diff --git a/src/utils/childrenValueInputValidation.js b/src/utils/childrenValueInputValidation.js new file mode 100644 index 0000000000..075a4c42b0 --- /dev/null +++ b/src/utils/childrenValueInputValidation.js @@ -0,0 +1,14 @@ +import React from 'react'; +import { singlePropFrom } from './CustomPropTypes'; + +const propList = ['children', 'value']; +const typeList = [React.PropTypes.number, React.PropTypes.string]; + +export default function valueValidation(props, propName, componentName) { + let error = singlePropFrom(propList)(props, propName, componentName); + if (!error) { + const oneOfType = React.PropTypes.oneOfType(typeList); + error = oneOfType(props, propName, componentName); + } + return error; +} diff --git a/test/ButtonInputSpec.js b/test/ButtonInputSpec.js index 5118181938..7f5e66ac66 100644 --- a/test/ButtonInputSpec.js +++ b/test/ButtonInputSpec.js @@ -55,11 +55,11 @@ describe('ButtonInput', () =>{ }); it('throws a warning if given both children and a value property', function () { - ReactTestUtils.renderIntoDocument( - button - ); + const testData = { value: 5, children: 'button' }; + const result = ButtonInput.propTypes.value(testData, 'value', 'ButtonInput'); - shouldWarn('Both value and children'); + result.should.be.instanceOf(Error); + result.message.should.have.string('value and children'); }); it('does not throw an error for strings and numbers', function () {