Last active
September 15, 2016 09:05
-
-
Save cirocosta/71046452d3ace8c11bb5 to your computer and use it in GitHub Desktop.
propTypes validation mixin - ReactJS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
require('harmony-reflect'); | |
/** | |
* Here we should not use 'harmony-reflect', but | |
* es6 proxies directly from a harmony | |
* implementation. Traceur-compiler / | |
* react-tools es6 transform dont provide | |
* proxies as the implementation would affect | |
* other things performance. | |
*/ | |
var PropertyValidationMixin = { | |
getInitialState () { | |
var propTypes = this._descriptor.type.propTypes; | |
var rawProps = this.props; | |
var component = this; | |
this.props = new Proxy(rawProps, { | |
get: (obj, prop, receiver) => { | |
if (prop === 'ref' || prop === 'key') | |
throw new Error('Shouldn\'t be defining props for ' + prop); | |
if (!(prop in propTypes)) | |
throw new Error(prop + ' not specified in propTypes.'); | |
return Reflect.get(obj, prop, receiver); | |
} | |
}); | |
return {}; | |
} | |
}; | |
module.exports = PropertyValidationMixin; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @jsx React.DOM | |
*/ | |
'use strict'; | |
jest.dontMock('../src/SwapCheckbox.jsx'); | |
jest.dontMock('harmony-reflect'); | |
describe('SwapCheckbox', function() { | |
it('should change the text after click', function() { | |
var React = require('react/addons'); | |
var SwapCheckbox = require('../src/SwapCheckbox.jsx'); | |
var TestUtils = React.addons.TestUtils; | |
var checkbox = TestUtils.renderIntoDocument( | |
<SwapCheckbox labelOn="On" | |
labelOff="Off" /> | |
); | |
var label = TestUtils.findRenderedDOMComponentWithTag( | |
checkbox, | |
'label' | |
); | |
expect(label.getDOMNode().textContent).toEqual('Off'); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @jsx React.DOM | |
*/ | |
'use strict'; | |
var React = require('react/addons'); | |
var PropertyValidationMixin = require('./PropertyValidationMixin.jsx'); | |
var SwapCheckbox = React.createClass({ | |
propTypes: { | |
labelOn: React.PropTypes.string.isRequired, | |
// labelOff: React.PropTypes.string.isRequired | |
}, | |
getInitialState () { | |
return { | |
isChecked: false | |
}; | |
}, | |
mixins: (() => { | |
return process.env.NODE_ENV === 'development' ? | |
[PropertyValidationMixin] : | |
[]; | |
})(), | |
handleChange () { | |
this.setState({ | |
isChecked: !this.state.isChecked | |
}); | |
}, | |
render () { | |
return ( | |
<label> | |
<input type="checkbox" | |
checked={this.state.isChecked} | |
onChange={this.handleChange} /> | |
{this.state.isChecked ? this.props.labelOn : this.props.labelOff } | |
</label> | |
); | |
} | |
}); | |
module.exports = SwapCheckbox; |
If we'd like to avoid the previous construction, using mixins and relying on Proxy, we could simply check in our tests (supposing that we are actually implementing a reasonable coverage of tests):
it('should have implemented all propTypes',() => {
var instance = TestUtils.renderIntoDocument(
<SwapCheckbox labelOn="On"
labelOff="Off" />
);
var propTypes = Object.keys(instance.constructor.propTypes);
var not = Object.keys(instance.props).filter((elem) =>
!~propTypes.indexOf(elem));
expect(not.length).toEqual(0);
});
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Removing

labelOff
propType will lead our tests to fail (if running our tests withNODE_ENV=development ./node_modules/jest/bin/jest
), as expectedThe interesting part of this is that it makes cli-ready, which let's us automate the process of checking if we are defining properly the propTypes for our components