Skip to content

Commit

Permalink
[New] add PropTypes.resetWarningCache
Browse files Browse the repository at this point in the history
  • Loading branch information
Patrick Way authored and ljharb committed Apr 8, 2018
1 parent 215265c commit 40af72f
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 4 deletions.
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -284,6 +284,10 @@ PropTypes.checkPropTypes(myPropTypes, props, 'age', 'MyComponent');
// `MyComponent`, expected `number`.
```

## PropTypes.resetWarningCache()

`PropTypes.checkPropTypes(...)` only `console.error.log(...)`s a given message once. To reset the cache while testing call `PropTypes.resetWarningCache()`

### License

prop-types is [MIT licensed](./LICENSE).
71 changes: 70 additions & 1 deletion __tests__/PropTypesDevelopmentReact15.js
Expand Up @@ -112,7 +112,7 @@ describe('PropTypesDevelopmentReact15', () => {

describe('checkPropTypes', () => {
it('should warn for invalid validators', () => {
spyOn(console, 'error')
spyOn(console, 'error');
const propTypes = { foo: undefined };
const props = { foo: 'foo' };
PropTypes.checkPropTypes(
Expand All @@ -128,6 +128,51 @@ describe('PropTypesDevelopmentReact15', () => {
);
});

it('should only warn once for identical validator failures', () => {
spyOn(console, 'error');
const propTypes = { foo: undefined };
const props = { foo: 'foo' };
PropTypes.checkPropTypes(
propTypes,
props,
'prop',
'testComponent',
null,
);
PropTypes.checkPropTypes(
propTypes,
props,
'prop',
'testComponent',
null,
);
expect(console.error.calls.count()).toEqual(1);
});

describe('checkPropTypes.resetWarningCache', () => {
it('should reset warning cache', () => {
spyOn(console, 'error');
const propTypes = { foo: undefined };
const props = { foo: 'foo' };
PropTypes.checkPropTypes(
propTypes,
props,
'prop',
'testComponent',
null,
);
PropTypes.checkPropTypes.resetWarningCache();
PropTypes.checkPropTypes(
propTypes,
props,
'prop',
'testComponent',
null,
);
expect(console.error.calls.count()).toEqual(2);
});
});

it('does not return a value from a validator', () => {
spyOn(console, 'error');
const propTypes = {
Expand Down Expand Up @@ -181,6 +226,30 @@ describe('PropTypesDevelopmentReact15', () => {
});
});

describe('resetWarningCache', () => {
it('should reset warning cache', () => {
spyOn(console, 'error');
const propTypes = { foo: undefined };
const props = { foo: 'foo' };
PropTypes.checkPropTypes(
propTypes,
props,
'prop',
'testComponent',
null,
);
PropTypes.resetWarningCache();
PropTypes.checkPropTypes(
propTypes,
props,
'prop',
'testComponent',
null,
);
expect(console.error.calls.count()).toEqual(2);
});
});

describe('Primitive Types', () => {
it('should warn for invalid strings', () => {
typeCheckFail(
Expand Down
71 changes: 70 additions & 1 deletion __tests__/PropTypesDevelopmentStandalone-test.js
Expand Up @@ -124,6 +124,51 @@ describe('PropTypesDevelopmentStandalone', () => {
);
});

it('should only warn once for identical validator failures', () => {
spyOn(console, 'error');
const propTypes = { foo: undefined };
const props = { foo: 'foo' };
PropTypes.checkPropTypes(
propTypes,
props,
'prop',
'testComponent',
null,
);
PropTypes.checkPropTypes(
propTypes,
props,
'prop',
'testComponent',
null,
);
expect(console.error.calls.count()).toEqual(1);
});

describe('checkPropTypes.resetWarningCache', () => {
it('should reset warning cache', () => {
spyOn(console, 'error')
const propTypes = { foo: undefined };
const props = { foo: 'foo' };
PropTypes.checkPropTypes(
propTypes,
props,
'prop',
'testComponent',
null,
);
PropTypes.checkPropTypes.resetWarningCache();
PropTypes.checkPropTypes(
propTypes,
props,
'prop',
'testComponent',
null,
);
expect(console.error.calls.count()).toEqual(2);
});
});

it('does not return a value from a validator', () => {
spyOn(console, 'error');
const propTypes = {
Expand Down Expand Up @@ -177,6 +222,30 @@ describe('PropTypesDevelopmentStandalone', () => {
});
});

describe('resetWarningCache', () => {
it('should reset warning cache', () => {
spyOn(console, 'error');
const propTypes = { foo: undefined };
const props = { foo: 'foo' };
PropTypes.checkPropTypes(
propTypes,
props,
'prop',
'testComponent',
null,
);
PropTypes.resetWarningCache();
PropTypes.checkPropTypes(
propTypes,
props,
'prop',
'testComponent',
null,
);
expect(console.error.calls.count()).toEqual(2);
});
});

describe('Primitive Types', () => {
it('should warn for invalid strings', () => {
typeCheckFail(
Expand Down Expand Up @@ -725,7 +794,7 @@ describe('PropTypesDevelopmentStandalone', () => {

it('should support objects with a null prototype', () => {
const nullObj = Object.create(null);
nullObj.test = "a property";
nullObj.test = 'a property';
typeCheckPass(PropTypes.objectOf(PropTypes.string), nullObj);
});

Expand Down
22 changes: 22 additions & 0 deletions __tests__/PropTypesProductionReact15-test.js
Expand Up @@ -968,4 +968,26 @@ describe('PropTypesProductionReact15', () => {
expectNoop(PropTypes.symbol, CoreSymbol('core-js'));
});
});

describe('checkPropTypes', function() {
describe('checkPropTypes.resetWarningCache', () => {
it('should provide empty function', () => {
spyOn(console, 'error');

var spy = jest.fn();
PropTypes.checkPropTypes.resetWarningCache();
expect(spy).not.toBeCalled();
});
});
});

describe('resetWarningCache', () => {
it('should provide empty function', () => {
spyOn(console, 'error');

var spy = jest.fn();
PropTypes.resetWarningCache();
expect(spy).not.toBeCalled();
});
});
});
20 changes: 20 additions & 0 deletions __tests__/PropTypesProductionStandalone-test.js
Expand Up @@ -232,5 +232,25 @@ describe('PropTypesProductionStandalone', function() {
typeCheckPass(spy, 'no way');
expect(spy).not.toBeCalled();
});

describe('checkPropTypes.resetWarningCache', () => {
it('should provide empty function', () => {
spyOn(console, 'error');

var spy = jest.fn();
PropTypes.checkPropTypes.resetWarningCache();
expect(spy).not.toBeCalled();
});
});
});

describe('resetWarningCache', () => {
it('should provide empty function', () => {
spyOn(console, 'error');

var spy = jest.fn();
PropTypes.resetWarningCache();
expect(spy).not.toBeCalled();
});
});
});
11 changes: 11 additions & 0 deletions checkPropTypes.js
Expand Up @@ -89,4 +89,15 @@ function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
}
}

/**
* Resets warning cache when testing.
*
* @private
*/
checkPropTypes.resetWarningCache = function() {
if (process.env.NODE_ENV !== 'production') {
loggedTypeFailures = {};
}
}

module.exports = checkPropTypes;
8 changes: 6 additions & 2 deletions factoryWithThrowingShims.js
Expand Up @@ -10,6 +10,8 @@
var ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');

function emptyFunction() {}
function emptyFunctionWithReset() {}
emptyFunctionWithReset.resetWarningCache = emptyFunction;

module.exports = function() {
function shim(props, propName, componentName, location, propFullName, secret) {
Expand Down Expand Up @@ -49,10 +51,12 @@ module.exports = function() {
oneOf: getShim,
oneOfType: getShim,
shape: getShim,
exact: getShim
exact: getShim,

checkPropTypes: emptyFunctionWithReset,
resetWarningCache: emptyFunction
};

ReactPropTypes.checkPropTypes = emptyFunction;
ReactPropTypes.PropTypes = ReactPropTypes;

return ReactPropTypes;
Expand Down
1 change: 1 addition & 0 deletions factoryWithTypeCheckers.js
Expand Up @@ -550,6 +550,7 @@ module.exports = function(isValidElement, throwOnDirectAccess) {
}

ReactPropTypes.checkPropTypes = checkPropTypes;
ReactPropTypes.resetWarningCache = checkPropTypes.resetWarningCache;
ReactPropTypes.PropTypes = ReactPropTypes;

return ReactPropTypes;
Expand Down

0 comments on commit 40af72f

Please sign in to comment.