@samitouri / QOS-React-1 / commits / 37bdff675c

Convert ReactIdentity-test.js to createRoot (#28106)

Matt Carroll committed Jan 26, 2024 at 13:18 UTC 37bdff675c28e247333ffe35055534ad94941e8c
1 file changed +70 -49
packages/react-dom/src/__tests__/ReactIdentity-test.js
+70 -49
@@ -10,18 +10,20 @@
10 'use strict';
11
12 let React;
13 -let ReactDOM;
13 +let ReactDOMClient;
14 let ReactTestUtils;
15 +let act;
16
17 describe('ReactIdentity', () => {
18 beforeEach(() => {
19 jest.resetModules();
20 React = require('react');
20 - ReactDOM = require('react-dom');
21 + ReactDOMClient = require('react-dom/client');
22 ReactTestUtils = require('react-dom/test-utils');
23 + act = require('internal-test-utils').act;
24 });
25
24 - it('should allow key property to express identity', () => {
26 + it('should allow key property to express identity', async () => {
27 let node;
28 const Component = props => (
29 <div ref={c => (node = c)}>
@@ -31,15 +33,20 @@ describe('ReactIdentity', () => {
33 );
34
35 const container = document.createElement('div');
34 - ReactDOM.render(<Component />, container);
36 + const root = ReactDOMClient.createRoot(container);
37 + await act(async () => {
38 + root.render(<Component />);
39 + });
40 const origChildren = Array.from(node.childNodes);
36 - ReactDOM.render(<Component swap={true} />, container);
41 + await act(async () => {
42 + root.render(<Component swap={true} />);
43 + });
44 const newChildren = Array.from(node.childNodes);
45 expect(origChildren[0]).toBe(newChildren[1]);
46 expect(origChildren[1]).toBe(newChildren[0]);
47 });
48
42 - it('should use composite identity', () => {
49 + it('should use composite identity', async () => {
50 class Wrapper extends React.Component {
51 render() {
52 return <a>{this.props.children}</a>;
@@ -47,25 +54,27 @@ describe('ReactIdentity', () => {
54 }
55
56 const container = document.createElement('div');
57 + const root = ReactDOMClient.createRoot(container);
58 let node1;
59 let node2;
52 - ReactDOM.render(
53 - <Wrapper key="wrap1">
54 - <span ref={c => (node1 = c)} />
55 - </Wrapper>,
56 - container,
57 - );
58 - ReactDOM.render(
59 - <Wrapper key="wrap2">
60 - <span ref={c => (node2 = c)} />
61 - </Wrapper>,
62 - container,
63 - );
64 -
60 + await act(async () => {
61 + root.render(
62 + <Wrapper key="wrap1">
63 + <span ref={c => (node1 = c)} />
64 + </Wrapper>,
65 + );
66 + });
67 + await act(async () => {
68 + root.render(
69 + <Wrapper key="wrap2">
70 + <span ref={c => (node2 = c)} />
71 + </Wrapper>,
72 + );
73 + });
74 expect(node1).not.toBe(node2);
75 });
76
68 - function renderAComponentWithKeyIntoContainer(key, container) {
77 + async function renderAComponentWithKeyIntoContainer(key, root) {
78 class Wrapper extends React.Component {
79 spanRef = React.createRef();
80 render() {
@@ -76,36 +85,41 @@ describe('ReactIdentity', () => {
85 );
86 }
87 }
79 -
80 - const instance = ReactDOM.render(<Wrapper />, container);
81 - const span = instance.spanRef.current;
88 + const wrapperRef = React.createRef();
89 + await act(async () => {
90 + root.render(<Wrapper ref={wrapperRef} />);
91 + });
92 + const span = wrapperRef.current.spanRef.current;
93 expect(span).not.toBe(null);
94 }
95
85 - it('should allow any character as a key, in a detached parent', () => {
96 + it('should allow any character as a key, in a detached parent', async () => {
97 const detachedContainer = document.createElement('div');
87 - renderAComponentWithKeyIntoContainer("<'WEIRD/&\\key'>", detachedContainer);
98 + const root = ReactDOMClient.createRoot(detachedContainer);
99 + await renderAComponentWithKeyIntoContainer("<'WEIRD/&\\key'>", root);
100 });
101
90 - it('should allow any character as a key, in an attached parent', () => {
102 + it('should allow any character as a key, in an attached parent', async () => {
103 // This test exists to protect against implementation details that
104 // incorrectly query escaped IDs using DOM tools like getElementById.
105 const attachedContainer = document.createElement('div');
106 + const root = ReactDOMClient.createRoot(attachedContainer);
107 document.body.appendChild(attachedContainer);
108
96 - renderAComponentWithKeyIntoContainer("<'WEIRD/&\\key'>", attachedContainer);
109 + await renderAComponentWithKeyIntoContainer("<'WEIRD/&\\key'>", root);
110
111 document.body.removeChild(attachedContainer);
112 });
113
101 - it('should not allow scripts in keys to execute', () => {
114 + it('should not allow scripts in keys to execute', async () => {
115 const h4x0rKey =
116 '"><script>window[\'YOUVEBEENH4X0RED\']=true;</script><div id="';
117
118 const attachedContainer = document.createElement('div');
119 + const root = ReactDOMClient.createRoot(attachedContainer);
120 document.body.appendChild(attachedContainer);
121
108 - renderAComponentWithKeyIntoContainer(h4x0rKey, attachedContainer);
122 + await renderAComponentWithKeyIntoContainer(h4x0rKey, root);
123
124 document.body.removeChild(attachedContainer);
125
@@ -209,7 +223,7 @@ describe('ReactIdentity', () => {
223 }).not.toThrow();
224 });
225
212 - it('should retain key during updates in composite components', () => {
226 + it('should retain key during updates in composite components', async () => {
227 class TestComponent extends React.Component {
228 render() {
229 return <div>{this.props.children}</div>;
@@ -236,16 +250,23 @@ describe('ReactIdentity', () => {
250 const instance0 = <span key="A" />;
251 const instance1 = <span key="B" />;
252
239 - let wrapped = <TestContainer first={instance0} second={instance1} />;
240 -
241 - wrapped = ReactDOM.render(wrapped, document.createElement('div'));
242 - const div = ReactDOM.findDOMNode(wrapped);
253 + const container = document.createElement('div');
254 + const root = ReactDOMClient.createRoot(container);
255 + const wrappedRef = React.createRef();
256 + await act(async () => {
257 + root.render(
258 + <TestContainer first={instance0} second={instance1} ref={wrappedRef} />,
259 + );
260 + });
261 + const div = container.firstChild;
262
244 - const beforeA = div.childNodes[0];
245 - const beforeB = div.childNodes[1];
246 - wrapped.swap();
247 - const afterA = div.childNodes[1];
248 - const afterB = div.childNodes[0];
263 + const beforeA = div.firstChild;
264 + const beforeB = div.lastChild;
265 + await act(async () => {
266 + wrappedRef.current.swap();
267 + });
268 + const afterA = div.lastChild;
269 + const afterB = div.firstChild;
270
271 expect(beforeA).toBe(afterA);
272 expect(beforeB).toBe(afterB);
@@ -264,7 +285,7 @@ describe('ReactIdentity', () => {
285 }).not.toThrow();
286 });
287
267 - it('should throw if key is a Temporal-like object', () => {
288 + it('should throw if key is a Temporal-like object', async () => {
289 class TemporalLike {
290 valueOf() {
291 // Throwing here is the behavior of ECMAScript "Temporal" date/time API.
@@ -277,15 +298,15 @@ describe('ReactIdentity', () => {
298 }
299
300 const el = document.createElement('div');
280 - const test = () =>
281 - ReactDOM.render(
282 - <div>
283 - <span key={new TemporalLike()} />
284 - </div>,
285 - el,
286 - );
287 - expect(() =>
288 - expect(test).toThrowError(new TypeError('prod message')),
301 + const root = ReactDOMClient.createRoot(el);
302 + await expect(() =>
303 + expect(() => {
304 + root.render(
305 + <div>
306 + <span key={new TemporalLike()} />
307 + </div>,
308 + );
309 + }).toThrowError(new TypeError('prod message')),
310 ).toErrorDev(
311 'The provided key is an unsupported type TemporalLike.' +
312 ' This value must be coerced to a string before using it here.',