1111
1212let React ;
1313let ReactDOM ;
14- let ReactTestUtils ;
14+ let ReactDOMClient ;
1515let PropTypes ;
16+ let act ;
1617
1718describe ( 'ReactLegacyCompositeComponent' , ( ) => {
1819 beforeEach ( ( ) => {
1920 jest . resetModules ( ) ;
2021 React = require ( 'react' ) ;
2122 ReactDOM = require ( 'react-dom' ) ;
22- ReactTestUtils = require ( 'react-dom/test-utils ' ) ;
23+ ReactDOMClient = require ( 'react-dom/client ' ) ;
2324 PropTypes = require ( 'prop-types' ) ;
25+ act = require ( 'internal-test-utils' ) . act ;
2426 } ) ;
2527
2628 it ( 'should warn about `setState` in render in legacy mode' , ( ) => {
@@ -70,7 +72,7 @@ describe('ReactLegacyCompositeComponent', () => {
7072 } ) ;
7173
7274 // @gate !disableLegacyContext
73- it ( 'should pass context to children when not owner' , ( ) => {
75+ it ( 'should pass context to children when not owner' , async ( ) => {
7476 class Parent extends React . Component {
7577 render ( ) {
7678 return (
@@ -106,13 +108,17 @@ describe('ReactLegacyCompositeComponent', () => {
106108 return < div > { this . context . foo } </ div > ;
107109 }
108110 }
109-
110- const component = ReactTestUtils . renderIntoDocument ( < Parent /> ) ;
111+ const container = document . createElement ( 'div' ) ;
112+ const root = ReactDOMClient . createRoot ( container ) ;
113+ let component ;
114+ await act ( ( ) => {
115+ root . render ( < Parent ref = { current => ( component = current ) } /> ) ;
116+ } ) ;
111117 expect ( ReactDOM . findDOMNode ( component ) . innerHTML ) . toBe ( 'bar' ) ;
112118 } ) ;
113119
114120 // @gate !disableLegacyContext
115- it ( 'should pass context when re-rendered for static child' , ( ) => {
121+ it ( 'should pass context when re-rendered for static child' , async ( ) => {
116122 let parentInstance = null ;
117123 let childInstance = null ;
118124
@@ -156,24 +162,31 @@ describe('ReactLegacyCompositeComponent', () => {
156162 }
157163 }
158164
159- parentInstance = ReactTestUtils . renderIntoDocument (
160- < Parent >
161- < Middle >
162- < Child />
163- </ Middle >
164- </ Parent > ,
165- ) ;
165+ const container = document . createElement ( 'div' ) ;
166+ const root = ReactDOMClient . createRoot ( container ) ;
167+
168+ await act ( ( ) => {
169+ root . render (
170+ < Parent ref = { current => ( parentInstance = current ) } >
171+ < Middle >
172+ < Child />
173+ </ Middle >
174+ </ Parent > ,
175+ ) ;
176+ } ) ;
166177
167178 expect ( parentInstance . state . flag ) . toBe ( false ) ;
168179 expect ( childInstance . context ) . toEqual ( { foo : 'bar' , flag : false } ) ;
169180
170- parentInstance . setState ( { flag : true } ) ;
181+ await act ( ( ) => {
182+ parentInstance . setState ( { flag : true } ) ;
183+ } ) ;
171184 expect ( parentInstance . state . flag ) . toBe ( true ) ;
172185 expect ( childInstance . context ) . toEqual ( { foo : 'bar' , flag : true } ) ;
173186 } ) ;
174187
175188 // @gate !disableLegacyContext
176- it ( 'should pass context when re-rendered for static child within a composite component' , ( ) => {
189+ it ( 'should pass context when re-rendered for static child within a composite component' , async ( ) => {
177190 class Parent extends React . Component {
178191 static childContextTypes = {
179192 flag : PropTypes . bool ,
@@ -217,20 +230,27 @@ describe('ReactLegacyCompositeComponent', () => {
217230 }
218231 }
219232
220- const wrapper = ReactTestUtils . renderIntoDocument ( < Wrapper /> ) ;
233+ const container = document . createElement ( 'div' ) ;
234+ const root = ReactDOMClient . createRoot ( container ) ;
235+ let wrapper ;
236+ await act ( ( ) => {
237+ root . render ( < Wrapper ref = { current => ( wrapper = current ) } /> ) ;
238+ } ) ;
221239
222240 expect ( wrapper . parentRef . current . state . flag ) . toEqual ( true ) ;
223241 expect ( wrapper . childRef . current . context ) . toEqual ( { flag : true } ) ;
224242
225243 // We update <Parent /> while <Child /> is still a static prop relative to this update
226- wrapper . parentRef . current . setState ( { flag : false } ) ;
244+ await act ( ( ) => {
245+ wrapper . parentRef . current . setState ( { flag : false } ) ;
246+ } ) ;
227247
228248 expect ( wrapper . parentRef . current . state . flag ) . toEqual ( false ) ;
229249 expect ( wrapper . childRef . current . context ) . toEqual ( { flag : false } ) ;
230250 } ) ;
231251
232252 // @gate !disableLegacyContext
233- it ( 'should pass context transitively' , ( ) => {
253+ it ( 'should pass context transitively' , async ( ) => {
234254 let childInstance = null ;
235255 let grandchildInstance = null ;
236256
@@ -286,13 +306,18 @@ describe('ReactLegacyCompositeComponent', () => {
286306 }
287307 }
288308
289- ReactTestUtils . renderIntoDocument ( < Parent /> ) ;
309+ const container = document . createElement ( 'div' ) ;
310+ const root = ReactDOMClient . createRoot ( container ) ;
311+ await act ( ( ) => {
312+ root . render ( < Parent /> ) ;
313+ } ) ;
314+
290315 expect ( childInstance . context ) . toEqual ( { foo : 'bar' , depth : 0 } ) ;
291316 expect ( grandchildInstance . context ) . toEqual ( { foo : 'bar' , depth : 1 } ) ;
292317 } ) ;
293318
294319 // @gate !disableLegacyContext
295- it ( 'should pass context when re-rendered' , ( ) => {
320+ it ( 'should pass context when re-rendered' , async ( ) => {
296321 let parentInstance = null ;
297322 let childInstance = null ;
298323
@@ -334,11 +359,16 @@ describe('ReactLegacyCompositeComponent', () => {
334359 }
335360 }
336361
337- parentInstance = ReactTestUtils . renderIntoDocument ( < Parent /> ) ;
362+ const container = document . createElement ( 'div' ) ;
363+ const root = ReactDOMClient . createRoot ( container ) ;
364+ await act ( ( ) => {
365+ root . render ( < Parent ref = { current => ( parentInstance = current ) } /> ) ;
366+ } ) ;
367+
338368 expect ( childInstance ) . toBeNull ( ) ;
339369
340370 expect ( parentInstance . state . flag ) . toBe ( false ) ;
341- ReactDOM . unstable_batchedUpdates ( function ( ) {
371+ await act ( ( ) => {
342372 parentInstance . setState ( { flag : true } ) ;
343373 } ) ;
344374 expect ( parentInstance . state . flag ) . toBe ( true ) ;
@@ -699,23 +729,31 @@ describe('ReactLegacyCompositeComponent', () => {
699729 ) ;
700730 } ) ;
701731
702- it ( 'should replace state in legacy mode' , ( ) => {
732+ it ( 'should replace state in legacy mode' , async ( ) => {
703733 class Moo extends React . Component {
704734 state = { x : 1 } ;
705735 render ( ) {
706736 return < div /> ;
707737 }
708738 }
709739
710- const moo = ReactTestUtils . renderIntoDocument ( < Moo /> ) ;
740+ const container = document . createElement ( 'div' ) ;
741+ const root = ReactDOMClient . createRoot ( container ) ;
742+ let moo ;
743+ await act ( ( ) => {
744+ root . render ( < Moo ref = { current => ( moo = current ) } /> ) ;
745+ } ) ;
746+
711747 // No longer a public API, but we can test that it works internally by
712748 // reaching into the updater.
713- moo . updater . enqueueReplaceState ( moo , { y : 2 } ) ;
749+ await act ( ( ) => {
750+ moo . updater . enqueueReplaceState ( moo , { y : 2 } ) ;
751+ } ) ;
714752 expect ( 'x' in moo . state ) . toBe ( false ) ;
715753 expect ( moo . state . y ) . toBe ( 2 ) ;
716754 } ) ;
717755
718- it ( 'should support objects with prototypes as state in legacy mode' , ( ) => {
756+ it ( 'should support objects with prototypes as state in legacy mode' , async ( ) => {
719757 const NotActuallyImmutable = function ( str ) {
720758 this . str = str ;
721759 } ;
@@ -732,32 +770,42 @@ describe('ReactLegacyCompositeComponent', () => {
732770 }
733771 }
734772
735- const moo = ReactTestUtils . renderIntoDocument ( < Moo /> ) ;
773+ const container = document . createElement ( 'div' ) ;
774+ const root = ReactDOMClient . createRoot ( container ) ;
775+ let moo ;
776+ await act ( ( ) => {
777+ root . render ( < Moo ref = { current => ( moo = current ) } /> ) ;
778+ } ) ;
779+
736780 expect ( moo . state . str ) . toBe ( 'first' ) ;
737781 expect ( moo . state . amIImmutable ( ) ) . toBe ( true ) ;
738782
739783 const secondState = new NotActuallyImmutable ( 'second' ) ;
740- moo . _replaceState ( secondState ) ;
784+ await act ( ( ) => {
785+ moo . _replaceState ( secondState ) ;
786+ } ) ;
741787 expect ( moo . state . str ) . toBe ( 'second' ) ;
742788 expect ( moo . state . amIImmutable ( ) ) . toBe ( true ) ;
743789 expect ( moo . state ) . toBe ( secondState ) ;
744790
745- moo . setState ( { str : 'third' } ) ;
791+ await act ( ( ) => {
792+ moo . setState ( { str : 'third' } ) ;
793+ } ) ;
746794 expect ( moo . state . str ) . toBe ( 'third' ) ;
747795 // Here we lose the prototype.
748796 expect ( moo . state . amIImmutable ) . toBe ( undefined ) ;
749797
750798 // When more than one state update is enqueued, we have the same behavior
751799 const fifthState = new NotActuallyImmutable ( 'fifth' ) ;
752- ReactDOM . unstable_batchedUpdates ( function ( ) {
800+ await act ( ( ) => {
753801 moo . setState ( { str : 'fourth' } ) ;
754802 moo . _replaceState ( fifthState ) ;
755803 } ) ;
756804 expect ( moo . state ) . toBe ( fifthState ) ;
757805
758806 // When more than one state update is enqueued, we have the same behavior
759807 const sixthState = new NotActuallyImmutable ( 'sixth' ) ;
760- ReactDOM . unstable_batchedUpdates ( function ( ) {
808+ await act ( ( ) => {
761809 moo . _replaceState ( sixthState ) ;
762810 moo . setState ( { str : 'seventh' } ) ;
763811 } ) ;
0 commit comments