From c22153e25a7e9824a9d3059f1b92e9130395506d Mon Sep 17 00:00:00 2001 From: Ben Alpert Date: Wed, 24 Jun 2015 23:51:27 -0700 Subject: [PATCH] Fail tests on any un-spied warnings Fixes #3890. --- .../__tests__/ReactTypeScriptClass-test.ts | 49 +++++++++---------- .../dom/client/__tests__/ReactMount-test.js | 11 ++--- .../__tests__/ReactCompositeComponent-test.js | 4 -- .../__tests__/traverseAllChildren-test.js | 3 ++ src/test/__tests__/ReactTestUtils-test.js | 8 --- test/index.html | 4 +- test/lib/jasmine-execute.js | 28 +++++++++++ 7 files changed, 60 insertions(+), 47 deletions(-) diff --git a/src/isomorphic/modern/class/__tests__/ReactTypeScriptClass-test.ts b/src/isomorphic/modern/class/__tests__/ReactTypeScriptClass-test.ts index cb94cdc68a..a92eefda9a 100644 --- a/src/isomorphic/modern/class/__tests__/ReactTypeScriptClass-test.ts +++ b/src/isomorphic/modern/class/__tests__/ReactTypeScriptClass-test.ts @@ -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((console.error).argsForCall.length).toBe(1); + expect((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((console.error).argsForCall.length).toBe(4); + expect((console.error).argsForCall[0][0]).toContain( 'getInitialState was defined on ClassicProperties, ' + 'a plain JavaScript class.' ); - expect(warn.mock.calls[1][0]).toContain( + expect((console.error).argsForCall[1][0]).toContain( 'getDefaultProps was defined on ClassicProperties, ' + 'a plain JavaScript class.' ); - expect(warn.mock.calls[2][0]).toContain( + expect((console.error).argsForCall[2][0]).toContain( 'propTypes was defined as an instance property on ClassicProperties.' ); - expect(warn.mock.calls[3][0]).toContain( + expect((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((console.error).argsForCall.length).toBe(1); + expect((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((console.error).argsForCall.length).toBe(1); + expect((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((console.error).argsForCall.length).toBe(5); + expect((console.error).argsForCall[0][0]).toContain( 'getDOMNode(...) is deprecated in plain JavaScript React classes' ); - expect(warn.mock.calls[1][0]).toContain( + expect((console.error).argsForCall[1][0]).toContain( 'replaceState(...) is deprecated in plain JavaScript React classes' ); - expect(warn.mock.calls[2][0]).toContain( + expect((console.error).argsForCall[2][0]).toContain( 'isMounted(...) is deprecated in plain JavaScript React classes' ); - expect(warn.mock.calls[3][0]).toContain( + expect((console.error).argsForCall[3][0]).toContain( 'setProps(...) is deprecated in plain JavaScript React classes' ); - expect(warn.mock.calls[4][0]).toContain( + expect((console.error).argsForCall[4][0]).toContain( 'replaceProps(...) is deprecated in plain JavaScript React classes' ); }); diff --git a/src/renderers/dom/client/__tests__/ReactMount-test.js b/src/renderers/dom/client/__tests__/ReactMount-test.js index 4da0abe11d..d5700df411 100644 --- a/src/renderers/dom/client/__tests__/ReactMount-test.js +++ b/src/renderers/dom/client/__tests__/ReactMount-test.js @@ -124,24 +124,23 @@ describe('ReactMount', function() { var container = document.createElement('container'); container.innerHTML = React.renderToString(
) + ' '; - console.error = mocks.getMockFunction(); + spyOn(console, 'error'); ReactMount.render(
, container); - expect(console.error.mock.calls.length).toBe(1); + expect(console.error.calls.length).toBe(1); container.innerHTML = ' ' + React.renderToString(
); - console.error = mocks.getMockFunction(); ReactMount.render(
, 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 = '
'; - console.error = mocks.getMockFunction(); + spyOn(console, 'error'); ReactMount.render(
, 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 () { diff --git a/src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js b/src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js index 51d1a739b6..8cd952cd53 100644 --- a/src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js +++ b/src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js @@ -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'); }); diff --git a/src/shared/utils/__tests__/traverseAllChildren-test.js b/src/shared/utils/__tests__/traverseAllChildren-test.js index b3e464059e..1e78ff84e9 100644 --- a/src/shared/utils/__tests__/traverseAllChildren-test.js +++ b/src/shared/utils/__tests__/traverseAllChildren-test.js @@ -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() { diff --git a/src/test/__tests__/ReactTestUtils-test.js b/src/test/__tests__/ReactTestUtils-test.js index f45af53c2d..f038b2f5be 100644 --- a/src/test/__tests__/ReactTestUtils-test.js +++ b/src/test/__tests__/ReactTestUtils-test.js @@ -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() { diff --git a/test/index.html b/test/index.html index 12673a3f32..2a7d460442 100644 --- a/test/index.html +++ b/test/index.html @@ -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') { diff --git a/test/lib/jasmine-execute.js b/test/lib/jasmine-execute.js index 177d55658c..5ddea20f0c 100644 --- a/test/lib/jasmine-execute.js +++ b/test/lib/jasmine-execute.js @@ -16,4 +16,32 @@ document.write('