From d1fc5947a442168b69c40b25d922f17336d56800 Mon Sep 17 00:00:00 2001 From: Sunil Pai Date: Wed, 6 Feb 2019 14:53:10 +0000 Subject: [PATCH 1/4] warn when using TestUtils.act in node --- .../src/test-utils/ReactTestUtils.js | 21 ++++++++++++++++--- .../ReactTestRenderer-test.internal.js | 9 +++++++- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/packages/react-dom/src/test-utils/ReactTestUtils.js b/packages/react-dom/src/test-utils/ReactTestUtils.js index dcb20d88cf9f7..ad79a80ffb4f8 100644 --- a/packages/react-dom/src/test-utils/ReactTestUtils.js +++ b/packages/react-dom/src/test-utils/ReactTestUtils.js @@ -151,8 +151,8 @@ function validateClassInstance(inst, methodName) { ); } -// stub element used by act() when flushing effects -let actContainerElement = document.createElement('div'); +// a stub element, lazily initialized, used by act() when flushing effects +let actContainerElement = null; /** * Utilities for making it easy to test React components. @@ -391,9 +391,24 @@ const ReactTestUtils = { SimulateNative: {}, act(callback: () => void): Thenable { + if (actContainerElement === null) { + // first, test whether we can actually create the stub element + invariant( + typeof document !== 'undefined' && + document !== null && + typeof document.createElement === 'function', + 'It looks like you called TestUtils.act() in a non-browser-like environment' + + "(like node.js). This is not supported. If you're using" + + 'TestRenderer for your tests, you should call ' + + 'TestRenderer.act(...) instead of TestUtils.act(...).', + ); + // then make it + actContainerElement = document.createElement('div'); + } + + const result = ReactDOM.unstable_batchedUpdates(callback); // note: keep these warning messages in sync with // createReactNoop.js and ReactTestRenderer.js - const result = ReactDOM.unstable_batchedUpdates(callback); if (__DEV__) { if (result !== undefined) { let addendum; diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js index 0ca6fb54b50a9..9ee15295cb24b 100644 --- a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js +++ b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js @@ -1023,7 +1023,7 @@ describe('ReactTestRenderer', () => { }); describe('act', () => { - it('works', () => { + it('can use .act() to batch updates and effects', () => { function App(props) { React.useEffect(() => { props.callback(); @@ -1043,5 +1043,12 @@ describe('ReactTestRenderer', () => { expect(called).toBe(true); }); + it('warns if you use TestUtils.act instead of TestRenderer.act in node', () => { + jest.resetModules(); + const {act} = require('react-dom/test-utils'); + expect(() => act(() => {})).toThrow( + 'It looks like you called TestUtils.act() in a non-browser-like environment(like node.js)', + ); + }); }); }); From 65b908a805f78c53f242304ecdb3fd597b8907ec Mon Sep 17 00:00:00 2001 From: Sunil Pai Date: Wed, 6 Feb 2019 15:27:44 +0000 Subject: [PATCH 2/4] s/warns/throws --- .../src/__tests__/ReactTestRenderer-test.internal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js index 9ee15295cb24b..1883ac18babac 100644 --- a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js +++ b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js @@ -1043,7 +1043,7 @@ describe('ReactTestRenderer', () => { expect(called).toBe(true); }); - it('warns if you use TestUtils.act instead of TestRenderer.act in node', () => { + it('throws if you use TestUtils.act instead of TestRenderer.act in node', () => { jest.resetModules(); const {act} = require('react-dom/test-utils'); expect(() => act(() => {})).toThrow( From f3c38c3c99ade4141c52d9baff25e5cbbdf9c590 Mon Sep 17 00:00:00 2001 From: Sunil Pai Date: Wed, 6 Feb 2019 15:53:36 +0000 Subject: [PATCH 3/4] s/throw/warn --- .../src/test-utils/ReactTestUtils.js | 21 ++++++++++--------- .../ReactTestRenderer-test.internal.js | 13 +++++++++--- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/packages/react-dom/src/test-utils/ReactTestUtils.js b/packages/react-dom/src/test-utils/ReactTestUtils.js index ad79a80ffb4f8..db4fe9e12b358 100644 --- a/packages/react-dom/src/test-utils/ReactTestUtils.js +++ b/packages/react-dom/src/test-utils/ReactTestUtils.js @@ -392,16 +392,17 @@ const ReactTestUtils = { act(callback: () => void): Thenable { if (actContainerElement === null) { - // first, test whether we can actually create the stub element - invariant( - typeof document !== 'undefined' && - document !== null && - typeof document.createElement === 'function', - 'It looks like you called TestUtils.act() in a non-browser-like environment' + - "(like node.js). This is not supported. If you're using" + - 'TestRenderer for your tests, you should call ' + - 'TestRenderer.act(...) instead of TestUtils.act(...).', - ); + // warn if we can't actually create the stub element + if (__DEV__) { + warningWithoutStack( + typeof document !== 'undefined' && + document !== null && + typeof document.createElement === 'function', + 'It looks like you called TestUtils.act() in a non-browser environment. ' + + "If you're using TestRenderer for your tests, you should call " + + 'TestRenderer.act(...) instead of TestUtils.act(...).', + ); + } // then make it actContainerElement = document.createElement('div'); } diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js index 1883ac18babac..dab6700ebae76 100644 --- a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js +++ b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js @@ -1043,11 +1043,18 @@ describe('ReactTestRenderer', () => { expect(called).toBe(true); }); - it('throws if you use TestUtils.act instead of TestRenderer.act in node', () => { + it('warns and throws if you use TestUtils.act instead of TestRenderer.act in node', () => { + // we warn when you try to load 2 renderers in the same 'scope' + // so as suggested, we call resetModules() to carry on with the test jest.resetModules(); const {act} = require('react-dom/test-utils'); - expect(() => act(() => {})).toThrow( - 'It looks like you called TestUtils.act() in a non-browser-like environment(like node.js)', + expect(() => { + expect(() => act(() => {})).toThrow('document is not defined'); + }).toWarnDev( + [ + 'It looks like you called TestUtils.act() in a non-browser environment', + ], + {withoutStack: 1}, ); }); }); From 66f8e6633e6f25204dbaa4955b34754e9b5f6979 Mon Sep 17 00:00:00 2001 From: Sunil Pai Date: Wed, 6 Feb 2019 15:58:52 +0000 Subject: [PATCH 4/4] consistent ellipses --- packages/react-dom/src/test-utils/ReactTestUtils.js | 2 +- .../src/__tests__/ReactTestRenderer-test.internal.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-dom/src/test-utils/ReactTestUtils.js b/packages/react-dom/src/test-utils/ReactTestUtils.js index db4fe9e12b358..649598c759a15 100644 --- a/packages/react-dom/src/test-utils/ReactTestUtils.js +++ b/packages/react-dom/src/test-utils/ReactTestUtils.js @@ -398,7 +398,7 @@ const ReactTestUtils = { typeof document !== 'undefined' && document !== null && typeof document.createElement === 'function', - 'It looks like you called TestUtils.act() in a non-browser environment. ' + + 'It looks like you called TestUtils.act(...) in a non-browser environment. ' + "If you're using TestRenderer for your tests, you should call " + 'TestRenderer.act(...) instead of TestUtils.act(...).', ); diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js index dab6700ebae76..1ce786c27b8cd 100644 --- a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js +++ b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js @@ -1052,7 +1052,7 @@ describe('ReactTestRenderer', () => { expect(() => act(() => {})).toThrow('document is not defined'); }).toWarnDev( [ - 'It looks like you called TestUtils.act() in a non-browser environment', + 'It looks like you called TestUtils.act(...) in a non-browser environment', ], {withoutStack: 1}, );