Fail tests on any un-spied warnings
Fixes #3890.
Ben Alpert committed
Jun 24, 2015 at 23:51 UTC
c22153e25a7e9824a9d3059f1b92e9130395506d
7 files changed
+60
-47
src/isomorphic/modern/class/__tests__/ReactTypeScriptClass-test.ts
+22
-27
@@ -311,13 +311,12 @@ describe('ReactTypeScriptClass', function() {
311
});
312
313
it('throws if no render function is defined', function() {
314
- var warn = jest.genMockFn();
315
- console.error = warn;
314
+ spyOn(console, 'error');
315
316
expect(() => React.render(React.createElement(Empty), container)).toThrow();
317
319
- expect(warn.mock.calls.length).toBe(1);
320
- expect(warn.mock.calls[0][0]).toBe(
318
+ expect((<any>console.error).argsForCall.length).toBe(1);
319
+ expect((<any>console.error).argsForCall[0][0]).toBe(
320
'Warning: Empty(...): ' +
321
'No `render` method found on the returned component instance: you may ' +
322
'have forgotten to define `render` in your component or you may have ' +
@@ -434,38 +433,36 @@ describe('ReactTypeScriptClass', function() {
433
434
it('warns when classic properties are defined on the instance, ' +
435
'but does not invoke them.', function() {
437
- var warn = jest.genMockFn();
438
- console.error = warn;
436
+ spyOn(console, 'error');
437
getInitialStateWasCalled = false;
438
getDefaultPropsWasCalled = false;
439
test(React.createElement(ClassicProperties), 'SPAN', 'foo');
440
expect(getInitialStateWasCalled).toBe(false);
441
expect(getDefaultPropsWasCalled).toBe(false);
444
- expect(warn.mock.calls.length).toBe(4);
445
- expect(warn.mock.calls[0][0]).toContain(
442
+ expect((<any>console.error).argsForCall.length).toBe(4);
443
+ expect((<any>console.error).argsForCall[0][0]).toContain(
444
'getInitialState was defined on ClassicProperties, ' +
445
'a plain JavaScript class.'
446
);
449
- expect(warn.mock.calls[1][0]).toContain(
447
+ expect((<any>console.error).argsForCall[1][0]).toContain(
448
'getDefaultProps was defined on ClassicProperties, ' +
449
'a plain JavaScript class.'
450
);
453
- expect(warn.mock.calls[2][0]).toContain(
451
+ expect((<any>console.error).argsForCall[2][0]).toContain(
452
'propTypes was defined as an instance property on ClassicProperties.'
453
);
456
- expect(warn.mock.calls[3][0]).toContain(
454
+ expect((<any>console.error).argsForCall[3][0]).toContain(
455
'contextTypes was defined as an instance property on ClassicProperties.'
456
);
457
});
458
459
it('should warn when misspelling shouldComponentUpdate', function() {
462
- var warn = jest.genMockFn();
463
- console.error = warn;
460
+ spyOn(console, 'error');
461
462
test(React.createElement(MisspelledComponent1), 'SPAN', 'foo');
463
467
- expect(warn.mock.calls.length).toBe(1);
468
- expect(warn.mock.calls[0][0]).toBe(
464
+ expect((<any>console.error).argsForCall.length).toBe(1);
465
+ expect((<any>console.error).argsForCall[0][0]).toBe(
466
'Warning: ' +
467
'MisspelledComponent1 has a method called componentShouldUpdate(). Did ' +
468
'you mean shouldComponentUpdate()? The name is phrased as a question ' +
@@ -474,13 +471,12 @@ describe('ReactTypeScriptClass', function() {
471
});
472
473
it('should warn when misspelling componentWillReceiveProps', function() {
477
- var warn = jest.genMockFn();
478
- console.error = warn;
474
+ spyOn(console, 'error');
475
476
test(React.createElement(MisspelledComponent2), 'SPAN', 'foo');
477
482
- expect(warn.mock.calls.length).toBe(1);
483
- expect(warn.mock.calls[0][0]).toBe(
478
+ expect((<any>console.error).argsForCall.length).toBe(1);
479
+ expect((<any>console.error).argsForCall[0][0]).toBe(
480
'Warning: ' +
481
'MisspelledComponent2 has a method called componentWillRecieveProps(). ' +
482
'Did you mean componentWillReceiveProps()?'
@@ -488,8 +484,7 @@ describe('ReactTypeScriptClass', function() {
484
});
485
486
it('should throw AND warn when trying to access classic APIs', function() {
491
- var warn = jest.genMockFn();
492
- console.error = warn;
487
+ spyOn(console, 'error');
488
var instance = test(
489
React.createElement(Inner, {name: 'foo'}),
490
'DIV','foo'
@@ -499,20 +494,20 @@ describe('ReactTypeScriptClass', function() {
494
expect(() => instance.isMounted()).toThrow();
495
expect(() => instance.setProps({ name: 'bar' })).toThrow();
496
expect(() => instance.replaceProps({ name: 'bar' })).toThrow();
502
- expect(warn.mock.calls.length).toBe(5);
503
- expect(warn.mock.calls[0][0]).toContain(
497
+ expect((<any>console.error).argsForCall.length).toBe(5);
498
+ expect((<any>console.error).argsForCall[0][0]).toContain(
499
'getDOMNode(...) is deprecated in plain JavaScript React classes'
500
);
506
- expect(warn.mock.calls[1][0]).toContain(
501
+ expect((<any>console.error).argsForCall[1][0]).toContain(
502
'replaceState(...) is deprecated in plain JavaScript React classes'
503
);
509
- expect(warn.mock.calls[2][0]).toContain(
504
+ expect((<any>console.error).argsForCall[2][0]).toContain(
505
'isMounted(...) is deprecated in plain JavaScript React classes'
506
);
512
- expect(warn.mock.calls[3][0]).toContain(
507
+ expect((<any>console.error).argsForCall[3][0]).toContain(
508
'setProps(...) is deprecated in plain JavaScript React classes'
509
);
515
- expect(warn.mock.calls[4][0]).toContain(
510
+ expect((<any>console.error).argsForCall[4][0]).toContain(
511
'replaceProps(...) is deprecated in plain JavaScript React classes'
512
);
513
});
src/renderers/dom/client/__tests__/ReactMount-test.js
+5
-6
@@ -124,24 +124,23 @@ describe('ReactMount', function() {
124
var container = document.createElement('container');
125
container.innerHTML = React.renderToString(<div />) + ' ';
126
127
- console.error = mocks.getMockFunction();
127
+ spyOn(console, 'error');
128
ReactMount.render(<div />, container);
129
- expect(console.error.mock.calls.length).toBe(1);
129
+ expect(console.error.calls.length).toBe(1);
130
131
container.innerHTML = ' ' + React.renderToString(<div />);
132
133
- console.error = mocks.getMockFunction();
133
ReactMount.render(<div />, container);
135
- expect(console.error.mock.calls.length).toBe(1);
134
+ expect(console.error.calls.length).toBe(2);
135
});
136
137
it('should not warn if mounting into non-empty node', function() {
138
var container = document.createElement('container');
139
container.innerHTML = '<div></div>';
140
142
- console.error = mocks.getMockFunction();
141
+ spyOn(console, 'error');
142
ReactMount.render(<div />, container);
144
- expect(console.error.mock.calls.length).toBe(0);
143
+ expect(console.error.calls.length).toBe(0);
144
});
145
146
it('should warn when mounting into document.body', function () {
src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js
-4
@@ -22,13 +22,10 @@ var ReactTestUtils;
22
var ReactUpdates;
23
24
var reactComponentExpect;
25
-var mocks;
25
26
describe('ReactCompositeComponent', function() {
27
28
beforeEach(function() {
30
- mocks = require('mocks');
31
-
29
reactComponentExpect = require('reactComponentExpect');
30
React = require('React');
31
ReactCurrentOwner = require('ReactCurrentOwner');
@@ -71,7 +68,6 @@ describe('ReactCompositeComponent', function() {
68
},
69
});
70
74
- console.error = mocks.getMockFunction();
71
spyOn(console, 'error');
72
});
73
src/shared/utils/__tests__/traverseAllChildren-test.js
+3
@@ -286,6 +286,7 @@ describe('traverseAllChildren', function() {
286
});
287
288
it('should be called for each child in an iterable without keys', function() {
289
+ spyOn(console, 'error');
290
var threeDivIterable = {
291
'@@iterator': function() {
292
var i = 0;
@@ -332,6 +333,8 @@ describe('traverseAllChildren', function() {
333
'.2'
334
);
335
336
+ expect(console.error.calls.length).toBe(1);
337
+ expect(console.error.calls[0].args[0]).toContain('Warning: Each child in an array or iterator should have a unique "key" prop.');
338
});
339
340
it('should be called for each child in an iterable with keys', function() {
src/test/__tests__/ReactTestUtils-test.js
-8
@@ -15,7 +15,6 @@ var React;
15
var ReactTestUtils;
16
17
var mocks;
18
-var warn;
18
19
describe('ReactTestUtils', function() {
20
@@ -24,13 +23,6 @@ describe('ReactTestUtils', function() {
23
24
React = require('React');
25
ReactTestUtils = require('ReactTestUtils');
27
-
28
- warn = console.error;
29
- console.error = mocks.getMockFunction();
30
- });
31
-
32
- afterEach(function() {
33
- console.error = warn;
26
});
27
28
it('should have shallow rendering', function() {
test/index.html
+2
-2
@@ -14,11 +14,11 @@
14
15
'lib/postDataToURL.browser.js',
16
'lib/reportTestResults.browser.js',
17
+ 'lib/jasmine-execute.js',
18
19
'../build/react.js',
20
'../build/react-test.js',
20
- 'the-files-to-test.generated.js',
21
- 'lib/jasmine-execute.js'
21
+ 'the-files-to-test.generated.js'
22
];
23
24
if (typeof Function.prototype.bind == 'undefined') {
test/lib/jasmine-execute.js
+28
@@ -16,4 +16,32 @@ document.write('<style> @import \'../vendor/jasmine/jasmine.css?_=' + (+new Date
16
window.onload = function() {
17
env.execute();
18
};
19
+
20
+ var oldError = console.error;
21
+ var newError = function() {
22
+ oldError.apply(this, arguments);
23
+ var spec = env.currentSpec;
24
+ if (spec) {
25
+ var expectationResult = new jasmine.ExpectationResult({
26
+ passed: false,
27
+ message:
28
+ 'Expected test not to warn. If the warning is expected, mock it ' +
29
+ 'out using spyOn(console, \'error\'); and test that the warning ' +
30
+ 'occurs.',
31
+ });
32
+ spec.addMatcherResult(expectationResult);
33
+ }
34
+ };
35
+ console.error = newError;
36
+ // Make sure console.error is set back at the end of each test, or else the
37
+ // above logic won't work
38
+ env.afterEach(function() {
39
+ if (console.error !== newError && !console.error.isSpy) {
40
+ var expectationResult = new jasmine.ExpectationResult({
41
+ passed: false,
42
+ message: 'Test did not tear down console.error mock properly.',
43
+ });
44
+ env.currentSpec.addMatcherResult(expectationResult);
45
+ }
46
+ });
47
})(jasmine.getEnv());