Merge pull request #3521 from grant/master

Display error when trying to create an element of type `boolean`. Fixes #3478
This commit is contained in:
Jim
2015-03-26 14:39:32 -07:00
3 changed files with 53 additions and 26 deletions
+6 -6
View File
@@ -362,7 +362,8 @@ function checkAndWarnForMutatedProps(element) {
* @param {ReactElement} element * @param {ReactElement} element
*/ */
function validatePropTypes(element) { function validatePropTypes(element) {
if (element.type == null) { if (!(typeof element.type === 'string' ||
typeof element.type === 'function')) {
// This has already warned. Don't throw. // This has already warned. Don't throw.
return; return;
} }
@@ -398,11 +399,10 @@ var ReactElementValidator = {
createElement: function(type, props, children) { createElement: function(type, props, children) {
// We warn in this case but don't throw. We expect the element creation to // We warn in this case but don't throw. We expect the element creation to
// succeed and there will likely be errors in render. // succeed and there will likely be errors in render.
warning( warning(typeof type === 'string' || typeof type === 'function',
type != null, 'React.createElement: type should not be null, undefined, boolean, or ' +
'React.createElement: type should not be null or undefined. It should ' + 'number. It should be a string (for DOM elements) or a ReactClass ' +
'be a string (for DOM elements) or a ReactClass (for composite ' + '(for composite components).%s',
'components).%s',
getDeclarationErrorAddendum() getDeclarationErrorAddendum()
); );
@@ -258,26 +258,40 @@ describe('ReactElementValidator', function() {
); );
}); });
it('gives a helpful error when passing null or undefined', function() { it('gives a helpful error when passing null, undefined, boolean, or number',
() => {
spyOn(console, 'error'); spyOn(console, 'error');
React.createElement(undefined); React.createElement(undefined);
React.createElement(null); React.createElement(null);
expect(console.error.calls.length).toBe(2); React.createElement(true);
React.createElement(123);
expect(console.error.calls.length).toBe(4);
expect(console.error.calls[0].args[0]).toBe( expect(console.error.calls[0].args[0]).toBe(
'Warning: React.createElement: type should not be null or undefined. ' + 'Warning: React.createElement: type should not be null, undefined, ' +
'It should be a string (for DOM elements) or a ReactClass (for ' + 'boolean, or number. It should be a string (for DOM elements) or a ' +
'composite components).' 'ReactClass (for composite components).'
); );
expect(console.error.calls[1].args[0]).toBe( expect(console.error.calls[1].args[0]).toBe(
'Warning: React.createElement: type should not be null or undefined. ' + 'Warning: React.createElement: type should not be null, undefined, ' +
'It should be a string (for DOM elements) or a ReactClass (for ' + 'boolean, or number. It should be a string (for DOM elements) or a ' +
'composite components).' 'ReactClass (for composite components).'
);
expect(console.error.calls[2].args[0]).toBe(
'Warning: React.createElement: type should not be null, undefined, ' +
'boolean, or number. It should be a string (for DOM elements) or a ' +
'ReactClass (for composite components).'
);
expect(console.error.calls[3].args[0]).toBe(
'Warning: React.createElement: type should not be null, undefined, ' +
'boolean, or number. It should be a string (for DOM elements) or a ' +
'ReactClass (for composite components).'
); );
React.createElement('div'); React.createElement('div');
expect(console.error.calls.length).toBe(2); expect(console.error.calls.length).toBe(4);
}); });
it('includes the owner name when passing null or undefined', function() { it('includes the owner name when passing null, undefined, boolean, or number',
() => {
spyOn(console, 'error'); spyOn(console, 'error');
var ParentComp = React.createClass({ var ParentComp = React.createClass({
render: function() { render: function() {
@@ -289,9 +303,10 @@ describe('ReactElementValidator', function() {
}).toThrow(); }).toThrow();
expect(console.error.calls.length).toBe(2); expect(console.error.calls.length).toBe(2);
expect(console.error.calls[0].args[0]).toBe( expect(console.error.calls[0].args[0]).toBe(
'Warning: React.createElement: type should not be null or undefined. ' + 'Warning: React.createElement: type should not be null, undefined, ' +
'It should be a string (for DOM elements) or a ReactClass (for ' + 'boolean, or number. It should be a string (for DOM elements) or a ' +
'composite components). Check the render method of `ParentComp`.' 'ReactClass (for composite components). Check the render method of ' +
'`ParentComp`.'
); );
expect(console.error.calls[1].args[0]).toBe( expect(console.error.calls[1].args[0]).toBe(
'Warning: Only functions or strings can be mounted as React components.' 'Warning: Only functions or strings can be mounted as React components.'
@@ -208,24 +208,36 @@ describe('ReactJSXElementValidator', function() {
); );
}); });
it('gives a helpful error when passing null or undefined', function() { it('gives a helpful error when passing null, undefined, or boolean', () => {
var Undefined = undefined; var Undefined = undefined;
var Null = null; var Null = null;
var True = true;
var Num = 123;
var Div = 'div'; var Div = 'div';
spyOn(console, 'error'); spyOn(console, 'error');
<Undefined />; <Undefined />;
<Null />; <Null />;
expect(console.error.calls.length).toBe(2); <True />;
<Num />;
expect(console.error.calls.length).toBe(4);
expect(console.error.calls[0].args[0]).toContain( expect(console.error.calls[0].args[0]).toContain(
'type should not be null or undefined. It should be a string (for ' + 'type should not be null, undefined, boolean, or number. It should be ' +
'DOM elements) or a ReactClass (for composite components).' 'a string (for DOM elements) or a ReactClass (for composite components).'
); );
expect(console.error.calls[1].args[0]).toContain( expect(console.error.calls[1].args[0]).toContain(
'type should not be null or undefined. It should be a string (for ' + 'type should not be null, undefined, boolean, or number. It should be ' +
'DOM elements) or a ReactClass (for composite components).' 'a string (for DOM elements) or a ReactClass (for composite components).'
);
expect(console.error.calls[2].args[0]).toContain(
'type should not be null, undefined, boolean, or number. It should be ' +
'a string (for DOM elements) or a ReactClass (for composite components).'
);
expect(console.error.calls[3].args[0]).toContain(
'type should not be null, undefined, boolean, or number. It should be ' +
'a string (for DOM elements) or a ReactClass (for composite components).'
); );
<Div />; <Div />;
expect(console.error.calls.length).toBe(2); expect(console.error.calls.length).toBe(4);
}); });
it('should check default prop values', function() { it('should check default prop values', function() {