Merge pull request #4223 from spicyj/check-no-warn

Fail tests on any un-spied warnings
This commit is contained in:
Ben Alpert 2015-06-29 07:57:56 -07:00
commit 454d47fa09
7 changed files with 60 additions and 47 deletions

View File

@ -311,13 +311,12 @@ describe('ReactTypeScriptClass', function() {
});
it('throws if no render function is defined', function() {
var warn = jest.genMockFn();
console.error = warn;
spyOn(console, 'error');
expect(() => React.render(React.createElement(Empty), container)).toThrow();
expect(warn.mock.calls.length).toBe(1);
expect(warn.mock.calls[0][0]).toBe(
expect((<any>console.error).argsForCall.length).toBe(1);
expect((<any>console.error).argsForCall[0][0]).toBe(
'Warning: Empty(...): ' +
'No `render` method found on the returned component instance: you may ' +
'have forgotten to define `render` in your component or you may have ' +
@ -434,38 +433,36 @@ describe('ReactTypeScriptClass', function() {
it('warns when classic properties are defined on the instance, ' +
'but does not invoke them.', function() {
var warn = jest.genMockFn();
console.error = warn;
spyOn(console, 'error');
getInitialStateWasCalled = false;
getDefaultPropsWasCalled = false;
test(React.createElement(ClassicProperties), 'SPAN', 'foo');
expect(getInitialStateWasCalled).toBe(false);
expect(getDefaultPropsWasCalled).toBe(false);
expect(warn.mock.calls.length).toBe(4);
expect(warn.mock.calls[0][0]).toContain(
expect((<any>console.error).argsForCall.length).toBe(4);
expect((<any>console.error).argsForCall[0][0]).toContain(
'getInitialState was defined on ClassicProperties, ' +
'a plain JavaScript class.'
);
expect(warn.mock.calls[1][0]).toContain(
expect((<any>console.error).argsForCall[1][0]).toContain(
'getDefaultProps was defined on ClassicProperties, ' +
'a plain JavaScript class.'
);
expect(warn.mock.calls[2][0]).toContain(
expect((<any>console.error).argsForCall[2][0]).toContain(
'propTypes was defined as an instance property on ClassicProperties.'
);
expect(warn.mock.calls[3][0]).toContain(
expect((<any>console.error).argsForCall[3][0]).toContain(
'contextTypes was defined as an instance property on ClassicProperties.'
);
});
it('should warn when misspelling shouldComponentUpdate', function() {
var warn = jest.genMockFn();
console.error = warn;
spyOn(console, 'error');
test(React.createElement(MisspelledComponent1), 'SPAN', 'foo');
expect(warn.mock.calls.length).toBe(1);
expect(warn.mock.calls[0][0]).toBe(
expect((<any>console.error).argsForCall.length).toBe(1);
expect((<any>console.error).argsForCall[0][0]).toBe(
'Warning: ' +
'MisspelledComponent1 has a method called componentShouldUpdate(). Did ' +
'you mean shouldComponentUpdate()? The name is phrased as a question ' +
@ -474,13 +471,12 @@ describe('ReactTypeScriptClass', function() {
});
it('should warn when misspelling componentWillReceiveProps', function() {
var warn = jest.genMockFn();
console.error = warn;
spyOn(console, 'error');
test(React.createElement(MisspelledComponent2), 'SPAN', 'foo');
expect(warn.mock.calls.length).toBe(1);
expect(warn.mock.calls[0][0]).toBe(
expect((<any>console.error).argsForCall.length).toBe(1);
expect((<any>console.error).argsForCall[0][0]).toBe(
'Warning: ' +
'MisspelledComponent2 has a method called componentWillRecieveProps(). ' +
'Did you mean componentWillReceiveProps()?'
@ -488,8 +484,7 @@ describe('ReactTypeScriptClass', function() {
});
it('should throw AND warn when trying to access classic APIs', function() {
var warn = jest.genMockFn();
console.error = warn;
spyOn(console, 'error');
var instance = test(
React.createElement(Inner, {name: 'foo'}),
'DIV','foo'
@ -499,20 +494,20 @@ describe('ReactTypeScriptClass', function() {
expect(() => instance.isMounted()).toThrow();
expect(() => instance.setProps({ name: 'bar' })).toThrow();
expect(() => instance.replaceProps({ name: 'bar' })).toThrow();
expect(warn.mock.calls.length).toBe(5);
expect(warn.mock.calls[0][0]).toContain(
expect((<any>console.error).argsForCall.length).toBe(5);
expect((<any>console.error).argsForCall[0][0]).toContain(
'getDOMNode(...) is deprecated in plain JavaScript React classes'
);
expect(warn.mock.calls[1][0]).toContain(
expect((<any>console.error).argsForCall[1][0]).toContain(
'replaceState(...) is deprecated in plain JavaScript React classes'
);
expect(warn.mock.calls[2][0]).toContain(
expect((<any>console.error).argsForCall[2][0]).toContain(
'isMounted(...) is deprecated in plain JavaScript React classes'
);
expect(warn.mock.calls[3][0]).toContain(
expect((<any>console.error).argsForCall[3][0]).toContain(
'setProps(...) is deprecated in plain JavaScript React classes'
);
expect(warn.mock.calls[4][0]).toContain(
expect((<any>console.error).argsForCall[4][0]).toContain(
'replaceProps(...) is deprecated in plain JavaScript React classes'
);
});

View File

@ -124,24 +124,23 @@ describe('ReactMount', function() {
var container = document.createElement('container');
container.innerHTML = React.renderToString(<div />) + ' ';
console.error = mocks.getMockFunction();
spyOn(console, 'error');
ReactMount.render(<div />, container);
expect(console.error.mock.calls.length).toBe(1);
expect(console.error.calls.length).toBe(1);
container.innerHTML = ' ' + React.renderToString(<div />);
console.error = mocks.getMockFunction();
ReactMount.render(<div />, container);
expect(console.error.mock.calls.length).toBe(1);
expect(console.error.calls.length).toBe(2);
});
it('should not warn if mounting into non-empty node', function() {
var container = document.createElement('container');
container.innerHTML = '<div></div>';
console.error = mocks.getMockFunction();
spyOn(console, 'error');
ReactMount.render(<div />, container);
expect(console.error.mock.calls.length).toBe(0);
expect(console.error.calls.length).toBe(0);
});
it('should warn when mounting into document.body', function () {

View File

@ -22,13 +22,10 @@ var ReactTestUtils;
var ReactUpdates;
var reactComponentExpect;
var mocks;
describe('ReactCompositeComponent', function() {
beforeEach(function() {
mocks = require('mocks');
reactComponentExpect = require('reactComponentExpect');
React = require('React');
ReactCurrentOwner = require('ReactCurrentOwner');
@ -71,7 +68,6 @@ describe('ReactCompositeComponent', function() {
},
});
console.error = mocks.getMockFunction();
spyOn(console, 'error');
});

View File

@ -286,6 +286,7 @@ describe('traverseAllChildren', function() {
});
it('should be called for each child in an iterable without keys', function() {
spyOn(console, 'error');
var threeDivIterable = {
'@@iterator': function() {
var i = 0;
@ -332,6 +333,8 @@ describe('traverseAllChildren', function() {
'.2'
);
expect(console.error.calls.length).toBe(1);
expect(console.error.calls[0].args[0]).toContain('Warning: Each child in an array or iterator should have a unique "key" prop.');
});
it('should be called for each child in an iterable with keys', function() {

View File

@ -15,7 +15,6 @@ var React;
var ReactTestUtils;
var mocks;
var warn;
describe('ReactTestUtils', function() {
@ -24,13 +23,6 @@ describe('ReactTestUtils', function() {
React = require('React');
ReactTestUtils = require('ReactTestUtils');
warn = console.error;
console.error = mocks.getMockFunction();
});
afterEach(function() {
console.error = warn;
});
it('should have shallow rendering', function() {

View File

@ -14,11 +14,11 @@
'lib/postDataToURL.browser.js',
'lib/reportTestResults.browser.js',
'lib/jasmine-execute.js',
'../build/react.js',
'../build/react-test.js',
'the-files-to-test.generated.js',
'lib/jasmine-execute.js'
'the-files-to-test.generated.js'
];
if (typeof Function.prototype.bind == 'undefined') {

View File

@ -16,4 +16,32 @@ document.write('<style> @import \'../vendor/jasmine/jasmine.css?_=' + (+new Date
window.onload = function() {
env.execute();
};
var oldError = console.error;
var newError = function() {
oldError.apply(this, arguments);
var spec = env.currentSpec;
if (spec) {
var expectationResult = new jasmine.ExpectationResult({
passed: false,
message:
'Expected test not to warn. If the warning is expected, mock it ' +
'out using spyOn(console, \'error\'); and test that the warning ' +
'occurs.',
});
spec.addMatcherResult(expectationResult);
}
};
console.error = newError;
// Make sure console.error is set back at the end of each test, or else the
// above logic won't work
env.afterEach(function() {
if (console.error !== newError && !console.error.isSpy) {
var expectationResult = new jasmine.ExpectationResult({
passed: false,
message: 'Test did not tear down console.error mock properly.',
});
env.currentSpec.addMatcherResult(expectationResult);
}
});
})(jasmine.getEnv());