From 4a0a534357ff3fdde2a503b22408a6c2f4058083 Mon Sep 17 00:00:00 2001 From: Troy DeMonbreun Date: Tue, 28 Jun 2016 19:30:41 -0500 Subject: [PATCH] Fix for #5468: Validate PropTypes.oneOf(Type) arguments early (#6316) * Fix for 5468: Validate proptype definitions sooner Added typeCheckWarn() func and updated the oneOf/oneOfType tests Added __DEV__ warning for invalid oneOf/OneOfType args * Suppress redundant error on warn; typeCheckWarn() removed * Return no-op * Using emptyFunction module for consistency * Remove createChainableTypeChecker() call * Adjust test to assert type check passes when warned (cherry picked from commit 6cc037bd0d49f1f55cbdd36fbfd395118c64d393) --- .../classic/types/ReactPropTypes.js | 15 +++------ .../types/__tests__/ReactPropTypes-test.js | 32 ++++++++++++------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/isomorphic/classic/types/ReactPropTypes.js b/src/isomorphic/classic/types/ReactPropTypes.js index 4d9ac1d846..9b419cc769 100644 --- a/src/isomorphic/classic/types/ReactPropTypes.js +++ b/src/isomorphic/classic/types/ReactPropTypes.js @@ -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,8 @@ 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.` - ); - }); + warning(false, 'Invalid argument supplied to oneOf, expected an instance of array.'); + return emptyFunction.thatReturnsNull; } function validate(props, propName, componentName, location, propFullName) { @@ -288,11 +286,8 @@ 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.` - ); - }); + warning(false, 'Invalid argument supplied to oneOfType, expected an instance of array.'); + return emptyFunction.thatReturnsNull; } function validate(props, propName, componentName, location, propFullName) { diff --git a/src/isomorphic/classic/types/__tests__/ReactPropTypes-test.js b/src/isomorphic/classic/types/__tests__/ReactPropTypes-test.js index 14559720ae..4e787857c7 100644 --- a/src/isomorphic/classic/types/__tests__/ReactPropTypes-test.js +++ b/src/isomorphic/classic/types/__tests__/ReactPropTypes-test.js @@ -590,12 +590,16 @@ 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.' - ); + it('should warn but not error for invalid argument', function() { + spyOn(console, 'error'); + + 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.'); + + typeCheckPass(PropTypes.oneOf('red', 'blue'), 'red'); }); it('should warn for invalid values', function() { @@ -651,12 +655,16 @@ 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.' - ); + it('should warn but not error for invalid argument', function() { + 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.'); + + typeCheckPass(PropTypes.oneOf(PropTypes.string, PropTypes.number), []); }); it('should warn if none of the types are valid', function() {