From d76262731237365198ddd84216d108da96820055 Mon Sep 17 00:00:00 2001 From: Paul O'Shannessy Date: Wed, 10 Jul 2013 14:45:16 -0700 Subject: [PATCH] Rename `props` to `propTypes` This does two things: - Rename `props` to `propTypes`. - Rename `ReactProps` to `ReactPropTypes` (and `React.Props` to `React.PropTypes`) --- src/core/React.js | 4 +- src/core/ReactCompositeComponent.js | 18 ++++----- src/core/{ReactProps.js => ReactPropTypes.js} | 12 +++--- .../__tests__/ReactCompositeComponent-test.js | 12 +++--- .../ReactCompositeComponentMixin-test.js | 40 ++++++++++++++++++- .../ReactCompositeComponentSpec-test.js | 8 ++-- ...ctProps-test.js => ReactPropTypes-test.js} | 2 +- 7 files changed, 67 insertions(+), 29 deletions(-) rename src/core/{ReactProps.js => ReactPropTypes.js} (95%) rename src/core/__tests__/{ReactProps-test.js => ReactPropTypes-test.js} (99%) diff --git a/src/core/React.js b/src/core/React.js index 7bdb3b39bd..1d7d9c3a0e 100644 --- a/src/core/React.js +++ b/src/core/React.js @@ -22,7 +22,7 @@ var ReactCompositeComponent = require('ReactCompositeComponent'); var ReactComponent = require('ReactComponent'); var ReactDOM = require('ReactDOM'); var ReactMount = require('ReactMount'); -var ReactProps = require('ReactProps'); +var ReactPropTypes = require('ReactPropTypes'); var ReactServerRendering = require('ReactServerRendering'); var ReactDefaultInjection = require('ReactDefaultInjection'); @@ -31,7 +31,7 @@ ReactDefaultInjection.inject(); var React = { DOM: ReactDOM, - Props: ReactProps, + PropTypes: ReactPropTypes, initializeTouchEvents: function(shouldUseTouch) { ReactMount.useTouchEvents = shouldUseTouch; }, diff --git a/src/core/ReactCompositeComponent.js b/src/core/ReactCompositeComponent.js index 95b1019fa7..03a3b0dc4e 100644 --- a/src/core/ReactCompositeComponent.js +++ b/src/core/ReactCompositeComponent.js @@ -81,12 +81,12 @@ var ReactCompositeComponentInterface = { mixins: SpecPolicy.DEFINE_MANY, /** - * Definition of props for this component. + * Definition of prop types for this component. * - * @type {array} + * @type {object} * @optional */ - props: SpecPolicy.DEFINE_ONCE, + propTypes: SpecPolicy.DEFINE_ONCE, @@ -278,8 +278,8 @@ var RESERVED_SPEC_KEYS = { } } }, - props: function(Constructor, props) { - Constructor.propDeclarations = props; + propTypes: function(Constructor, propTypes) { + Constructor.propTypes = propTypes; } }; @@ -602,11 +602,11 @@ var ReactCompositeComponentMixin = { props[propName] = defaultProps[propName]; } } - var propDeclarations = this.constructor.propDeclarations; - if (propDeclarations) { + var propTypes = this.constructor.propTypes; + if (propTypes) { var componentName = this.constructor.displayName; - for (propName in propDeclarations) { - var checkProp = propDeclarations[propName]; + for (propName in propTypes) { + var checkProp = propTypes[propName]; if (checkProp) { checkProp(props, propName, componentName); } diff --git a/src/core/ReactProps.js b/src/core/ReactPropTypes.js similarity index 95% rename from src/core/ReactProps.js rename to src/core/ReactPropTypes.js index 0a2c0d7c21..5857c8f0c0 100644 --- a/src/core/ReactProps.js +++ b/src/core/ReactPropTypes.js @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * @providesModule ReactProps + * @providesModule ReactPropTypes */ "use strict"; @@ -25,9 +25,9 @@ var invariant = require('invariant'); * Collection of methods that allow declaration and validation of props that are * supplied to React components. Example usage: * - * var Props = require('ReactProps'); + * var Props = require('ReactPropTypes'); * var MyArticle = React.createClass({ - * props: { + * propTypes: { * // An optional string prop named "description". * description: Props.string, * @@ -43,14 +43,14 @@ var invariant = require('invariant'); * A more formal specification of how these methods are used: * * type := array|bool|object|number|string|oneOf([...])|instanceOf(...) - * decl := ReactProps.{type}(.isRequired)? + * decl := ReactPropTypes.{type}(.isRequired)? * * Each and every declaration produces a function with the same signature. This * allows the creation of custom validation functions. For example: * - * var Props = require('ReactProps'); + * var Props = require('ReactPropTypes'); * var MyLink = React.createClass({ - * props: { + * propTypes: { * // An optional string or URI prop named "href". * href: function(props, propName, componentName) { * var propValue = props[propName]; diff --git a/src/core/__tests__/ReactCompositeComponent-test.js b/src/core/__tests__/ReactCompositeComponent-test.js index abbd7cf17f..b5e70a43dc 100644 --- a/src/core/__tests__/ReactCompositeComponent-test.js +++ b/src/core/__tests__/ReactCompositeComponent-test.js @@ -24,7 +24,7 @@ var MorphingAutoBindComponent; var ChildUpdates; var React; var ReactCurrentOwner; -var ReactProps; +var ReactPropTypes; var ReactTestUtils; var ReactID; var ReactDoNotBindDeprecated; @@ -40,7 +40,7 @@ describe('ReactCompositeComponent', function() { React = require('React'); ReactCurrentOwner = require('ReactCurrentOwner'); ReactDoNotBindDeprecated = require('ReactDoNotBindDeprecated'); - ReactProps = require('ReactProps'); + ReactPropTypes = require('ReactPropTypes'); ReactTestUtils = require('ReactTestUtils'); ReactID = require('ReactID'); @@ -220,7 +220,7 @@ describe('ReactCompositeComponent', function() { it('should normalize props with default values', function() { var Component = React.createClass({ - props: {key: ReactProps.string.isRequired}, + propTypes: {key: ReactPropTypes.string.isRequired}, getDefaultProps: function() { return {key: 'testKey'}; }, @@ -247,7 +247,7 @@ describe('ReactCompositeComponent', function() { it('should check default prop values', function() { var Component = React.createClass({ - props: {key: ReactProps.string.isRequired}, + propTypes: {key: ReactPropTypes.string.isRequired}, getDefaultProps: function() { return {key: null}; }, @@ -267,8 +267,8 @@ describe('ReactCompositeComponent', function() { it('should check declared prop types', function() { var Component = React.createClass({ - props: { - key: ReactProps.string.isRequired + propTypes: { + key: ReactPropTypes.string.isRequired }, render: function() { return {this.props.key}; diff --git a/src/core/__tests__/ReactCompositeComponentMixin-test.js b/src/core/__tests__/ReactCompositeComponentMixin-test.js index 06216f1ac9..3be64ca672 100644 --- a/src/core/__tests__/ReactCompositeComponentMixin-test.js +++ b/src/core/__tests__/ReactCompositeComponentMixin-test.js @@ -26,6 +26,9 @@ var ReactTestUtils; var reactComponentExpect; var TestComponent; +var TestComponentWithPropTypes; +var mixinPropValidator; +var componentPropValidator; describe('ReactCompositeComponent-mixin', function() { @@ -33,6 +36,8 @@ describe('ReactCompositeComponent-mixin', function() { React = require('React'); ReactTestUtils = require('ReactTestUtils'); reactComponentExpect = require('reactComponentExpect'); + mixinPropValidator = mocks.getMockFunction(); + componentPropValidator = mocks.getMockFunction(); var MixinA = { componentDidMount: function() { @@ -53,8 +58,14 @@ describe('ReactCompositeComponent-mixin', function() { } }; + var MixinD = { + propTypes: { + value: mixinPropValidator + } + }; + TestComponent = React.createClass({ - mixins: [MixinB, MixinC], + mixins: [MixinB, MixinC, MixinD], componentDidMount: function() { this.props.listener('Component didMount'); @@ -65,6 +76,15 @@ describe('ReactCompositeComponent-mixin', function() { } }); + TestComponentWithPropTypes = React.createClass({ + mixins: [MixinD], + propTypes: { + value: componentPropValidator + }, + render: function() { + return
; + } + }); }); it('should support chaining delegate functions', function() { @@ -79,4 +99,22 @@ describe('ReactCompositeComponent-mixin', function() { ['Component didMount'] ]); }); + + it('should validate prop types via mixins', function() { + expect(TestComponent.componentConstructor.propTypes).toBeDefined(); + expect(TestComponent.componentConstructor.propTypes.value) + .toBe(mixinPropValidator); + }); + + it('should override mixin prop types with class prop types', function() { + // Sanity check... + expect(componentPropValidator).toNotBe(mixinPropValidator); + // Actually check... + expect(TestComponentWithPropTypes.componentConstructor.propTypes) + .toBeDefined(); + expect(TestComponentWithPropTypes.componentConstructor.propTypes.value) + .toNotBe(mixinPropValidator); + expect(TestComponentWithPropTypes.componentConstructor.propTypes.value) + .toBe(componentPropValidator); + }); }); diff --git a/src/core/__tests__/ReactCompositeComponentSpec-test.js b/src/core/__tests__/ReactCompositeComponentSpec-test.js index bda8afbb93..92c6894cb5 100644 --- a/src/core/__tests__/ReactCompositeComponentSpec-test.js +++ b/src/core/__tests__/ReactCompositeComponentSpec-test.js @@ -53,10 +53,10 @@ describe('ReactCompositeComponent-spec', function() { .toBe('TestComponent'); }); - it('should copy prop declarations onto the Constructor', function() { + it('should copy prop types onto the Constructor', function() { var propValidator = mocks.getMockFunction(); var TestComponent = React.createClass({ - props: { + propTypes: { value: propValidator }, render: function() { @@ -64,8 +64,8 @@ describe('ReactCompositeComponent-spec', function() { } }); - expect(TestComponent.componentConstructor.propDeclarations).toBeDefined(); - expect(TestComponent.componentConstructor.propDeclarations.value) + expect(TestComponent.componentConstructor.propTypes).toBeDefined(); + expect(TestComponent.componentConstructor.propTypes.value) .toBe(propValidator); }); }); diff --git a/src/core/__tests__/ReactProps-test.js b/src/core/__tests__/ReactPropTypes-test.js similarity index 99% rename from src/core/__tests__/ReactProps-test.js rename to src/core/__tests__/ReactPropTypes-test.js index df9080ae3e..262711a352 100644 --- a/src/core/__tests__/ReactProps-test.js +++ b/src/core/__tests__/ReactPropTypes-test.js @@ -19,7 +19,7 @@ "use strict"; -var Props = require('ReactProps'); +var Props = require('ReactPropTypes'); function typeCheck(declaration, value) { var props = {};