createClass + PropTypes + checkPropTypes warnings (#9399)

(Temporarily) re-adds getters with deprecation warnings for React.PropTypes, React.checkPropTypes, and React.createClass.

* 08bd020: Replace all references to React.PropTypes with prop-types to avoid triggering our own warning message.
* ef5b5c6: Removed several references to React.createClass that appeared after rebasing this branch. (reviewed by @flarnie)
* 524ce20: Added getters for createClass and PropTypes to the main React isomorphic object, behind one-time warning messages. (reviewed by @spicyj)
* db48f54: Fixed Rollup bundles to inline 'prop-types' and 'create-react-class' for UMD builds only. (reviewed by @spicyj, @trueadm )
* cf49cfd: Updated tests-passing.txt to remove tests that were deleted in this branch.
* d34109a: Responses to PR feedback from @spicyj. (Added package.json dependencies to packages/react and packages/react-dom. Renamed a var. Expanded on an inline comment.)
* 488c8d2: Added warning for moved package to React.checkPropTypes accessor too and updated build script.
* 83bcb29: Wordsmithing for deprecation notices (added fb.me links).
* afdc9d2: Tweaked legacy module inlining to remove order-of-deps constraint
* d1348b9: Removed $FlowFixMe.
* 7dbc3e7: More wordsmithing of deprecation notices based on Dan's feedback.
This commit is contained in:
Brian Vaughn
2017-04-11 14:28:03 -07:00
committed by GitHub
parent aa1f8687d7
commit 2beec2f308
59 changed files with 710 additions and 1373 deletions
+40 -4
View File
@@ -20,6 +20,7 @@ var ReactVersion = require('ReactVersion');
var onlyChild = require('onlyChild');
var checkPropTypes = require('checkPropTypes');
var createReactClass = require('createClass');
var createElement = ReactElement.createElement;
var createFactory = ReactElement.createFactory;
@@ -56,11 +57,13 @@ var React = {
cloneElement: cloneElement,
isValidElement: ReactElement.isValidElement,
// TODO (bvaughn) Remove these getters in 16.0.0-alpha.10
PropTypes: ReactPropTypes,
checkPropTypes: checkPropTypes,
createClass: createReactClass,
// Classic
PropTypes: ReactPropTypes,
createFactory: createFactory,
createMixin: createMixin,
@@ -82,8 +85,10 @@ if (__DEV__) {
ReactDebugCurrentFrame: require('ReactDebugCurrentFrame'),
});
let warnedForCheckPropTypes = false;
let warnedForCreateMixin = false;
let warnedForCreateClass = false;
let warnedForPropTypes = false;
React.createMixin = function(mixin) {
warning(
@@ -95,18 +100,49 @@ if (__DEV__) {
return mixin;
};
// TODO (bvaughn) Remove both of these deprecation warnings in 16.0.0-alpha.10
if (canDefineProperty) {
Object.defineProperty(React, 'checkPropTypes', {
get() {
warning(
warnedForCheckPropTypes,
'checkPropTypes has been moved to a separate package. ' +
'Accessing React.checkPropTypes is no longer supported ' +
'and will be removed completely in React 16. ' +
'Use the prop-types package on npm instead. ' +
'(https://fb.me/migrating-from-react-proptypes)',
);
warnedForCheckPropTypes = true;
return ReactPropTypes;
},
});
Object.defineProperty(React, 'createClass', {
get: function() {
warning(
warnedForCreateClass,
'React.createClass is no longer supported. Use a plain JavaScript ' +
"class instead. If you're not yet ready to migrate, " +
'create-react-class is available on npm as a temporary, ' +
'drop-in replacement.',
'create-react-class is available on npm as a drop-in replacement. ' +
'(https://fb.me/migrating-from-react-create-class)',
);
warnedForCreateClass = true;
return undefined;
return createReactClass;
},
});
Object.defineProperty(React, 'PropTypes', {
get() {
warning(
warnedForPropTypes,
'PropTypes has been moved to a separate package. ' +
'Accessing React.PropTypes is no longer supported ' +
'and will be removed completely in React 16. ' +
'Use the prop-types package on npm instead. ' +
'(https://fb.me/migrating-from-react-proptypes)',
);
warnedForPropTypes = true;
return ReactPropTypes;
},
});
}
+35 -5
View File
@@ -32,13 +32,43 @@ describe('React', () => {
spyOn(console, 'error');
let createClass = React.createClass;
createClass = React.createClass;
expect(createClass).toBe(undefined);
expect(createClass).not.toBe(undefined);
expectDev(console.error.calls.count()).toBe(1);
expectDev(console.error.calls.argsFor(0)[0]).toContain(
'React.createClass is no longer supported. Use a plain ' +
"JavaScript class instead. If you're not yet ready to migrate, " +
'create-react-class is available on npm as a temporary, ' +
'drop-in replacement.',
'React.createClass is no longer supported. Use a plain JavaScript ' +
"class instead. If you're not yet ready to migrate, " +
'create-react-class is available on npm as a drop-in replacement. ' +
'(https://fb.me/migrating-from-react-create-class)',
);
});
it('should warn once when attempting to access React.PropTypes', () => {
spyOn(console, 'error');
let PropTypes = React.PropTypes;
PropTypes = React.PropTypes;
expect(PropTypes).not.toBe(undefined);
expectDev(console.error.calls.count()).toBe(1);
expectDev(console.error.calls.argsFor(0)[0]).toContain(
'PropTypes has been moved to a separate package. ' +
'Accessing React.PropTypes is no longer supported ' +
'and will be removed completely in React 16. ' +
'Use the prop-types package on npm instead. ' +
'(https://fb.me/migrating-from-react-proptypes)',
);
});
it('should warn once when attempting to access React.checkPropTypes', () => {
spyOn(console, 'error');
let checkPropTypes = React.checkPropTypes;
checkPropTypes = React.checkPropTypes;
expect(checkPropTypes).not.toBe(undefined);
expectDev(console.error.calls.count()).toBe(1);
expectDev(console.error.calls.argsFor(0)[0]).toContain(
'checkPropTypes has been moved to a separate package. ' +
'Accessing React.checkPropTypes is no longer supported ' +
'and will be removed completely in React 16. ' +
'Use the prop-types package on npm instead. ' +
'(https://fb.me/migrating-from-react-proptypes)',
);
});
});
@@ -17,6 +17,7 @@
'use strict';
var PropTypes;
var React;
var ReactDOM;
var ReactTestUtils;
@@ -29,6 +30,7 @@ describe('ReactContextValidator', () => {
beforeEach(() => {
jest.resetModules();
PropTypes = require('prop-types');
React = require('react');
ReactDOM = require('react-dom');
ReactTestUtils = require('ReactTestUtils');
@@ -44,7 +46,7 @@ describe('ReactContextValidator', () => {
}
}
Component.contextTypes = {
foo: React.PropTypes.string,
foo: PropTypes.string,
};
class ComponentInFooBarContext extends React.Component {
@@ -60,8 +62,8 @@ describe('ReactContextValidator', () => {
}
}
ComponentInFooBarContext.childContextTypes = {
foo: React.PropTypes.string,
bar: React.PropTypes.number,
foo: PropTypes.string,
bar: PropTypes.number,
};
var instance = ReactTestUtils.renderIntoDocument(
@@ -88,8 +90,8 @@ describe('ReactContextValidator', () => {
}
}
Parent.childContextTypes = {
foo: React.PropTypes.string.isRequired,
bar: React.PropTypes.string.isRequired,
foo: PropTypes.string.isRequired,
bar: PropTypes.string.isRequired,
};
class Component extends React.Component {
@@ -112,7 +114,7 @@ describe('ReactContextValidator', () => {
}
}
Component.contextTypes = {
foo: React.PropTypes.string,
foo: PropTypes.string,
};
var container = document.createElement('div');
@@ -139,8 +141,8 @@ describe('ReactContextValidator', () => {
}
}
Parent.childContextTypes = {
foo: React.PropTypes.string.isRequired,
bar: React.PropTypes.string.isRequired,
foo: PropTypes.string.isRequired,
bar: PropTypes.string.isRequired,
};
class Component extends React.Component {
@@ -153,7 +155,7 @@ describe('ReactContextValidator', () => {
}
}
Component.contextTypes = {
foo: React.PropTypes.string,
foo: PropTypes.string,
};
var container = document.createElement('div');
@@ -171,7 +173,7 @@ describe('ReactContextValidator', () => {
}
}
Component.contextTypes = {
foo: React.PropTypes.string.isRequired,
foo: PropTypes.string.isRequired,
};
ReactTestUtils.renderIntoDocument(<Component />);
@@ -196,7 +198,7 @@ describe('ReactContextValidator', () => {
}
}
ComponentInFooStringContext.childContextTypes = {
foo: React.PropTypes.string,
foo: PropTypes.string,
};
ReactTestUtils.renderIntoDocument(
@@ -218,7 +220,7 @@ describe('ReactContextValidator', () => {
}
}
ComponentInFooNumberContext.childContextTypes = {
foo: React.PropTypes.number,
foo: PropTypes.number,
};
ReactTestUtils.renderIntoDocument(
@@ -248,8 +250,8 @@ describe('ReactContextValidator', () => {
}
}
Component.childContextTypes = {
foo: React.PropTypes.string.isRequired,
bar: React.PropTypes.number,
foo: PropTypes.string.isRequired,
bar: PropTypes.number,
};
ReactTestUtils.renderIntoDocument(<Component testContext={{bar: 123}} />);
@@ -288,7 +290,7 @@ describe('ReactContextValidator', () => {
class ComponentA extends React.Component {
static childContextTypes = {
foo: React.PropTypes.string.isRequired,
foo: PropTypes.string.isRequired,
};
render() {
return <div />;
@@ -296,7 +298,7 @@ describe('ReactContextValidator', () => {
}
class ComponentB extends React.Component {
static childContextTypes = {
foo: React.PropTypes.string.isRequired,
foo: PropTypes.string.isRequired,
};
render() {
return <div />;
@@ -330,7 +332,7 @@ describe('ReactContextValidator', () => {
class ParentContextProvider extends React.Component {
static childContextTypes = {
foo: React.PropTypes.number,
foo: PropTypes.number,
};
getChildContext() {
return {
@@ -344,7 +346,7 @@ describe('ReactContextValidator', () => {
class MiddleMissingContext extends React.Component {
static childContextTypes = {
bar: React.PropTypes.string.isRequired,
bar: PropTypes.string.isRequired,
};
render() {
return <ChildContextConsumer />;
@@ -359,8 +361,8 @@ describe('ReactContextValidator', () => {
}
}
ChildContextConsumer.contextTypes = {
bar: React.PropTypes.string.isRequired,
foo: React.PropTypes.string.isRequired,
bar: PropTypes.string.isRequired,
foo: PropTypes.string.isRequired,
};
ReactTestUtils.renderIntoDocument(<ParentContextProvider />);
@@ -11,6 +11,7 @@
'use strict';
var PropTypes;
var React;
var ReactDOM;
var ReactTestUtils;
@@ -18,8 +19,9 @@ var createReactClass;
describe('create-react-class-integration', () => {
beforeEach(() => {
React = require('React');
ReactDOM = require('ReactDOM');
PropTypes = require('prop-types');
React = require('react');
ReactDOM = require('react-dom');
ReactTestUtils = require('ReactTestUtils');
var createReactClassFactory = require('create-react-class/factory');
createReactClass = createReactClassFactory(
@@ -188,13 +190,13 @@ describe('create-react-class-integration', () => {
createReactClass({
mixins: [{}],
propTypes: {
foo: React.PropTypes.string,
foo: PropTypes.string,
},
contextTypes: {
foo: React.PropTypes.string,
foo: PropTypes.string,
},
childContextTypes: {
foo: React.PropTypes.string,
foo: PropTypes.string,
},
render: function() {
return <div />;
@@ -268,7 +270,7 @@ describe('create-react-class-integration', () => {
it('renders based on context getInitialState', () => {
var Foo = createReactClass({
contextTypes: {
className: React.PropTypes.string,
className: PropTypes.string,
},
getInitialState() {
return {className: this.context.className};
@@ -280,7 +282,7 @@ describe('create-react-class-integration', () => {
var Outer = createReactClass({
childContextTypes: {
className: React.PropTypes.string,
className: PropTypes.string,
},
getChildContext() {
return {className: 'foo'};
@@ -0,0 +1,19 @@
/**
* Copyright 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule createClass
*/
'use strict';
var {Component} = require('ReactBaseClasses');
var {isValidElement} = require('ReactElement');
var ReactNoopUpdateQueue = require('ReactNoopUpdateQueue');
var factory = require('create-react-class/factory');
module.exports = factory(Component, isValidElement, ReactNoopUpdateQueue);
@@ -11,6 +11,7 @@
'use strict';
var PropTypes;
var React;
var ReactDOM;
var ReactTestUtils;
@@ -19,6 +20,7 @@ describe('ReactElementClone', () => {
var ComponentClass;
beforeEach(() => {
PropTypes = require('prop-types');
React = require('react');
ReactDOM = require('react-dom');
ReactTestUtils = require('ReactTestUtils');
@@ -288,13 +290,13 @@ describe('ReactElementClone', () => {
it('should check declared prop types after clone', () => {
spyOn(console, 'error');
class Component extends React.Component {
static propTypes = {
color: PropTypes.string.isRequired,
};
render() {
return React.createElement('div', null, 'My color is ' + this.color);
}
}
Component.propTypes = {
color: React.PropTypes.string.isRequired,
};
class Parent extends React.Component {
render() {
return React.cloneElement(this.props.child, {color: 123});
@@ -14,6 +14,7 @@
// NOTE: We're explicitly not using JSX in this file. This is intended to test
// classic JS without JSX.
var PropTypes;
var React;
var ReactDOM;
var ReactTestUtils;
@@ -28,6 +29,7 @@ describe('ReactElementValidator', () => {
beforeEach(() => {
jest.resetModules();
PropTypes = require('prop-types');
React = require('react');
ReactDOM = require('react-dom');
ReactTestUtils = require('ReactTestUtils');
@@ -247,7 +249,7 @@ describe('ReactElementValidator', () => {
return React.createElement('div', null, 'My color is ' + props.color);
}
MyComp.propTypes = {
color: React.PropTypes.string,
color: PropTypes.string,
};
function ParentComp() {
return React.createElement(MyComp, {color: 123});
@@ -332,12 +334,12 @@ describe('ReactElementValidator', () => {
spyOn(console, 'error');
class Component extends React.Component {
static propTypes = {prop: PropTypes.string.isRequired};
static defaultProps = {prop: null};
render() {
return React.createElement('span', null, this.props.prop);
}
}
Component.propTypes = {prop: React.PropTypes.string.isRequired};
Component.defaultProps = {prop: null};
ReactTestUtils.renderIntoDocument(React.createElement(Component));
@@ -353,12 +355,12 @@ describe('ReactElementValidator', () => {
spyOn(console, 'error');
class Component extends React.Component {
static propTypes = {prop: PropTypes.string.isRequired};
static defaultProps = {prop: 'text'};
render() {
return React.createElement('span', null, this.props.prop);
}
}
Component.propTypes = {prop: React.PropTypes.string.isRequired};
Component.defaultProps = {prop: 'text'};
ReactTestUtils.renderIntoDocument(
React.createElement(Component, {prop: null}),
@@ -376,13 +378,13 @@ describe('ReactElementValidator', () => {
spyOn(console, 'error');
class Component extends React.Component {
static propTypes = {
prop: PropTypes.string.isRequired,
};
render() {
return React.createElement('span', null, this.props.prop);
}
}
Component.propTypes = {
prop: React.PropTypes.string.isRequired,
};
ReactTestUtils.renderIntoDocument(React.createElement(Component));
ReactTestUtils.renderIntoDocument(
@@ -416,13 +418,13 @@ describe('ReactElementValidator', () => {
spyOn(console, 'error');
class Component extends React.Component {
static propTypes = {
myProp: PropTypes.shape,
};
render() {
return React.createElement('span', null, this.props.myProp.value);
}
}
Component.propTypes = {
myProp: React.PropTypes.shape,
};
ReactTestUtils.renderIntoDocument(
React.createElement(Component, {myProp: {value: 'hi'}}),
+3 -544
View File
@@ -11,548 +11,7 @@
'use strict';
var ReactElement = require('ReactElement');
var ReactPropTypesSecret = require('ReactPropTypesSecret');
var {isValidElement} = require('ReactElement');
var factory = require('prop-types/factory');
var emptyFunction = require('fbjs/lib/emptyFunction');
var getIteratorFn = require('getIteratorFn');
var invariant = require('fbjs/lib/invariant');
var warning = require('fbjs/lib/warning');
/**
* Collection of methods that allow declaration and validation of props that are
* supplied to React components. Example usage:
*
* var Props = require('ReactPropTypes');
* var MyArticle = React.createClass({
* propTypes: {
* // An optional string prop named "description".
* description: Props.string,
*
* // A required enum prop named "category".
* category: Props.oneOf(['News','Photos']).isRequired,
*
* // A prop named "dialog" that requires an instance of Dialog.
* dialog: Props.instanceOf(Dialog).isRequired
* },
* render: function() { ... }
* });
*
* A more formal specification of how these methods are used:
*
* type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...)
* 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 MyLink = React.createClass({
* propTypes: {
* // An optional string or URI prop named "href".
* href: function(props, propName, componentName) {
* var propValue = props[propName];
* if (propValue != null && typeof propValue !== 'string' &&
* !(propValue instanceof URI)) {
* return new Error(
* 'Expected a string or an URI for ' + propName + ' in ' +
* componentName
* );
* }
* }
* },
* render: function() {...}
* });
*
* @internal
*/
var ANONYMOUS = '<<anonymous>>';
var ReactPropTypes;
if (__DEV__) {
// Keep in sync with production version below
ReactPropTypes = {
array: createPrimitiveTypeChecker('array'),
bool: createPrimitiveTypeChecker('boolean'),
func: createPrimitiveTypeChecker('function'),
number: createPrimitiveTypeChecker('number'),
object: createPrimitiveTypeChecker('object'),
string: createPrimitiveTypeChecker('string'),
symbol: createPrimitiveTypeChecker('symbol'),
any: createAnyTypeChecker(),
arrayOf: createArrayOfTypeChecker,
element: createElementTypeChecker(),
instanceOf: createInstanceTypeChecker,
node: createNodeChecker(),
objectOf: createObjectOfTypeChecker,
oneOf: createEnumTypeChecker,
oneOfType: createUnionTypeChecker,
shape: createShapeTypeChecker,
};
} else {
var productionTypeChecker = function() {
invariant(
false,
'React.PropTypes type checking code is stripped in production.',
);
};
productionTypeChecker.isRequired = productionTypeChecker;
var getProductionTypeChecker = () => productionTypeChecker;
// Keep in sync with development version above
ReactPropTypes = {
array: productionTypeChecker,
bool: productionTypeChecker,
func: productionTypeChecker,
number: productionTypeChecker,
object: productionTypeChecker,
string: productionTypeChecker,
symbol: productionTypeChecker,
any: productionTypeChecker,
arrayOf: getProductionTypeChecker,
element: productionTypeChecker,
instanceOf: getProductionTypeChecker,
node: productionTypeChecker,
objectOf: getProductionTypeChecker,
oneOf: getProductionTypeChecker,
oneOfType: getProductionTypeChecker,
shape: getProductionTypeChecker,
};
}
/**
* inlined Object.is polyfill to avoid requiring consumers ship their own
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
*/
/*eslint-disable no-self-compare*/
function is(x, y) {
// SameValue algorithm
if (x === y) {
// Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
return x !== 0 || 1 / x === 1 / y;
} else {
// Step 6.a: NaN == NaN
return x !== x && y !== y;
}
}
/*eslint-enable no-self-compare*/
/**
* We use an Error-like object for backward compatibility as people may call
* PropTypes directly and inspect their output. However, we don't use real
* Errors anymore. We don't inspect their stack anyway, and creating them
* is prohibitively expensive if they are created too often, such as what
* happens in oneOfType() for any type before the one that matched.
*/
function PropTypeError(message) {
this.message = message;
this.stack = '';
}
// Make `instanceof Error` still work for returned errors.
PropTypeError.prototype = Error.prototype;
function createChainableTypeChecker(validate) {
if (__DEV__) {
var manualPropTypeCallCache = {};
}
function checkType(
isRequired,
props,
propName,
componentName,
location,
propFullName,
secret,
) {
componentName = componentName || ANONYMOUS;
propFullName = propFullName || propName;
if (__DEV__) {
if (secret !== ReactPropTypesSecret && typeof console !== 'undefined') {
var cacheKey = `${componentName}:${propName}`;
if (!manualPropTypeCallCache[cacheKey]) {
warning(
false,
'You are manually calling a React.PropTypes validation ' +
'function for the `%s` prop on `%s`. This is deprecated ' +
'and will not work in production with the next major version. ' +
'You may be seeing this warning due to a third-party PropTypes ' +
'library. See https://fb.me/react-warning-dont-call-proptypes ' +
'for details.',
propFullName,
componentName,
);
manualPropTypeCallCache[cacheKey] = true;
}
}
}
if (props[propName] == null) {
if (isRequired) {
if (props[propName] === null) {
return new PropTypeError(
`The ${location} \`${propFullName}\` is marked as required ` +
`in \`${componentName}\`, but its value is \`null\`.`,
);
}
return new PropTypeError(
`The ${location} \`${propFullName}\` is marked as required in ` +
`\`${componentName}\`, but its value is \`undefined\`.`,
);
}
return null;
} else {
return validate(props, propName, componentName, location, propFullName);
}
}
var chainedCheckType = checkType.bind(null, false);
chainedCheckType.isRequired = checkType.bind(null, true);
return chainedCheckType;
}
function createPrimitiveTypeChecker(expectedType) {
function validate(
props,
propName,
componentName,
location,
propFullName,
secret,
) {
var propValue = props[propName];
var propType = getPropType(propValue);
if (propType !== expectedType) {
// `propValue` being instance of, say, date/regexp, pass the 'object'
// check, but we can offer a more precise error message here rather than
// 'of type `object`'.
var preciseType = getPreciseType(propValue);
return new PropTypeError(
`Invalid ${location} \`${propFullName}\` of type ` +
`\`${preciseType}\` supplied to \`${componentName}\`, expected ` +
`\`${expectedType}\`.`,
);
}
return null;
}
return createChainableTypeChecker(validate);
}
function createAnyTypeChecker() {
return createChainableTypeChecker(emptyFunction.thatReturnsNull);
}
function createArrayOfTypeChecker(typeChecker) {
function validate(props, propName, componentName, location, propFullName) {
if (typeof typeChecker !== 'function') {
return new PropTypeError(
`Property \`${propFullName}\` of component \`${componentName}\` has invalid PropType notation inside arrayOf.`,
);
}
var propValue = props[propName];
if (!Array.isArray(propValue)) {
var propType = getPropType(propValue);
return new PropTypeError(
`Invalid ${location} \`${propFullName}\` of type ` +
`\`${propType}\` supplied to \`${componentName}\`, expected an array.`,
);
}
for (var i = 0; i < propValue.length; i++) {
var error = typeChecker(
propValue,
i,
componentName,
location,
`${propFullName}[${i}]`,
ReactPropTypesSecret,
);
if (error instanceof Error) {
return error;
}
}
return null;
}
return createChainableTypeChecker(validate);
}
function createElementTypeChecker() {
function validate(props, propName, componentName, location, propFullName) {
var propValue = props[propName];
if (!ReactElement.isValidElement(propValue)) {
var propType = getPropType(propValue);
return new PropTypeError(
`Invalid ${location} \`${propFullName}\` of type ` +
`\`${propType}\` supplied to \`${componentName}\`, expected a single ReactElement.`,
);
}
return null;
}
return createChainableTypeChecker(validate);
}
function createInstanceTypeChecker(expectedClass) {
function validate(props, propName, componentName, location, propFullName) {
if (!(props[propName] instanceof expectedClass)) {
var expectedClassName = expectedClass.name || ANONYMOUS;
var actualClassName = getClassName(props[propName]);
return new PropTypeError(
`Invalid ${location} \`${propFullName}\` of type ` +
`\`${actualClassName}\` supplied to \`${componentName}\`, expected ` +
`instance of \`${expectedClassName}\`.`,
);
}
return null;
}
return createChainableTypeChecker(validate);
}
function createEnumTypeChecker(expectedValues) {
if (!Array.isArray(expectedValues)) {
warning(
false,
'Invalid argument supplied to oneOf, expected an instance of array.',
);
return emptyFunction.thatReturnsNull;
}
function validate(props, propName, componentName, location, propFullName) {
var propValue = props[propName];
for (var i = 0; i < expectedValues.length; i++) {
if (is(propValue, expectedValues[i])) {
return null;
}
}
var valuesString = JSON.stringify(expectedValues);
return new PropTypeError(
`Invalid ${location} \`${propFullName}\` of value \`${propValue}\` ` +
`supplied to \`${componentName}\`, expected one of ${valuesString}.`,
);
}
return createChainableTypeChecker(validate);
}
function createObjectOfTypeChecker(typeChecker) {
function validate(props, propName, componentName, location, propFullName) {
if (typeof typeChecker !== 'function') {
return new PropTypeError(
`Property \`${propFullName}\` of component \`${componentName}\` has invalid PropType notation inside objectOf.`,
);
}
var propValue = props[propName];
var propType = getPropType(propValue);
if (propType !== 'object') {
return new PropTypeError(
`Invalid ${location} \`${propFullName}\` of type ` +
`\`${propType}\` supplied to \`${componentName}\`, expected an object.`,
);
}
for (var key in propValue) {
if (propValue.hasOwnProperty(key)) {
var error = typeChecker(
propValue,
key,
componentName,
location,
`${propFullName}.${key}`,
ReactPropTypesSecret,
);
if (error instanceof Error) {
return error;
}
}
}
return null;
}
return createChainableTypeChecker(validate);
}
function createUnionTypeChecker(arrayOfTypeCheckers) {
if (!Array.isArray(arrayOfTypeCheckers)) {
warning(
false,
'Invalid argument supplied to oneOfType, expected an instance of array.',
);
return emptyFunction.thatReturnsNull;
}
function validate(props, propName, componentName, location, propFullName) {
for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
var checker = arrayOfTypeCheckers[i];
if (
checker(
props,
propName,
componentName,
location,
propFullName,
ReactPropTypesSecret,
) == null
) {
return null;
}
}
return new PropTypeError(
`Invalid ${location} \`${propFullName}\` supplied to ` +
`\`${componentName}\`.`,
);
}
return createChainableTypeChecker(validate);
}
function createNodeChecker() {
function validate(props, propName, componentName, location, propFullName) {
if (!isNode(props[propName])) {
return new PropTypeError(
`Invalid ${location} \`${propFullName}\` supplied to ` +
`\`${componentName}\`, expected a ReactNode.`,
);
}
return null;
}
return createChainableTypeChecker(validate);
}
function createShapeTypeChecker(shapeTypes) {
function validate(props, propName, componentName, location, propFullName) {
var propValue = props[propName];
var propType = getPropType(propValue);
if (propType !== 'object') {
return new PropTypeError(
`Invalid ${location} \`${propFullName}\` of type \`${propType}\` ` +
`supplied to \`${componentName}\`, expected \`object\`.`,
);
}
for (var key in shapeTypes) {
var checker = shapeTypes[key];
if (!checker) {
continue;
}
var error = checker(
propValue,
key,
componentName,
location,
`${propFullName}.${key}`,
ReactPropTypesSecret,
);
if (error) {
return error;
}
}
return null;
}
return createChainableTypeChecker(validate);
}
function isNode(propValue) {
switch (typeof propValue) {
case 'number':
case 'string':
case 'undefined':
return true;
case 'boolean':
return !propValue;
case 'object':
if (Array.isArray(propValue)) {
return propValue.every(isNode);
}
if (propValue === null || ReactElement.isValidElement(propValue)) {
return true;
}
var iteratorFn = getIteratorFn(propValue);
if (iteratorFn) {
var iterator = iteratorFn.call(propValue);
var step;
if (iteratorFn !== propValue.entries) {
while (!(step = iterator.next()).done) {
if (!isNode(step.value)) {
return false;
}
}
} else {
// Iterator will provide entry [k,v] tuples rather than values.
while (!(step = iterator.next()).done) {
var entry = step.value;
if (entry) {
if (!isNode(entry[1])) {
return false;
}
}
}
}
} else {
return false;
}
return true;
default:
return false;
}
}
function isSymbol(propType, propValue) {
// Native Symbol.
if (propType === 'symbol') {
return true;
}
// 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol'
if (propValue['@@toStringTag'] === 'Symbol') {
return true;
}
// Fallback for non-spec compliant Symbols which are polyfilled.
if (typeof Symbol === 'function' && propValue instanceof Symbol) {
return true;
}
return false;
}
// Equivalent of `typeof` but with special handling for array and regexp.
function getPropType(propValue) {
var propType = typeof propValue;
if (Array.isArray(propValue)) {
return 'array';
}
if (propValue instanceof RegExp) {
// Old webkits (at least until Android 4.0) return 'function' rather than
// 'object' for typeof a RegExp. We'll normalize this here so that /bla/
// passes PropTypes.object.
return 'object';
}
if (isSymbol(propType, propValue)) {
return 'symbol';
}
return propType;
}
// This handles more types than `getPropType`. Only used for error messages.
// See `createPrimitiveTypeChecker`.
function getPreciseType(propValue) {
var propType = getPropType(propValue);
if (propType === 'object') {
if (propValue instanceof Date) {
return 'date';
} else if (propValue instanceof RegExp) {
return 'regexp';
}
}
return propType;
}
// Returns class name of the object, if any.
function getClassName(propValue) {
if (!propValue.constructor || !propValue.constructor.name) {
return ANONYMOUS;
}
return propValue.constructor.name;
}
module.exports = ReactPropTypes;
module.exports = factory(isValidElement);
@@ -1,219 +0,0 @@
/**
* Copyright 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @emails react-core
*/
'use strict';
describe('ReactPropTypesProduction', function() {
var PropTypes;
var React;
var ReactTestUtils;
var oldProcess;
beforeEach(function() {
__DEV__ = false;
// Mutating process.env.NODE_ENV would cause our babel plugins to do the
// wrong thing. If you change this, make sure to test with jest --no-cache.
oldProcess = process;
global.process = {
...process,
env: {...process.env, NODE_ENV: 'production'},
};
jest.resetModules();
PropTypes = require('ReactPropTypes');
React = require('react');
ReactTestUtils = require('ReactTestUtils');
});
afterEach(function() {
__DEV__ = true;
global.process = oldProcess;
});
function expectThrowsInProduction(declaration, value) {
var props = {testProp: value};
expect(() => {
declaration(props, 'testProp', 'testComponent', 'prop');
}).toThrowError('Minified React error #144');
}
describe('Primitive Types', function() {
it('should be a no-op', function() {
expectThrowsInProduction(PropTypes.array, /please/);
expectThrowsInProduction(PropTypes.array.isRequired, /please/);
expectThrowsInProduction(PropTypes.array.isRequired, null);
expectThrowsInProduction(PropTypes.array.isRequired, undefined);
expectThrowsInProduction(PropTypes.bool, []);
expectThrowsInProduction(PropTypes.bool.isRequired, []);
expectThrowsInProduction(PropTypes.bool.isRequired, null);
expectThrowsInProduction(PropTypes.bool.isRequired, undefined);
expectThrowsInProduction(PropTypes.func, false);
expectThrowsInProduction(PropTypes.func.isRequired, false);
expectThrowsInProduction(PropTypes.func.isRequired, null);
expectThrowsInProduction(PropTypes.func.isRequired, undefined);
expectThrowsInProduction(PropTypes.number, function() {});
expectThrowsInProduction(PropTypes.number.isRequired, function() {});
expectThrowsInProduction(PropTypes.number.isRequired, null);
expectThrowsInProduction(PropTypes.number.isRequired, undefined);
expectThrowsInProduction(PropTypes.string, 0);
expectThrowsInProduction(PropTypes.string.isRequired, 0);
expectThrowsInProduction(PropTypes.string.isRequired, null);
expectThrowsInProduction(PropTypes.string.isRequired, undefined);
expectThrowsInProduction(PropTypes.symbol, 0);
expectThrowsInProduction(PropTypes.symbol.isRequired, 0);
expectThrowsInProduction(PropTypes.symbol.isRequired, null);
expectThrowsInProduction(PropTypes.symbol.isRequired, undefined);
expectThrowsInProduction(PropTypes.object, '');
expectThrowsInProduction(PropTypes.object.isRequired, '');
expectThrowsInProduction(PropTypes.object.isRequired, null);
expectThrowsInProduction(PropTypes.object.isRequired, undefined);
});
});
describe('Any Type', function() {
it('should be a no-op', function() {
expectThrowsInProduction(PropTypes.any, null);
expectThrowsInProduction(PropTypes.any.isRequired, null);
expectThrowsInProduction(PropTypes.any.isRequired, undefined);
});
});
describe('ArrayOf Type', function() {
it('should be a no-op', function() {
expectThrowsInProduction(PropTypes.arrayOf({foo: PropTypes.string}), {
foo: 'bar',
});
expectThrowsInProduction(PropTypes.arrayOf(PropTypes.number), [
1,
2,
'b',
]);
expectThrowsInProduction(PropTypes.arrayOf(PropTypes.number), {
'0': 'maybe-array',
length: 1,
});
expectThrowsInProduction(
PropTypes.arrayOf(PropTypes.number).isRequired,
null,
);
expectThrowsInProduction(
PropTypes.arrayOf(PropTypes.number).isRequired,
undefined,
);
});
});
describe('Component Type', function() {
it('should be a no-op', function() {
expectThrowsInProduction(PropTypes.element, [<div />, <div />]);
expectThrowsInProduction(PropTypes.element, 123);
expectThrowsInProduction(PropTypes.element, 'foo');
expectThrowsInProduction(PropTypes.element, false);
expectThrowsInProduction(PropTypes.element.isRequired, null);
expectThrowsInProduction(PropTypes.element.isRequired, undefined);
});
});
describe('Instance Types', function() {
it('should be a no-op', function() {
expectThrowsInProduction(PropTypes.instanceOf(Date), {});
expectThrowsInProduction(PropTypes.instanceOf(Date).isRequired, {});
});
});
describe('React Component Types', function() {
it('should be a no-op', function() {
expectThrowsInProduction(PropTypes.node, {});
expectThrowsInProduction(PropTypes.node.isRequired, null);
expectThrowsInProduction(PropTypes.node.isRequired, undefined);
});
});
describe('ObjectOf Type', function() {
it('should be a no-op', function() {
expectThrowsInProduction(PropTypes.objectOf({foo: PropTypes.string}), {
foo: 'bar',
});
expectThrowsInProduction(PropTypes.objectOf(PropTypes.number), {
a: 1,
b: 2,
c: 'b',
});
expectThrowsInProduction(PropTypes.objectOf(PropTypes.number), [1, 2]);
expectThrowsInProduction(PropTypes.objectOf(PropTypes.number), null);
expectThrowsInProduction(PropTypes.objectOf(PropTypes.number), undefined);
});
});
describe('OneOf Types', function() {
it('should be a no-op', function() {
expectThrowsInProduction(PropTypes.oneOf('red', 'blue'), 'red');
expectThrowsInProduction(PropTypes.oneOf(['red', 'blue']), true);
expectThrowsInProduction(PropTypes.oneOf(['red', 'blue']), null);
expectThrowsInProduction(PropTypes.oneOf(['red', 'blue']), undefined);
});
});
describe('Union Types', function() {
it('should be a no-op', function() {
expectThrowsInProduction(
PropTypes.oneOfType(PropTypes.string, PropTypes.number),
'red',
);
expectThrowsInProduction(
PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
[],
);
expectThrowsInProduction(
PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
null,
);
expectThrowsInProduction(
PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
undefined,
);
});
});
describe('Shape Types', function() {
it('should be a no-op', function() {
expectThrowsInProduction(PropTypes.shape({}), 'some string');
expectThrowsInProduction(
PropTypes.shape({key: PropTypes.number}).isRequired,
null,
);
expectThrowsInProduction(
PropTypes.shape({key: PropTypes.number}).isRequired,
undefined,
);
});
});
describe('Custom validator', function() {
beforeEach(function() {
jest.resetModules();
});
it('should not have been called', function() {
var spy = jest.fn();
function Component() {
return <div />;
}
Component.propTypes = {num: spy};
var instance = <Component num={5} />;
ReactTestUtils.renderIntoDocument(instance);
expect(spy).not.toBeCalled();
});
});
});
+1 -81
View File
@@ -11,84 +11,4 @@
'use strict';
var ReactPropTypesSecret = require('ReactPropTypesSecret');
var invariant = require('fbjs/lib/invariant');
var warning = require('fbjs/lib/warning');
var loggedTypeFailures = {};
/**
* Assert that the values match with the type specs.
* Error messages are memorized and will only be shown once.
*
* @param {object} typeSpecs Map of name to a ReactPropType
* @param {object} values Runtime values that need to be type-checked
* @param {string} location e.g. "prop", "context", "child context"
* @param {string} componentName Name of the component for error messages.
* @param {?Function} getStack Returns the component stack.
* @private
*/
function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
if (__DEV__) {
for (var typeSpecName in typeSpecs) {
if (typeSpecs.hasOwnProperty(typeSpecName)) {
var error;
// Prop type validation may throw. In case they do, we don't want to
// fail the render phase where it didn't fail before. So we log it.
// After these have been cleaned up, we'll let them throw.
try {
// This is intentionally an invariant that gets caught. It's the same
// behavior as without this statement except with a better message.
invariant(
typeof typeSpecs[typeSpecName] === 'function',
'%s: %s type `%s` is invalid; it must be a function, usually from ' +
'React.PropTypes.',
componentName || 'React class',
location,
typeSpecName,
);
error = typeSpecs[typeSpecName](
values,
typeSpecName,
componentName,
location,
null,
ReactPropTypesSecret,
);
} catch (ex) {
error = ex;
}
warning(
!error || error instanceof Error,
'%s: type specification of %s `%s` is invalid; the type checker ' +
'function must return `null` or an `Error` but returned a %s. ' +
'You may have forgotten to pass an argument to the type checker ' +
'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
'shape all require an argument).',
componentName || 'React class',
location,
typeSpecName,
typeof error,
);
if (error instanceof Error && !(error.message in loggedTypeFailures)) {
// Only monitor this failure once because there tends to be a lot of the
// same error.
loggedTypeFailures[error.message] = true;
var stack = getStack ? getStack() : '';
warning(
false,
'Failed %s type: %s%s',
location,
error.message,
stack != null ? stack : '',
);
}
}
}
}
}
module.exports = checkPropTypes;
module.exports = require('prop-types/checkPropTypes');
+19
View File
@@ -0,0 +1,19 @@
/*!
* Copyright 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
/**
* TypeScript Definition File for React.
*
* Full type definitions are not yet officially supported. These are mostly
* just helpers for the unit test.
*/
declare module 'prop-types' {
export var string : any;
}
@@ -9,6 +9,7 @@ of patent rights can be found in the PATENTS file in the same directory.
React = null
ReactDOM = null
PropTypes = null
describe 'ReactCoffeeScriptClass', ->
div = null
@@ -21,6 +22,7 @@ describe 'ReactCoffeeScriptClass', ->
beforeEach ->
React = require 'react'
ReactDOM = require 'react-dom'
PropTypes = require 'prop-types'
container = document.createElement 'div'
attachedListener = null
renderedName = null
@@ -102,8 +104,8 @@ describe 'ReactCoffeeScriptClass', ->
it 'renders based on context in the constructor', ->
class Foo extends React.Component
@contextTypes:
tag: React.PropTypes.string
className: React.PropTypes.string
tag: PropTypes.string
className: PropTypes.string
constructor: (props, context) ->
super props, context
@@ -118,8 +120,8 @@ describe 'ReactCoffeeScriptClass', ->
class Outer extends React.Component
@childContextTypes:
tag: React.PropTypes.string
className: React.PropTypes.string
tag: PropTypes.string
className: PropTypes.string
getChildContext: ->
tag: 'span'
@@ -393,13 +395,13 @@ describe 'ReactCoffeeScriptClass', ->
it 'supports this.context passed via getChildContext', ->
class Bar extends React.Component
@contextTypes:
bar: React.PropTypes.string
bar: PropTypes.string
render: ->
div className: @context.bar
class Foo extends React.Component
@childContextTypes:
bar: React.PropTypes.string
bar: PropTypes.string
getChildContext: ->
bar: 'bar-through-context'
render: ->
@@ -11,6 +11,7 @@
'use strict';
var PropTypes;
var React;
var ReactDOM;
@@ -25,6 +26,7 @@ describe('ReactES6Class', () => {
var renderedName = null;
beforeEach(() => {
PropTypes = require('prop-types');
React = require('react');
ReactDOM = require('react-dom');
container = document.createElement('div');
@@ -123,8 +125,8 @@ describe('ReactES6Class', () => {
}
}
Foo.contextTypes = {
tag: React.PropTypes.string,
className: React.PropTypes.string,
tag: PropTypes.string,
className: PropTypes.string,
};
class Outer extends React.Component {
@@ -136,8 +138,8 @@ describe('ReactES6Class', () => {
}
}
Outer.childContextTypes = {
tag: React.PropTypes.string,
className: React.PropTypes.string,
tag: PropTypes.string,
className: PropTypes.string,
};
test(<Outer />, 'SPAN', 'foo');
});
@@ -419,7 +421,7 @@ describe('ReactES6Class', () => {
return <div className={this.context.bar} />;
}
}
Bar.contextTypes = {bar: React.PropTypes.string};
Bar.contextTypes = {bar: PropTypes.string};
class Foo extends React.Component {
getChildContext() {
return {bar: 'bar-through-context'};
@@ -428,7 +430,7 @@ describe('ReactES6Class', () => {
return <Bar />;
}
}
Foo.childContextTypes = {bar: React.PropTypes.string};
Foo.childContextTypes = {bar: PropTypes.string};
test(<Foo />, 'DIV', 'bar-through-context');
});
@@ -1,3 +1,4 @@
/// <reference path="../PropTypes.d.ts" />
/// <reference path="../React.d.ts" />
/// <reference path="../ReactDOM.d.ts" />
@@ -12,6 +13,7 @@
import React = require('react');
import ReactDOM = require('react-dom');
import PropTypes = require('prop-types');
// Before Each
@@ -85,8 +87,8 @@ class StateBasedOnProps extends React.Component {
// it renders based on context in the constructor
class StateBasedOnContext extends React.Component {
static contextTypes = {
tag: React.PropTypes.string,
className: React.PropTypes.string
tag: PropTypes.string,
className: PropTypes.string
};
state = {
tag: this.context.tag,
@@ -100,8 +102,8 @@ class StateBasedOnContext extends React.Component {
class ProvideChildContextTypes extends React.Component {
static childContextTypes = {
tag: React.PropTypes.string,
className: React.PropTypes.string
tag: PropTypes.string,
className: PropTypes.string
};
getChildContext() {
return { tag: 'span', className: 'foo' };
@@ -278,13 +280,13 @@ class MisspelledComponent2 extends React.Component {
// it supports this.context passed via getChildContext
class ReadContext extends React.Component {
static contextTypes = { bar: React.PropTypes.string };
static contextTypes = { bar: PropTypes.string };
render() {
return React.createElement('div', { className: this.context.bar });
}
}
class ProvideContext extends React.Component {
static childContextTypes = { bar: React.PropTypes.string };
static childContextTypes = { bar: PropTypes.string };
getChildContext() {
return { bar: 'bar-through-context' };
}
@@ -17,6 +17,7 @@
var React;
var ReactDOM;
var ReactTestUtils;
var PropTypes;
describe('ReactJSXElementValidator', () => {
function normalizeCodeLocInfo(str) {
@@ -29,6 +30,7 @@ describe('ReactJSXElementValidator', () => {
beforeEach(() => {
jest.resetModules();
PropTypes = require('prop-types');
React = require('react');
ReactDOM = require('react-dom');
ReactTestUtils = require('ReactTestUtils');
@@ -45,7 +47,7 @@ describe('ReactJSXElementValidator', () => {
}
};
RequiredPropComponent.displayName = 'RequiredPropComponent';
RequiredPropComponent.propTypes = {prop: React.PropTypes.string.isRequired};
RequiredPropComponent.propTypes = {prop: PropTypes.string.isRequired};
});
it('warns for keys for arrays of elements in children position', () => {
@@ -188,7 +190,7 @@ describe('ReactJSXElementValidator', () => {
}
}
MyComp.propTypes = {
color: React.PropTypes.string,
color: PropTypes.string,
};
class ParentComp extends React.Component {
render() {
@@ -211,7 +213,7 @@ describe('ReactJSXElementValidator', () => {
return null;
}
MyComp.propTypes = {
color: React.PropTypes.string,
color: PropTypes.string,
};
function MiddleComp(props) {
return <MyComp color={props.color} />;
@@ -14,6 +14,7 @@
var React;
var ReactDOM;
var ReactTestUtils;
var PropTypes;
var clone = function(o) {
return JSON.parse(JSON.stringify(o));
@@ -91,6 +92,7 @@ describe('ReactComponentLifeCycle', () => {
React = require('react');
ReactDOM = require('react-dom');
ReactTestUtils = require('ReactTestUtils');
PropTypes = require('prop-types');
});
it('should not reuse an instance when it has been unmounted', () => {
@@ -605,14 +607,14 @@ describe('ReactComponentLifeCycle', () => {
};
}
Parent.childContextTypes = {
x: React.PropTypes.number,
x: PropTypes.number,
};
function Child(props, context) {
expect(context.x).toBe(2);
return <div />;
}
Child.contextTypes = {
x: React.PropTypes.number,
x: PropTypes.number,
};
const div = document.createElement('div');
@@ -29,10 +29,12 @@ describeStack('ReactComponentTreeHook', () => {
var View;
var Image;
var Text;
var PropTypes;
beforeEach(() => {
jest.resetModules();
PropTypes = require('prop-types');
React = require('react');
ReactNative = require('ReactNative');
ReactInstanceMap = require('ReactInstanceMap');
@@ -50,7 +52,7 @@ describeStack('ReactComponentTreeHook', () => {
});
Text = class extends React.Component {
static childContextTypes = {
isInAParentText: React.PropTypes.bool,
isInAParentText: PropTypes.bool,
};
getChildContext() {
@@ -13,6 +13,7 @@
var ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
var PropTypes;
var React;
var ReactDOM;
@@ -37,6 +38,7 @@ describe('ReactErrorBoundaries', () => {
var Normal;
beforeEach(() => {
PropTypes = require('prop-types');
ReactDOM = require('react-dom');
React = require('react');
@@ -737,7 +739,7 @@ describe('ReactErrorBoundaries', () => {
it('renders an error state if context provider throws in componentWillMount', () => {
class BrokenComponentWillMountWithContext extends React.Component {
static childContextTypes = {foo: React.PropTypes.number};
static childContextTypes = {foo: PropTypes.number};
getChildContext() {
return {foo: 42};
}
@@ -774,7 +776,7 @@ describe('ReactErrorBoundaries', () => {
};
}
BrokenComponentWillMountWithContext.childContextTypes = {
foo: React.PropTypes.number,
foo: PropTypes.number,
};
var container = document.createElement('div');
@@ -11,6 +11,7 @@
'use strict';
var PropTypes;
var React;
var ReactDOM;
var ReactTestUtils;
@@ -28,6 +29,7 @@ describe('ReactStatelessComponent', () => {
beforeEach(() => {
jest.resetModuleRegistry();
PropTypes = require('prop-types');
React = require('react');
ReactDOM = require('react-dom');
ReactTestUtils = require('ReactTestUtils');
@@ -68,7 +70,7 @@ describe('ReactStatelessComponent', () => {
it('should pass context thru stateless component', () => {
class Child extends React.Component {
static contextTypes = {
test: React.PropTypes.string.isRequired,
test: PropTypes.string.isRequired,
};
render() {
@@ -82,7 +84,7 @@ describe('ReactStatelessComponent', () => {
class GrandParent extends React.Component {
static childContextTypes = {
test: React.PropTypes.string.isRequired,
test: PropTypes.string.isRequired,
};
getChildContext() {
@@ -111,7 +113,7 @@ describe('ReactStatelessComponent', () => {
}
StatelessComponentWithChildContext.childContextTypes = {
foo: React.PropTypes.string,
foo: PropTypes.string,
};
var container = document.createElement('div');
@@ -355,7 +357,7 @@ describe('ReactStatelessComponent', () => {
return <div>{props.test}</div>;
}
Child.defaultProps = {test: 2};
Child.propTypes = {test: React.PropTypes.string};
Child.propTypes = {test: PropTypes.string};
spyOn(console, 'error');
ReactTestUtils.renderIntoDocument(<Child />);
@@ -372,7 +374,7 @@ describe('ReactStatelessComponent', () => {
it('should receive context', () => {
class Parent extends React.Component {
static childContextTypes = {
lang: React.PropTypes.string,
lang: PropTypes.string,
};
getChildContext() {
@@ -387,7 +389,7 @@ describe('ReactStatelessComponent', () => {
function Child(props, context) {
return <div>{context.lang}</div>;
}
Child.contextTypes = {lang: React.PropTypes.string};
Child.contextTypes = {lang: PropTypes.string};
var el = document.createElement('div');
ReactDOM.render(<Parent />, el);
@@ -15,6 +15,7 @@ var React = require('react');
var ReactDOM = require('react-dom');
var ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
var ReactTestUtils = require('ReactTestUtils');
var PropTypes = require('prop-types');
describe('ReactDOMFiber', () => {
var container;
@@ -683,7 +684,7 @@ describe('ReactDOMFiber', () => {
class Component extends React.Component {
static contextTypes = {
foo: React.PropTypes.string.isRequired,
foo: PropTypes.string.isRequired,
};
render() {
@@ -693,7 +694,7 @@ describe('ReactDOMFiber', () => {
class Parent extends React.Component {
static childContextTypes = {
foo: React.PropTypes.string.isRequired,
foo: PropTypes.string.isRequired,
};
getChildContext() {
@@ -717,8 +718,8 @@ describe('ReactDOMFiber', () => {
class Component extends React.Component {
static contextTypes = {
foo: React.PropTypes.string.isRequired,
getFoo: React.PropTypes.func.isRequired,
foo: PropTypes.string.isRequired,
getFoo: PropTypes.func.isRequired,
};
render() {
@@ -728,8 +729,8 @@ describe('ReactDOMFiber', () => {
class Parent extends React.Component {
static childContextTypes = {
foo: React.PropTypes.string.isRequired,
getFoo: React.PropTypes.func.isRequired,
foo: PropTypes.string.isRequired,
getFoo: PropTypes.func.isRequired,
};
state = {
@@ -761,8 +762,8 @@ describe('ReactDOMFiber', () => {
class Component extends React.Component {
static contextTypes = {
foo: React.PropTypes.string.isRequired,
getFoo: React.PropTypes.func.isRequired,
foo: PropTypes.string.isRequired,
getFoo: PropTypes.func.isRequired,
};
render() {
@@ -772,8 +773,8 @@ describe('ReactDOMFiber', () => {
class Parent extends React.Component {
static childContextTypes = {
foo: React.PropTypes.string.isRequired,
getFoo: React.PropTypes.func.isRequired,
foo: PropTypes.string.isRequired,
getFoo: PropTypes.func.isRequired,
};
getChildContext() {
@@ -12,6 +12,7 @@
'use strict';
let ExecutionEnvironment;
let PropTypes;
let React;
let ReactDOM;
let ReactDOMServer;
@@ -206,6 +207,7 @@ function expectMarkupMismatch(serverElement, clientElement) {
// To get around this, we must reload React modules in between server and client render.
function resetModules() {
jest.resetModuleRegistry();
PropTypes = require('prop-types');
React = require('React');
ReactDOM = require('ReactDOM');
ReactDOMServer = require('ReactDOMServer');
@@ -1585,7 +1587,7 @@ describe('ReactDOMServerIntegration', () => {
return this.props.children;
}
}
Parent.childContextTypes = {text: React.PropTypes.string};
Parent.childContextTypes = {text: PropTypes.string};
PurpleContext = props => <Parent text="purple">{props.children}</Parent>;
RedContext = props => <Parent text="red">{props.children}</Parent>;
@@ -1597,7 +1599,7 @@ describe('ReactDOMServerIntegration', () => {
return <div>{this.context.text}</div>;
}
}
ClassChildWithContext.contextTypes = {text: React.PropTypes.string};
ClassChildWithContext.contextTypes = {text: PropTypes.string};
const e = await render(
<PurpleContext><ClassChildWithContext /></PurpleContext>,
@@ -1609,7 +1611,7 @@ describe('ReactDOMServerIntegration', () => {
function StatelessChildWithContext(props, context) {
return <div>{context.text}</div>;
}
StatelessChildWithContext.contextTypes = {text: React.PropTypes.string};
StatelessChildWithContext.contextTypes = {text: PropTypes.string};
const e = await render(
<PurpleContext><StatelessChildWithContext /></PurpleContext>,
@@ -1650,7 +1652,7 @@ describe('ReactDOMServerIntegration', () => {
return <div id="classWrongChild">{this.context.text}</div>;
}
}
ClassChildWithWrongContext.contextTypes = {foo: React.PropTypes.string};
ClassChildWithWrongContext.contextTypes = {foo: PropTypes.string};
const e = await render(
<PurpleContext><ClassChildWithWrongContext /></PurpleContext>,
@@ -1664,7 +1666,7 @@ describe('ReactDOMServerIntegration', () => {
return <div id="statelessWrongChild">{context.text}</div>;
}
StatelessChildWithWrongContext.contextTypes = {
foo: React.PropTypes.string,
foo: PropTypes.string,
};
const e = await render(
@@ -1677,7 +1679,7 @@ describe('ReactDOMServerIntegration', () => {
function Grandchild(props, context) {
return <div>{context.text}</div>;
}
Grandchild.contextTypes = {text: React.PropTypes.string};
Grandchild.contextTypes = {text: PropTypes.string};
const Child = props => <Grandchild />;
@@ -1689,7 +1691,7 @@ describe('ReactDOMServerIntegration', () => {
const Grandchild = (props, context) => {
return <div>{context.text}</div>;
};
Grandchild.contextTypes = {text: React.PropTypes.string};
Grandchild.contextTypes = {text: PropTypes.string};
const e = await render(
<PurpleContext><RedContext><Grandchild /></RedContext></PurpleContext>,
@@ -1706,7 +1708,7 @@ describe('ReactDOMServerIntegration', () => {
return <Child />;
}
}
Parent.childContextTypes = {text1: React.PropTypes.string};
Parent.childContextTypes = {text1: PropTypes.string};
class Child extends React.Component {
getChildContext() {
@@ -1716,7 +1718,7 @@ describe('ReactDOMServerIntegration', () => {
return <Grandchild />;
}
}
Child.childContextTypes = {text2: React.PropTypes.string};
Child.childContextTypes = {text2: PropTypes.string};
const Grandchild = (props, context) => {
return (
@@ -1727,8 +1729,8 @@ describe('ReactDOMServerIntegration', () => {
);
};
Grandchild.contextTypes = {
text1: React.PropTypes.string,
text2: React.PropTypes.string,
text1: PropTypes.string,
text2: PropTypes.string,
};
const e = await render(<Parent />);
@@ -1750,12 +1752,12 @@ describe('ReactDOMServerIntegration', () => {
return <Child />;
}
}
WillMountContext.childContextTypes = {text: React.PropTypes.string};
WillMountContext.childContextTypes = {text: PropTypes.string};
const Child = (props, context) => {
return <div>{context.text}</div>;
};
Child.contextTypes = {text: React.PropTypes.string};
Child.contextTypes = {text: PropTypes.string};
const e = await render(<WillMountContext />);
expect(e.textContent).toBe('foo');
@@ -1788,7 +1790,7 @@ describe('ReactDOMServerIntegration', () => {
return {value1: 'foo', value2: 'bar'};
}
}
Component.childContextTypes = {value1: React.PropTypes.string};
Component.childContextTypes = {value1: PropTypes.string};
return render(<Component />);
},
);
@@ -12,6 +12,7 @@
'use strict';
var React = require('react');
var PropTypes = require('prop-types');
var ReactDOM = require('react-dom');
var ReactTestUtils = require('ReactTestUtils');
var renderSubtreeIntoContainer = require('renderSubtreeIntoContainer');
@@ -22,7 +23,7 @@ describe('renderSubtreeIntoContainer', () => {
class Component extends React.Component {
static contextTypes = {
foo: React.PropTypes.string.isRequired,
foo: PropTypes.string.isRequired,
};
render() {
@@ -32,7 +33,7 @@ describe('renderSubtreeIntoContainer', () => {
class Parent extends React.Component {
static childContextTypes = {
foo: React.PropTypes.string.isRequired,
foo: PropTypes.string.isRequired,
};
getChildContext() {
@@ -63,7 +64,7 @@ describe('renderSubtreeIntoContainer', () => {
class Component extends React.Component {
static contextTypes = {
foo: React.PropTypes.string.isRequired,
foo: PropTypes.string.isRequired,
};
render() {
@@ -76,7 +77,7 @@ describe('renderSubtreeIntoContainer', () => {
// eslint-disable-next-line no-unused-vars
class Parent extends React.Component {
static childContextTypes = {
foo: React.PropTypes.string.isRequired,
foo: PropTypes.string.isRequired,
};
getChildContext() {
@@ -104,8 +105,8 @@ describe('renderSubtreeIntoContainer', () => {
class Component extends React.Component {
static contextTypes = {
foo: React.PropTypes.string.isRequired,
getFoo: React.PropTypes.func.isRequired,
foo: PropTypes.string.isRequired,
getFoo: PropTypes.func.isRequired,
};
render() {
@@ -115,8 +116,8 @@ describe('renderSubtreeIntoContainer', () => {
class Parent extends React.Component {
static childContextTypes = {
foo: React.PropTypes.string.isRequired,
getFoo: React.PropTypes.func.isRequired,
foo: PropTypes.string.isRequired,
getFoo: PropTypes.func.isRequired,
};
state = {
@@ -156,8 +157,8 @@ describe('renderSubtreeIntoContainer', () => {
class Component extends React.Component {
static contextTypes = {
foo: React.PropTypes.string.isRequired,
getFoo: React.PropTypes.func.isRequired,
foo: PropTypes.string.isRequired,
getFoo: PropTypes.func.isRequired,
};
render() {
@@ -167,8 +168,8 @@ describe('renderSubtreeIntoContainer', () => {
class Parent extends React.Component {
static childContextTypes = {
foo: React.PropTypes.string.isRequired,
getFoo: React.PropTypes.func.isRequired,
foo: PropTypes.string.isRequired,
getFoo: PropTypes.func.isRequired,
};
getChildContext() {
@@ -229,7 +230,7 @@ describe('renderSubtreeIntoContainer', () => {
return {value: this.props.value};
}
static childContextTypes = {
value: React.PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
};
}
@@ -244,7 +245,7 @@ describe('renderSubtreeIntoContainer', () => {
class Child extends React.Component {
static contextTypes = {
value: React.PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
};
render() {
return <div>{this.context.value}</div>;
@@ -272,7 +273,7 @@ describe('renderSubtreeIntoContainer', () => {
renderSubtreeIntoContainer(this, <Middle />, portal1);
}
static childContextTypes = {
value: React.PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
};
}
@@ -287,7 +288,7 @@ describe('renderSubtreeIntoContainer', () => {
class Child extends React.Component {
static contextTypes = {
value: React.PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
};
render() {
return <div>{this.context.value}</div>;
@@ -11,7 +11,7 @@
'use strict';
var React = require('react');
var PropTypes = require('prop-types');
var ReactPropTypesSecret = require('ReactPropTypesSecret');
var warning = require('fbjs/lib/warning');
@@ -57,7 +57,7 @@ var propTypes = {
'set either `onChange` or `readOnly`.',
);
},
onChange: React.PropTypes.func,
onChange: PropTypes.func,
};
var loggedTypeFailures = {};
@@ -11,6 +11,7 @@
'use strict';
var PropTypes;
var RCTEventEmitter;
var React;
var ReactNative;
@@ -21,6 +22,7 @@ var createReactNativeComponentClass;
beforeEach(() => {
jest.resetModules();
PropTypes = require('prop-types');
RCTEventEmitter = require('RCTEventEmitter');
React = require('react');
ReactNative = require('ReactNative');
@@ -97,7 +99,7 @@ it('handles events on text nodes', () => {
});
class ContextHack extends React.Component {
static childContextTypes = {isInAParentText: React.PropTypes.bool};
static childContextTypes = {isInAParentText: PropTypes.bool};
getChildContext() {
return {isInAParentText: true};
}
@@ -15,7 +15,7 @@
import type {Fiber} from 'ReactFiber';
import type {StackCursor} from 'ReactFiberStack';
var React = require('react');
var checkPropTypes = require('checkPropTypes');
var emptyObject = require('fbjs/lib/emptyObject');
var getComponentName = require('getComponentName');
var invariant = require('fbjs/lib/invariant');
@@ -105,8 +105,7 @@ exports.getMaskedContext = function(
if (__DEV__) {
const name = getComponentName(workInProgress) || 'Unknown';
ReactDebugCurrentFrame.current = workInProgress;
// $FlowFixMe - We know this export exists now, need to wait for Flow update
React.checkPropTypes(
checkPropTypes(
contextTypes,
context,
'context',
@@ -219,8 +218,7 @@ function processChildContext(
// TODO: remove this hack when we delete unstable_renderSubtree in Fiber.
const workInProgress = isReconciling ? fiber : null;
ReactDebugCurrentFrame.current = workInProgress;
// $FlowFixMe - We know this export exists now, need to wait for Flow update
React.checkPropTypes(
checkPropTypes(
childContextTypes,
childContext,
'child context',
@@ -14,12 +14,14 @@
var React;
var ReactNoop;
var ReactFeatureFlags;
var PropTypes;
describe('ReactIncremental', () => {
beforeEach(() => {
jest.resetModules();
React = require('react');
ReactNoop = require('ReactNoop');
PropTypes = require('prop-types');
ReactFeatureFlags = require('ReactFeatureFlags');
ReactFeatureFlags.disableNewFiberFeatures = false;
@@ -1592,7 +1594,7 @@ describe('ReactIncremental', () => {
class Intl extends React.Component {
static childContextTypes = {
locale: React.PropTypes.string,
locale: PropTypes.string,
};
getChildContext() {
return {
@@ -1607,7 +1609,7 @@ describe('ReactIncremental', () => {
class Router extends React.Component {
static childContextTypes = {
route: React.PropTypes.string,
route: PropTypes.string,
};
getChildContext() {
return {
@@ -1622,7 +1624,7 @@ describe('ReactIncremental', () => {
class ShowLocale extends React.Component {
static contextTypes = {
locale: React.PropTypes.string,
locale: PropTypes.string,
};
render() {
ops.push('ShowLocale ' + JSON.stringify(this.context));
@@ -1632,7 +1634,7 @@ describe('ReactIncremental', () => {
class ShowRoute extends React.Component {
static contextTypes = {
route: React.PropTypes.string,
route: PropTypes.string,
};
render() {
ops.push('ShowRoute ' + JSON.stringify(this.context));
@@ -1645,8 +1647,8 @@ describe('ReactIncremental', () => {
return `${context.route} in ${context.locale}`;
}
ShowBoth.contextTypes = {
locale: React.PropTypes.string,
route: React.PropTypes.string,
locale: PropTypes.string,
route: PropTypes.string,
};
class ShowNeither extends React.Component {
@@ -1745,10 +1747,10 @@ describe('ReactIncremental', () => {
var ops = [];
class Recurse extends React.Component {
static contextTypes = {
n: React.PropTypes.number,
n: PropTypes.number,
};
static childContextTypes = {
n: React.PropTypes.number,
n: PropTypes.number,
};
getChildContext() {
return {n: (this.context.n || 3) - 1};
@@ -1777,7 +1779,7 @@ describe('ReactIncremental', () => {
class Intl extends React.Component {
static childContextTypes = {
locale: React.PropTypes.string,
locale: PropTypes.string,
};
getChildContext() {
return {
@@ -1792,7 +1794,7 @@ describe('ReactIncremental', () => {
class ShowLocale extends React.Component {
static contextTypes = {
locale: React.PropTypes.string,
locale: PropTypes.string,
};
render() {
ops.push('ShowLocale ' + JSON.stringify(this.context));
@@ -1835,7 +1837,7 @@ describe('ReactIncremental', () => {
class Intl extends React.Component {
static childContextTypes = {
locale: React.PropTypes.string,
locale: PropTypes.string,
};
getChildContext() {
const childContext = {
@@ -1852,7 +1854,7 @@ describe('ReactIncremental', () => {
class ShowLocaleClass extends React.Component {
static contextTypes = {
locale: React.PropTypes.string,
locale: PropTypes.string,
};
render() {
ops.push('ShowLocaleClass:read ' + JSON.stringify(this.context));
@@ -1865,7 +1867,7 @@ describe('ReactIncremental', () => {
return context.locale;
}
ShowLocaleFn.contextTypes = {
locale: React.PropTypes.string,
locale: PropTypes.string,
};
class Stateful extends React.Component {
@@ -1925,7 +1927,7 @@ describe('ReactIncremental', () => {
class Intl extends React.Component {
static childContextTypes = {
locale: React.PropTypes.string,
locale: PropTypes.string,
};
getChildContext() {
const childContext = {
@@ -1942,7 +1944,7 @@ describe('ReactIncremental', () => {
class ShowLocaleClass extends React.Component {
static contextTypes = {
locale: React.PropTypes.string,
locale: PropTypes.string,
};
render() {
ops.push('ShowLocaleClass:read ' + JSON.stringify(this.context));
@@ -1955,7 +1957,7 @@ describe('ReactIncremental', () => {
return context.locale;
}
ShowLocaleFn.contextTypes = {
locale: React.PropTypes.string,
locale: PropTypes.string,
};
function IndirectionFn(props, context) {
@@ -11,6 +11,7 @@
'use strict';
var PropTypes;
var React;
var ReactNoop;
var ReactFeatureFlags;
@@ -18,6 +19,7 @@ var ReactFeatureFlags;
describe('ReactIncrementalErrorHandling', () => {
beforeEach(() => {
jest.resetModules();
PropTypes = require('prop-types');
React = require('react');
ReactNoop = require('ReactNoop');
ReactFeatureFlags = require('ReactFeatureFlags');
@@ -679,8 +681,8 @@ describe('ReactIncrementalErrorHandling', () => {
it('unwinds the context stack correctly on error', () => {
class Provider extends React.Component {
static childContextTypes = {message: React.PropTypes.string};
static contextTypes = {message: React.PropTypes.string};
static childContextTypes = {message: PropTypes.string};
static contextTypes = {message: PropTypes.string};
getChildContext() {
return {
message: (this.context.message || '') + this.props.message,
@@ -696,7 +698,7 @@ describe('ReactIncrementalErrorHandling', () => {
}
Connector.contextTypes = {
message: React.PropTypes.string,
message: PropTypes.string,
};
function BadRender() {
@@ -17,6 +17,7 @@ describe('ReactDebugFiberPerf', () => {
let ReactFeatureFlags;
let ReactNoop;
let ReactPortal;
let PropTypes;
let root;
let activeMeasure;
@@ -119,6 +120,7 @@ describe('ReactDebugFiberPerf', () => {
ReactNoop = require('ReactNoop');
ReactPortal = require('ReactPortal');
ReactFeatureFlags.disableNewFiberFeatures = false;
PropTypes = require('prop-types');
});
afterEach(() => {
@@ -245,7 +247,7 @@ describe('ReactDebugFiberPerf', () => {
it('captures all lifecycles', () => {
class AllLifecycles extends React.Component {
static childContextTypes = {
foo: React.PropTypes.any,
foo: PropTypes.any,
};
shouldComponentUpdate() {
return true;
@@ -27,6 +27,7 @@ if (__DEV__) {
var warningAboutMissingGetChildContext = {};
}
var checkPropTypes = require('checkPropTypes');
var emptyObject = require('fbjs/lib/emptyObject');
var invariant = require('fbjs/lib/invariant');
var shallowEqual = require('fbjs/lib/shallowEqual');
@@ -729,7 +730,7 @@ var ReactCompositeComponent = {
_checkContextTypes: function(typeSpecs, values, location: string) {
if (__DEV__) {
ReactDebugCurrentFrame.current = this._debugID;
React.checkPropTypes(
checkPropTypes(
typeSpecs,
values,
location,
+5 -3
View File
@@ -11,6 +11,7 @@
'use strict';
var PropTypes;
var React;
var ReactDOM;
var ReactDOMServer;
@@ -18,6 +19,7 @@ var ReactTestUtils;
describe('ReactTestUtils', () => {
beforeEach(() => {
PropTypes = require('prop-types');
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');
@@ -195,7 +197,7 @@ describe('ReactTestUtils', () => {
it('can shallowly render components with contextTypes', () => {
class SimpleComponent extends React.Component {
static contextTypes = {
name: React.PropTypes.string,
name: PropTypes.string,
};
render() {
@@ -258,7 +260,7 @@ describe('ReactTestUtils', () => {
it('can pass context when shallowly rendering', () => {
class SimpleComponent extends React.Component {
static contextTypes = {
name: React.PropTypes.string,
name: PropTypes.string,
};
render() {
@@ -278,7 +280,7 @@ describe('ReactTestUtils', () => {
class SimpleComponent extends React.Component {
static contextTypes = {
name: React.PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
};
render() {