Move propType validation to element instead of class.

Conflicts:
	src/classic/element/ReactElementValidator.js
This commit is contained in:
Jim
2015-01-26 17:16:49 -08:00
parent f837cc289e
commit 6ee5299b4a
4 changed files with 69 additions and 42 deletions
@@ -216,31 +216,35 @@ describe('ReactDOMInput', function() {
try {
console.warn = mocks.getMockFunction();
var node = document.createElement('div');
var link = new ReactLink('yolo', mocks.getMockFunction());
React.render(<input type="text" valueLink={link} />, node);
ReactTestUtils.renderIntoDocument(<input type="text" valueLink={link} />);
expect(console.warn.mock.calls.length).toBe(0);
React.render(
<input type="text" value="zoink" onChange={mocks.getMockFunction()} />,
node
ReactTestUtils.renderIntoDocument(
<input type="text" value="zoink" onChange={mocks.getMockFunction()} />
);
expect(console.warn.mock.calls.length).toBe(0);
React.render(
<input type="text" value="zoink" readOnly={true} />,
node
);
expect(console.warn.mock.calls.length).toBe(0);
React.render(<input type="text" value="zoink" />, node);
ReactTestUtils.renderIntoDocument(<input type="text" value="zoink" />);
expect(console.warn.mock.calls.length).toBe(1);
} finally {
console.warn = oldWarn;
}
});
React.render(
<input type="text" value="zoink" readOnly={false} />,
node
it('should warn with value and no onChange handler and readOnly specified', function() {
var oldWarn = console.warn;
try {
console.warn = mocks.getMockFunction();
ReactTestUtils.renderIntoDocument(
<input type="text" value="zoink" readOnly={true} />
);
expect(console.warn.mock.calls.length).toBe(2);
expect(console.warn.mock.calls.length).toBe(0);
ReactTestUtils.renderIntoDocument(
<input type="text" value="zoink" readOnly={false} />
);
expect(console.warn.mock.calls.length).toBe(1);
} finally {
console.warn = oldWarn;
}
@@ -299,30 +303,41 @@ describe('ReactDOMInput', function() {
React.render(<input type="checkbox" checkedLink={link} />, node);
expect(console.warn.mock.calls.length).toBe(0);
React.render(
ReactTestUtils.renderIntoDocument(
<input
type="checkbox"
checked="false"
onChange={mocks.getMockFunction()}
/>,
node
/>
);
expect(console.warn.mock.calls.length).toBe(0);
React.render(
<input type="checkbox" checked="false" readOnly={true} />,
node
ReactTestUtils.renderIntoDocument(
<input type="checkbox" checked="false" readOnly={true} />
);
expect(console.warn.mock.calls.length).toBe(0);
React.render(<input type="checkbox" checked="false" />, node);
ReactTestUtils.renderIntoDocument(<input type="checkbox" checked="false" />);
expect(console.warn.mock.calls.length).toBe(1);
} finally {
console.warn = oldWarn;
}
});
React.render(
<input type="checkbox" checked="false" readOnly={false} />,
node
it('should warn with checked and no onChange handler with readOnly specified', function() {
var oldWarn = console.warn;
try {
console.warn = mocks.getMockFunction();
ReactTestUtils.renderIntoDocument(
<input type="checkbox" checked="false" readOnly={true} />
);
expect(console.warn.mock.calls.length).toBe(2);
expect(console.warn.mock.calls.length).toBe(0);
ReactTestUtils.renderIntoDocument(
<input type="checkbox" checked="false" readOnly={false} />
);
expect(console.warn.mock.calls.length).toBe(1);
} finally {
console.warn = oldWarn;
}
+13 -13
View File
@@ -29,6 +29,16 @@ var monitorCodeUse = require('monitorCodeUse');
var invariant = require('invariant');
var warning = require('warning');
function getDeclarationErrorAddendum() {
if (ReactCurrentOwner.current) {
var name = ReactCurrentOwner.current.getName();
if (name) {
return ' Check the render method of `' + name + '`.';
}
}
return '';
}
/**
* Warn if there's no key explicitly set on dynamic arrays of children or
* object keys are not valid. This allows us to keep track of children between
@@ -257,11 +267,9 @@ function checkPropTypes(componentName, propTypes, props, location) {
// Only monitor this failure once because there tends to be a lot of the
// same error.
loggedTypeFailures[error.message] = true;
// This will soon use the warning module
monitorCodeUse(
'react_failed_descriptor_type_check',
{ message: error.message }
);
var addendum = getDeclarationErrorAddendum(this);
warning(false, error.message + addendum);
}
}
}
@@ -378,14 +386,6 @@ var ReactElementValidator = {
ReactPropTypeLocations.prop
);
}
if (componentClass.contextTypes) {
checkPropTypes(
name,
componentClass.contextTypes,
element._context,
ReactPropTypeLocations.context
);
}
if (typeof componentClass.getDefaultProps === 'function') {
warning(
componentClass.getDefaultProps.isReactClassApproved,
+9 -1
View File
@@ -28,6 +28,7 @@ var assign = require('Object.assign');
var emptyObject = require('emptyObject');
var invariant = require('invariant');
var keyMirror = require('keyMirror');
var monitorCodeUse = require('monitorCodeUse');
var shouldUpdateReactComponent = require('shouldUpdateReactComponent');
var warning = require('warning');
@@ -608,7 +609,14 @@ var ReactCompositeComponentMixin = {
// React.render calls, so I'm abstracting it away into
// a function to minimize refactoring in the future
var addendum = getDeclarationErrorAddendum(this);
warning(false, error.message + addendum);
if (location === ReactPropTypeLocations.prop) {
// Preface gives us something to blacklist in warning module
var preface = 'Failed CompositeComponent proptype check. ';
warning(false, preface + error.message + addendum);
} else {
warning(false, error.message + addendum);
}
}
}
}
+4
View File
@@ -31,6 +31,10 @@ if (__DEV__) {
);
}
if (format.indexOf('Failed CompositeComponent proptype check. ') === 0) {
return; // Ignore CompositeComponent proptype check.
}
if (!condition) {
var argIndex = 0;
var message = 'Warning: ' + format.replace(/%s/g, () => args[argIndex++]);