Skip to content

Commit

Permalink
Convert createReactClassIntegration-test to createRoot
Browse files Browse the repository at this point in the history
  • Loading branch information
kassens committed Jan 9, 2024
1 parent 31603f1 commit a6b3226
Showing 1 changed file with 108 additions and 56 deletions.
164 changes: 108 additions & 56 deletions packages/react/src/__tests__/createReactClassIntegration-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -318,7 +321,10 @@ describe('create-react-class-integration', () => {
});

const container = document.createElement('div');
ReactDOM.render(<Outer />, container);
const root = ReactDOMClient.createRoot(container);
await act(() => {
root.render(<Outer />);
});
expect(container.firstChild.className).toBe('foo');
});

Expand Down Expand Up @@ -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 {
Expand All @@ -404,23 +410,26 @@ describe('create-react-class-integration', () => {
});

const container = document.createElement('div');
const instance = ReactDOM.render(
<div>
<Component incrementBy={0} />
</div>,
container,
);
expect(instance.textContent).toEqual('count:1');
ReactDOM.render(
<div>
<Component incrementBy={2} />
</div>,
container,
);
expect(instance.textContent).toEqual('count:3');
const root = ReactDOMClient.createRoot(container);
await act(() => {
root.render(
<div>
<Component incrementBy={0} />
</div>,
);
});
expect(container.firstChild.textContent).toEqual('count:1');
await act(() => {
root.render(
<div>
<Component incrementBy={2} />
</div>,
);
});
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: {
Expand All @@ -438,11 +447,14 @@ describe('create-react-class-integration', () => {
return null;
},
});
ReactDOM.render(<Component />, document.createElement('div'));
const root = ReactDOMClient.createRoot(document.createElement('div'));
await act(() => {
root.render(<Component />);
});
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() {
Expand All @@ -452,15 +464,18 @@ describe('create-react-class-integration', () => {
return <div />;
},
});
expect(() =>
ReactDOM.render(<Foo foo="foo" />, document.createElement('div')),
).toErrorDev(
await expect(async () => {
const root = ReactDOMClient.createRoot(document.createElement('div'));
await act(() => {
root.render(<Foo foo="foo" />);
});
}).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() {
Expand All @@ -470,15 +485,18 @@ describe('create-react-class-integration', () => {
return <div />;
},
});
expect(() =>
ReactDOM.render(<Foo foo="foo" />, document.createElement('div')),
).toErrorDev(
await expect(async () => {
const root = ReactDOMClient.createRoot(document.createElement('div'));
await act(() => {
root.render(<Foo foo="foo" />);
});
}).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: {
Expand All @@ -490,15 +508,18 @@ describe('create-react-class-integration', () => {
return <div />;
},
});
expect(() =>
ReactDOM.render(<Foo foo="foo" />, document.createElement('div')),
).toErrorDev(
await expect(async () => {
const root = ReactDOMClient.createRoot(document.createElement('div'));
await act(() => {
root.render(<Foo foo="foo" />);
});
}).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: {
Expand All @@ -510,17 +531,20 @@ describe('create-react-class-integration', () => {
return null;
},
});
expect(() =>
ReactDOM.render(<Component />, document.createElement('div')),
).toErrorDev(
await expect(async () => {
const root = ReactDOMClient.createRoot(document.createElement('div'));
await act(() => {
root.render(<Component />);
});
}).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`. ' +
'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
);
});

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 () {
Expand All @@ -544,9 +568,12 @@ describe('create-react-class-integration', () => {
},
});

expect(() => {
expect(() => {
ReactDOM.render(<Component />, document.createElement('div'));
await expect(async () => {
await expect(async () => {
const root = ReactDOMClient.createRoot(document.createElement('div'));
await act(() => {
root.render(<Component />);
});
}).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' +
Expand All @@ -564,10 +591,13 @@ describe('create-react-class-integration', () => {
],
{withoutStack: true},
);
ReactDOM.render(<Component foo={1} />, document.createElement('div'));
const root = ReactDOMClient.createRoot(document.createElement('div'));
await act(() => {
root.render(<Component foo={1} />);
});
});

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;
Expand All @@ -587,9 +617,12 @@ describe('create-react-class-integration', () => {
},
});

expect(() => {
expect(() => {
ReactDOM.render(<Component />, document.createElement('div'));
await expect(async () => {
await expect(async () => {
const root = ReactDOMClient.createRoot(document.createElement('div'));
await act(() => {
root.render(<Component />);
});
}).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' +
Expand All @@ -607,10 +640,13 @@ describe('create-react-class-integration', () => {
],
{withoutStack: true},
);
ReactDOM.render(<Component foo={1} />, document.createElement('div'));
await act(() => {
const root2 = ReactDOMClient.createRoot(document.createElement('div'));
root2.render(<Component foo={1} />);
});
});

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({
Expand Down Expand Up @@ -641,8 +677,13 @@ describe('create-react-class-integration', () => {
},
});

const div = document.createElement('div');
expect(() => ReactDOM.render(<Component foo="bar" />, div)).toWarnDev(
const root = ReactDOMClient.createRoot(document.createElement('div'));

await expect(async () => {
await act(() => {
root.render(<Component foo="bar" />);
});
}).toWarnDev(
[
'componentWillMount has been renamed',
'componentWillReceiveProps has been renamed',
Expand All @@ -654,7 +695,9 @@ describe('create-react-class-integration', () => {

log.length = 0;

ReactDOM.render(<Component foo="baz" />, div);
await act(() => {
root.render(<Component foo="baz" />);
});
expect(log).toEqual([
'componentWillReceiveProps',
'UNSAFE_componentWillReceiveProps',
Expand All @@ -663,7 +706,7 @@ describe('create-react-class-integration', () => {
]);
});

it('isMounted works', () => {
it('isMounted works', async () => {
const ops = [];
let instance;
const Component = createReactClass({
Expand Down Expand Up @@ -716,19 +759,28 @@ describe('create-react-class-integration', () => {
},
});

const container = document.createElement('div');
const root = ReactDOMClient.createRoot(document.createElement('div'));

expect(() => ReactDOM.render(<Component />, container)).toErrorDev(
await expect(async () => {
await act(() => {
root.render(<Component />);
});
}).toErrorDev(
'Warning: MyComponent: isMounted is deprecated. Instead, make sure to ' +
'clean up subscriptions and pending requests in componentWillUnmount ' +
'to prevent memory leaks.',
{withoutStack: true},
);

// Dedupe
ReactDOM.render(<Component />, container);

ReactDOM.unmountComponentAtNode(container);
await act(() => {
root.render(<Component />);
});

await act(() => {
root.unmount();
});
instance.log('after unmount');
expect(ops).toEqual([
'getInitialState: false',
Expand Down

0 comments on commit a6b3226

Please sign in to comment.