@samitouri / QOS-React / commits / b6bc4bd996

Spy at warnings consistently inside test cases

We move any spies on `console.error()` from `beforeEach()` to the individual `it()` tests. This means that if a new test is introduced in these suites, it does not ignore warnings by default, but fails on any unexpected warning, which is Jest's default behavior. We also change a few old instances of direct `console.error = jest.genMockFn()` assignment to use `spyOn()` for consistency with the rest of the tests.

Dan Abramov committed Mar 30, 2016 at 21:50 UTC b6bc4bd996404304aebc935560ed4c9aa35fbc00
4 files changed +80 -86
src/isomorphic/classic/__tests__/ReactContextValidator-test.js
+4 -2
@@ -31,8 +31,6 @@ describe('ReactContextValidator', function() {
31 ReactDOM = require('ReactDOM');
32 ReactTestUtils = require('ReactTestUtils');
33 reactComponentExpect = require('reactComponentExpect');
34 -
35 - spyOn(console, 'error');
34 });
35
36 // TODO: This behavior creates a runtime dependency on propTypes. We should
@@ -133,6 +131,8 @@ describe('ReactContextValidator', function() {
131 });
132
133 it('should check context types', function() {
134 + spyOn(console, 'error');
135 +
136 var Component = React.createClass({
137 contextTypes: {
138 foo: React.PropTypes.string.isRequired,
@@ -202,6 +202,8 @@ describe('ReactContextValidator', function() {
202 });
203
204 it('should check child context types', function() {
205 + spyOn(console, 'error');
206 +
207 var Component = React.createClass({
208 childContextTypes: {
209 foo: React.PropTypes.string.isRequired,
src/isomorphic/classic/class/__tests__/ReactClass-test.js
+51 -63
@@ -21,7 +21,6 @@ describe('ReactClass-spec', function() {
21 React = require('React');
22 ReactDOM = require('ReactDOM');
23 ReactTestUtils = require('ReactTestUtils');
24 - spyOn(console, 'error');
24 });
25
26 it('should throw when `render` is not specified', function() {
@@ -60,76 +59,62 @@ describe('ReactClass-spec', function() {
59 });
60
61 it('should warn on invalid prop types', function() {
63 - var warn = console.error;
64 - console.error = jest.genMockFn();
65 - try {
66 -
67 - React.createClass({
68 - displayName: 'Component',
69 - propTypes: {
70 - prop: null,
71 - },
72 - render: function() {
73 - return <span>{this.props.prop}</span>;
74 - },
75 - });
76 - expect(console.error.mock.calls.length).toBe(1);
77 - expect(console.error.mock.calls[0][0]).toBe(
78 - 'Warning: Component: prop type `prop` is invalid; ' +
79 - 'it must be a function, usually from React.PropTypes.'
80 - );
81 - } finally {
82 - console.error = warn;
83 - }
62 + spyOn(console, 'error');
63 + React.createClass({
64 + displayName: 'Component',
65 + propTypes: {
66 + prop: null,
67 + },
68 + render: function() {
69 + return <span>{this.props.prop}</span>;
70 + },
71 + });
72 + expect(console.error.argsForCall.length).toBe(1);
73 + expect(console.error.argsForCall[0][0]).toBe(
74 + 'Warning: Component: prop type `prop` is invalid; ' +
75 + 'it must be a function, usually from React.PropTypes.'
76 + );
77 });
78
79 it('should warn on invalid context types', function() {
87 - var warn = console.error;
88 - console.error = jest.genMockFn();
89 - try {
90 - React.createClass({
91 - displayName: 'Component',
92 - contextTypes: {
93 - prop: null,
94 - },
95 - render: function() {
96 - return <span>{this.props.prop}</span>;
97 - },
98 - });
99 - expect(console.error.mock.calls.length).toBe(1);
100 - expect(console.error.mock.calls[0][0]).toBe(
101 - 'Warning: Component: context type `prop` is invalid; ' +
102 - 'it must be a function, usually from React.PropTypes.'
103 - );
104 - } finally {
105 - console.error = warn;
106 - }
80 + spyOn(console, 'error');
81 + React.createClass({
82 + displayName: 'Component',
83 + contextTypes: {
84 + prop: null,
85 + },
86 + render: function() {
87 + return <span>{this.props.prop}</span>;
88 + },
89 + });
90 + expect(console.error.argsForCall.length).toBe(1);
91 + expect(console.error.argsForCall[0][0]).toBe(
92 + 'Warning: Component: context type `prop` is invalid; ' +
93 + 'it must be a function, usually from React.PropTypes.'
94 + );
95 });
96
97 it('should throw on invalid child context types', function() {
110 - var warn = console.error;
111 - console.error = jest.genMockFn();
112 - try {
113 - React.createClass({
114 - displayName: 'Component',
115 - childContextTypes: {
116 - prop: null,
117 - },
118 - render: function() {
119 - return <span>{this.props.prop}</span>;
120 - },
121 - });
122 - expect(console.error.mock.calls.length).toBe(1);
123 - expect(console.error.mock.calls[0][0]).toBe(
124 - 'Warning: Component: child context type `prop` is invalid; ' +
125 - 'it must be a function, usually from React.PropTypes.'
126 - );
127 - } finally {
128 - console.error = warn;
129 - }
98 + spyOn(console, 'error');
99 + React.createClass({
100 + displayName: 'Component',
101 + childContextTypes: {
102 + prop: null,
103 + },
104 + render: function() {
105 + return <span>{this.props.prop}</span>;
106 + },
107 + });
108 + expect(console.error.argsForCall.length).toBe(1);
109 + expect(console.error.argsForCall[0][0]).toBe(
110 + 'Warning: Component: child context type `prop` is invalid; ' +
111 + 'it must be a function, usually from React.PropTypes.'
112 + );
113 });
114
115 it('should warn when mispelling shouldComponentUpdate', function() {
116 + spyOn(console, 'error');
117 +
118 React.createClass({
119 componentShouldUpdate: function() {
120 return false;
@@ -163,6 +148,7 @@ describe('ReactClass-spec', function() {
148 });
149
150 it('should warn when mispelling componentWillReceiveProps', function() {
151 + spyOn(console, 'error');
152 React.createClass({
153 componentWillRecieveProps: function() {
154 return false;
@@ -204,6 +190,7 @@ describe('ReactClass-spec', function() {
190 // TODO: Consider actually moving these to statics or drop this unit test.
191
192 xit('should warn when using deprecated non-static spec keys', function() {
193 + spyOn(console, 'error');
194 React.createClass({
195 mixins: [{}],
196 propTypes: {
@@ -348,6 +335,7 @@ describe('ReactClass-spec', function() {
335 });
336
337 it('should throw when using legacy factories', function() {
338 + spyOn(console, 'error');
339 var Component = React.createClass({
340 render() {
341 return <div />;
@@ -355,7 +343,7 @@ describe('ReactClass-spec', function() {
343 });
344
345 expect(() => Component()).toThrow();
358 - expect(console.error.calls.length).toBe(1);
346 + expect(console.error.argsForCall.length).toBe(1);
347 expect(console.error.argsForCall[0][0]).toBe(
348 'Warning: Something is calling a React component directly. Use a ' +
349 'factory or JSX instead. See: https://fb.me/react-legacyfactory'
src/isomorphic/classic/types/__tests__/ReactPropTypes-test.js
+8 -2
@@ -241,7 +241,6 @@ describe('ReactPropTypes', function() {
241 return <div>{this.props.label}</div>;
242 },
243 });
244 - spyOn(console, 'error');
244 });
245
246 it('should support components', () => {
@@ -258,6 +257,8 @@ describe('ReactPropTypes', function() {
257 });
258
259 it('should be able to define a single child as label', () => {
260 + spyOn(console, 'error');
261 +
262 var instance = <Component label={<div />} />;
263 instance = ReactTestUtils.renderIntoDocument(instance);
264
@@ -265,6 +266,8 @@ describe('ReactPropTypes', function() {
266 });
267
268 it('should warn when passing no label and isRequired is set', () => {
269 + spyOn(console, 'error');
270 +
271 var instance = <Component />;
272 instance = ReactTestUtils.renderIntoDocument(instance);
273
@@ -782,7 +785,6 @@ describe('ReactPropTypes', function() {
785 describe('Custom validator', function() {
786 beforeEach(function() {
787 jest.resetModuleRegistry();
785 - spyOn(console, 'error');
788 });
789
790 it('should have been called with the right params', function() {
@@ -820,6 +822,8 @@ describe('ReactPropTypes', function() {
822 });
823
824 it('should have received the validator\'s return value', function() {
825 + spyOn(console, 'error');
826 +
827 var spy = jasmine.createSpy().andCallFake(
828 function(props, propName, componentName) {
829 if (props[propName] !== 5) {
@@ -845,6 +849,8 @@ describe('ReactPropTypes', function() {
849
850 it('should not warn if the validator returned null',
851 function() {
852 + spyOn(console, 'error');
853 +
854 var spy = jasmine.createSpy().andCallFake(
855 function(props, propName, componentName) {
856 return null;
src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js
+17 -19
@@ -68,8 +68,6 @@ describe('ReactCompositeComponent', function() {
68 <b></b>;
69 },
70 });
71 -
72 - spyOn(console, 'error');
71 });
72
73 it('should support module pattern components', function() {
@@ -123,7 +121,6 @@ describe('ReactCompositeComponent', function() {
121 container.innerHTML = markup;
122
123 ReactDOM.render(<Parent />, container);
126 - expect(console.error).not.toHaveBeenCalled();
124 });
125
126 it('should react to state changes from callbacks', function() {
@@ -173,6 +170,8 @@ describe('ReactCompositeComponent', function() {
170 });
171
172 it('should auto bind methods and values correctly', function() {
173 + spyOn(console, 'error');
174 +
175 var ComponentClass = React.createClass({
176 getInitialState: function() {
177 return {valueToReturn: 'hi'};
@@ -273,6 +272,8 @@ describe('ReactCompositeComponent', function() {
272 });
273
274 it('should warn about `forceUpdate` on unmounted components', function() {
275 + spyOn(console, 'error');
276 +
277 var container = document.createElement('div');
278 document.body.appendChild(container);
279
@@ -303,6 +304,8 @@ describe('ReactCompositeComponent', function() {
304 });
305
306 it('should warn about `setState` on unmounted components', function() {
307 + spyOn(console, 'error');
308 +
309 var container = document.createElement('div');
310 document.body.appendChild(container);
311
@@ -367,17 +370,16 @@ describe('ReactCompositeComponent', function() {
370 });
371
372 var instance = ReactDOM.render(<Component />, container);
370 -
373 instance.setState({value: 1});
372 - expect(console.error.calls.length).toBe(0);
374
375 ReactDOM.unmountComponentAtNode(container);
375 - expect(console.error.calls.length).toBe(0);
376 expect(cbCalled).toBe(false);
377 });
378
379
380 it('should warn about `setState` in render', function() {
381 + spyOn(console, 'error');
382 +
383 var container = document.createElement('div');
384
385 var renderedState = -1;
@@ -425,6 +427,8 @@ describe('ReactCompositeComponent', function() {
427 });
428
429 it('should warn about `setState` in getChildContext', function() {
430 + spyOn(console, 'error');
431 +
432 var container = document.createElement('div');
433
434 var renderPasses = 0;
@@ -499,6 +503,8 @@ describe('ReactCompositeComponent', function() {
503 });
504
505 it('should warn when shouldComponentUpdate() returns undefined', function() {
506 + spyOn(console, 'error');
507 +
508 var Component = React.createClass({
509 getInitialState: function() {
510 return {bogus: false};
@@ -524,6 +530,8 @@ describe('ReactCompositeComponent', function() {
530 });
531
532 it('should warn when componentDidUnmount method is defined', function() {
533 + spyOn(console, 'error');
534 +
535 var Component = React.createClass({
536 componentDidUnmount: function() {
537 },
@@ -659,8 +667,6 @@ describe('ReactCompositeComponent', function() {
667 parentInstance.setState({flag: true});
668 expect(parentInstance.state.flag).toBe(true);
669
662 - expect(console.error.argsForCall.length).toBe(0);
663 -
670 reactComponentExpect(childInstance).scalarContextEqual({foo: 'bar', flag: true});
671 });
672
@@ -719,8 +725,6 @@ describe('ReactCompositeComponent', function() {
725 // We update <Parent /> while <Child /> is still a static prop relative to this update
726 wrapper.refs.parent.setState({flag: false});
727
722 - expect(console.error.argsForCall.length).toBe(0);
723 -
728 expect(wrapper.refs.parent.state.flag).toEqual(false);
729 reactComponentExpect(wrapper.refs.child).scalarContextEqual({flag: false});
730
@@ -840,8 +844,6 @@ describe('ReactCompositeComponent', function() {
844 });
845 expect(parentInstance.state.flag).toBe(true);
846
843 - expect(console.error.argsForCall.length).toBe(0);
844 -
847 reactComponentExpect(childInstance).scalarContextEqual({foo: 'bar', depth: 0});
848 });
849
@@ -1036,6 +1038,8 @@ describe('ReactCompositeComponent', function() {
1038 });
1039
1040 it('should disallow nested render calls', function() {
1041 + spyOn(console, 'error');
1042 +
1043 var Inner = React.createClass({
1044 render: function() {
1045 return <div />;
@@ -1176,8 +1180,6 @@ describe('ReactCompositeComponent', function() {
1180
1181 var div = document.createElement('div');
1182 ReactDOM.render(<Parent><Component /></Parent>, div);
1179 -
1180 - expect(console.error.argsForCall.length).toBe(0);
1183 });
1184
1185 it('should replace state', function() {
@@ -1270,15 +1272,11 @@ describe('ReactCompositeComponent', function() {
1272 });
1273
1274 ReactDOM.render(<Outer><Component /></Outer>, container);
1273 -
1274 - expect(console.error.calls.length).toBe(0);
1275 -
1275 ReactDOM.render(<Outer />, container);
1277 -
1278 - expect(console.error.calls.length).toBe(0);
1276 });
1277
1278 it('should warn when mutated props are passed', function() {
1279 + spyOn(console, 'error');
1280
1281 var container = document.createElement('div');
1282