From a6b3226cc6f9c3366767c72ee8874b66ee382d43 Mon Sep 17 00:00:00 2001 From: Jan Kassens Date: Tue, 9 Jan 2024 13:53:45 -0500 Subject: [PATCH] Convert createReactClassIntegration-test to createRoot --- .../createReactClassIntegration-test.js | 164 ++++++++++++------ 1 file changed, 108 insertions(+), 56 deletions(-) diff --git a/packages/react/src/__tests__/createReactClassIntegration-test.js b/packages/react/src/__tests__/createReactClassIntegration-test.js index b907fafea64f..dff9042a1bd2 100644 --- a/packages/react/src/__tests__/createReactClassIntegration-test.js +++ b/packages/react/src/__tests__/createReactClassIntegration-test.js @@ -9,18 +9,21 @@ 'use strict'; +let act; + let PropTypes; let React; -let ReactDOM; +let ReactDOMClient; let ReactTestUtils; let createReactClass; describe('create-react-class-integration', () => { beforeEach(() => { jest.resetModules(); + ({act} = require('internal-test-utils')); PropTypes = require('prop-types'); React = require('react'); - ReactDOM = require('react-dom'); + ReactDOMClient = require('react-dom/client'); ReactTestUtils = require('react-dom/test-utils'); createReactClass = require('create-react-class/factory')( React.Component, @@ -292,7 +295,7 @@ describe('create-react-class-integration', () => { }); // @gate !disableLegacyContext - it('renders based on context getInitialState', () => { + it('renders based on context getInitialState', async () => { const Foo = createReactClass({ contextTypes: { className: PropTypes.string, @@ -318,7 +321,10 @@ describe('create-react-class-integration', () => { }); const container = document.createElement('div'); - ReactDOM.render(, container); + const root = ReactDOMClient.createRoot(container); + await act(() => { + root.render(); + }); expect(container.firstChild.className).toBe('foo'); }); @@ -388,7 +394,7 @@ describe('create-react-class-integration', () => { expect(ops).toEqual(['Render: 0', 'Render: 1', 'Callback: 1']); }); - it('getDerivedStateFromProps updates state when props change', () => { + it('getDerivedStateFromProps updates state when props change', async () => { const Component = createReactClass({ getInitialState() { return { @@ -404,23 +410,26 @@ describe('create-react-class-integration', () => { }); const container = document.createElement('div'); - const instance = ReactDOM.render( -
- -
, - container, - ); - expect(instance.textContent).toEqual('count:1'); - ReactDOM.render( -
- -
, - container, - ); - expect(instance.textContent).toEqual('count:3'); + const root = ReactDOMClient.createRoot(container); + await act(() => { + root.render( +
+ +
, + ); + }); + expect(container.firstChild.textContent).toEqual('count:1'); + await act(() => { + root.render( +
+ +
, + ); + }); + expect(container.firstChild.textContent).toEqual('count:3'); }); - it('should support the new static getDerivedStateFromProps method', () => { + it('should support the new static getDerivedStateFromProps method', async () => { let instance; const Component = createReactClass({ statics: { @@ -438,11 +447,14 @@ describe('create-react-class-integration', () => { return null; }, }); - ReactDOM.render(, document.createElement('div')); + const root = ReactDOMClient.createRoot(document.createElement('div')); + await act(() => { + root.render(); + }); expect(instance.state.foo).toBe('bar'); }); - it('warns if getDerivedStateFromProps is not static', () => { + it('warns if getDerivedStateFromProps is not static', async () => { const Foo = createReactClass({ displayName: 'Foo', getDerivedStateFromProps() { @@ -452,15 +464,18 @@ describe('create-react-class-integration', () => { return
; }, }); - expect(() => - ReactDOM.render(, document.createElement('div')), - ).toErrorDev( + await expect(async () => { + const root = ReactDOMClient.createRoot(document.createElement('div')); + await act(() => { + root.render(); + }); + }).toErrorDev( 'Foo: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', ); }); - it('warns if getDerivedStateFromError is not static', () => { + it('warns if getDerivedStateFromError is not static', async () => { const Foo = createReactClass({ displayName: 'Foo', getDerivedStateFromError() { @@ -470,15 +485,18 @@ describe('create-react-class-integration', () => { return
; }, }); - expect(() => - ReactDOM.render(, document.createElement('div')), - ).toErrorDev( + await expect(async () => { + const root = ReactDOMClient.createRoot(document.createElement('div')); + await act(() => { + root.render(); + }); + }).toErrorDev( 'Foo: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', ); }); - it('warns if getSnapshotBeforeUpdate is static', () => { + it('warns if getSnapshotBeforeUpdate is static', async () => { const Foo = createReactClass({ displayName: 'Foo', statics: { @@ -490,15 +508,18 @@ describe('create-react-class-integration', () => { return
; }, }); - expect(() => - ReactDOM.render(, document.createElement('div')), - ).toErrorDev( + await expect(async () => { + const root = ReactDOMClient.createRoot(document.createElement('div')); + await act(() => { + root.render(); + }); + }).toErrorDev( 'Foo: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', ); }); - it('should warn if state is not properly initialized before getDerivedStateFromProps', () => { + it('should warn if state is not properly initialized before getDerivedStateFromProps', async () => { const Component = createReactClass({ displayName: 'Component', statics: { @@ -510,9 +531,12 @@ describe('create-react-class-integration', () => { return null; }, }); - expect(() => - ReactDOM.render(, document.createElement('div')), - ).toErrorDev( + await expect(async () => { + const root = ReactDOMClient.createRoot(document.createElement('div')); + await act(() => { + root.render(); + }); + }).toErrorDev( '`Component` uses `getDerivedStateFromProps` but its initial state is ' + 'null. This is not recommended. Instead, define the initial state by ' + 'assigning an object to `this.state` in the constructor of `Component`. ' + @@ -520,7 +544,7 @@ describe('create-react-class-integration', () => { ); }); - it('should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new static gDSFP is present', () => { + it('should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new static gDSFP is present', async () => { const Component = createReactClass({ statics: { getDerivedStateFromProps: function () { @@ -544,9 +568,12 @@ describe('create-react-class-integration', () => { }, }); - expect(() => { - expect(() => { - ReactDOM.render(, document.createElement('div')); + await expect(async () => { + await expect(async () => { + const root = ReactDOMClient.createRoot(document.createElement('div')); + await act(() => { + root.render(); + }); }).toErrorDev( 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' + 'Component uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' + @@ -564,10 +591,13 @@ describe('create-react-class-integration', () => { ], {withoutStack: true}, ); - ReactDOM.render(, document.createElement('div')); + const root = ReactDOMClient.createRoot(document.createElement('div')); + await act(() => { + root.render(); + }); }); - it('should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new getSnapshotBeforeUpdate is present', () => { + it('should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new getSnapshotBeforeUpdate is present', async () => { const Component = createReactClass({ getSnapshotBeforeUpdate: function () { return null; @@ -587,9 +617,12 @@ describe('create-react-class-integration', () => { }, }); - expect(() => { - expect(() => { - ReactDOM.render(, document.createElement('div')); + await expect(async () => { + await expect(async () => { + const root = ReactDOMClient.createRoot(document.createElement('div')); + await act(() => { + root.render(); + }); }).toErrorDev( 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' + 'Component uses getSnapshotBeforeUpdate() but also contains the following legacy lifecycles:\n' + @@ -607,10 +640,13 @@ describe('create-react-class-integration', () => { ], {withoutStack: true}, ); - ReactDOM.render(, document.createElement('div')); + await act(() => { + const root2 = ReactDOMClient.createRoot(document.createElement('div')); + root2.render(); + }); }); - it('should invoke both deprecated and new lifecycles if both are present', () => { + it('should invoke both deprecated and new lifecycles if both are present', async () => { const log = []; const Component = createReactClass({ @@ -641,8 +677,13 @@ describe('create-react-class-integration', () => { }, }); - const div = document.createElement('div'); - expect(() => ReactDOM.render(, div)).toWarnDev( + const root = ReactDOMClient.createRoot(document.createElement('div')); + + await expect(async () => { + await act(() => { + root.render(); + }); + }).toWarnDev( [ 'componentWillMount has been renamed', 'componentWillReceiveProps has been renamed', @@ -654,7 +695,9 @@ describe('create-react-class-integration', () => { log.length = 0; - ReactDOM.render(, div); + await act(() => { + root.render(); + }); expect(log).toEqual([ 'componentWillReceiveProps', 'UNSAFE_componentWillReceiveProps', @@ -663,7 +706,7 @@ describe('create-react-class-integration', () => { ]); }); - it('isMounted works', () => { + it('isMounted works', async () => { const ops = []; let instance; const Component = createReactClass({ @@ -716,9 +759,13 @@ describe('create-react-class-integration', () => { }, }); - const container = document.createElement('div'); + const root = ReactDOMClient.createRoot(document.createElement('div')); - expect(() => ReactDOM.render(, container)).toErrorDev( + await expect(async () => { + await act(() => { + root.render(); + }); + }).toErrorDev( 'Warning: MyComponent: isMounted is deprecated. Instead, make sure to ' + 'clean up subscriptions and pending requests in componentWillUnmount ' + 'to prevent memory leaks.', @@ -726,9 +773,14 @@ describe('create-react-class-integration', () => { ); // Dedupe - ReactDOM.render(, container); - ReactDOM.unmountComponentAtNode(container); + await act(() => { + root.render(); + }); + + await act(() => { + root.unmount(); + }); instance.log('after unmount'); expect(ops).toEqual([ 'getInitialState: false',