-
Notifications
You must be signed in to change notification settings - Fork 47.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix for #5468: Validate proptype definitions sooner #6316
Changes from 4 commits
985a484
72e5ada
5a1f598
d225816
e1c7e55
1e6ab81
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ var ReactPropTypeLocationNames = require('ReactPropTypeLocationNames'); | |
|
||
var emptyFunction = require('emptyFunction'); | ||
var getIteratorFn = require('getIteratorFn'); | ||
var warning = require('warning'); | ||
|
||
/** | ||
* Collection of methods that allow declaration and validation of props that are | ||
|
@@ -226,11 +227,16 @@ function createInstanceTypeChecker(expectedClass) { | |
|
||
function createEnumTypeChecker(expectedValues) { | ||
if (!Array.isArray(expectedValues)) { | ||
return createChainableTypeChecker(function() { | ||
return new Error( | ||
`Invalid argument supplied to oneOf, expected an instance of array.` | ||
); | ||
}); | ||
if (__DEV__) { | ||
warning(false, 'Invalid argument supplied to oneOf, expected an instance of array.'); | ||
return emptyFunction.thatReturnsNull; | ||
} else { | ||
return createChainableTypeChecker(function() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For consistency with DEV behavior, let’s return Not that all these semantics really matter because nobody should be calling prop types in prod but it’s best to have them behave the same way until we explicitly disallow it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gaearon oh, so don't call createChainableTypeChecker as an alternate branch flow, always call warning? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gaearon pushed my interpretation of your comments, thanks |
||
return new Error( | ||
`Invalid argument supplied to oneOf, expected an instance of array.` | ||
); | ||
}); | ||
} | ||
} | ||
|
||
function validate(props, propName, componentName, location, propFullName) { | ||
|
@@ -288,11 +294,16 @@ function createObjectOfTypeChecker(typeChecker) { | |
|
||
function createUnionTypeChecker(arrayOfTypeCheckers) { | ||
if (!Array.isArray(arrayOfTypeCheckers)) { | ||
return createChainableTypeChecker(function() { | ||
return new Error( | ||
`Invalid argument supplied to oneOfType, expected an instance of array.` | ||
); | ||
}); | ||
if (__DEV__) { | ||
warning(false, 'Invalid argument supplied to oneOfType, expected an instance of array.'); | ||
return emptyFunction.thatReturnsNull; | ||
} else { | ||
return createChainableTypeChecker(function() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. So basically both of these blocks should become warning(...)
return emptyFunction.thatReturnsNull;
|
||
return new Error( | ||
`Invalid argument supplied to oneOfType, expected an instance of array.` | ||
); | ||
}); | ||
} | ||
} | ||
|
||
function validate(props, propName, componentName, location, propFullName) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -591,11 +591,13 @@ describe('ReactPropTypes', function() { | |
|
||
describe('OneOf Types', function() { | ||
it('should fail for invalid argument', function() { | ||
typeCheckFail( | ||
PropTypes.oneOf('red', 'blue'), | ||
'red', | ||
'Invalid argument supplied to oneOf, expected an instance of array.' | ||
); | ||
spyOn(console, ['error']); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you change this to |
||
|
||
PropTypes.oneOf('red', 'blue'); | ||
|
||
expect(console.error).toHaveBeenCalled(); | ||
expect(console.error.calls.argsFor(0)[0]) | ||
.toContain('Invalid argument supplied to oneOf, expected an instance of array.'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let’s additionally test that type check passes (since that’s the behavior we have now). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gaearon feedback implemented, thanks |
||
}); | ||
|
||
it('should warn for invalid values', function() { | ||
|
@@ -652,11 +654,13 @@ describe('ReactPropTypes', function() { | |
|
||
describe('Union Types', function() { | ||
it('should fail for invalid argument', function() { | ||
typeCheckFail( | ||
PropTypes.oneOfType(PropTypes.string, PropTypes.number), | ||
'red', | ||
'Invalid argument supplied to oneOfType, expected an instance of array.' | ||
); | ||
spyOn(console, ['error']); | ||
|
||
PropTypes.oneOfType(PropTypes.string, PropTypes.number); | ||
|
||
expect(console.error).toHaveBeenCalled(); | ||
expect(console.error.calls.argsFor(0)[0]) | ||
.toContain('Invalid argument supplied to oneOfType, expected an instance of array.'); | ||
}); | ||
|
||
it('should warn if none of the types are valid', function() { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We would still want to return a function for consistency—it would just be a no-op.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gaearon no-oped, or should I return false?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let’s use
emptyFunction.thatReturnsNull
(if I recall correctly)