1414
1515let PropTypes ;
1616let React ;
17- let ReactDOM ;
18- let ReactTestUtils ;
17+ let ReactDOMClient ;
18+ let act ;
1919
2020let ReactFeatureFlags = require ( 'shared/ReactFeatureFlags' ) ;
2121
@@ -29,8 +29,8 @@ describe('ReactElementValidator', () => {
2929 ReactFeatureFlags = require ( 'shared/ReactFeatureFlags' ) ;
3030 ReactFeatureFlags . replayFailedUnitOfWorkWithInvokeGuardedCallback = false ;
3131 React = require ( 'react' ) ;
32- ReactDOM = require ( 'react-dom' ) ;
33- ReactTestUtils = require ( 'react-dom/ test-utils' ) ;
32+ ReactDOMClient = require ( 'react-dom/client ' ) ;
33+ act = require ( 'internal- test-utils' ) . act ;
3434 ComponentClass = class extends React . Component {
3535 render ( ) {
3636 return React . createElement ( 'div' ) ;
@@ -47,7 +47,7 @@ describe('ReactElementValidator', () => {
4747 } ) . toErrorDev ( 'Each child in a list should have a unique "key" prop.' ) ;
4848 } ) ;
4949
50- it ( 'warns for keys for arrays of elements with owner info' , ( ) => {
50+ it ( 'warns for keys for arrays of elements with owner info' , async ( ) => {
5151 class InnerClass extends React . Component {
5252 render ( ) {
5353 return React . createElement ( ComponentClass , null , this . props . childSet ) ;
@@ -65,37 +65,41 @@ describe('ReactElementValidator', () => {
6565 }
6666 }
6767
68- expect ( ( ) => {
69- ReactTestUtils . renderIntoDocument ( React . createElement ( ComponentWrapper ) ) ;
68+ await expect ( async ( ) => {
69+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
70+ await act ( ( ) => root . render ( React . createElement ( ComponentWrapper ) ) ) ;
7071 } ) . toErrorDev (
7172 'Each child in a list should have a unique "key" prop.' +
7273 '\n\nCheck the render method of `InnerClass`. ' +
7374 'It was passed a child from ComponentWrapper. ' ,
7475 ) ;
7576 } ) ;
7677
77- it ( 'warns for keys for arrays with no owner or parent info' , ( ) => {
78+ it ( 'warns for keys for arrays with no owner or parent info' , async ( ) => {
7879 function Anonymous ( ) {
7980 return < div /> ;
8081 }
8182 Object . defineProperty ( Anonymous , 'name' , { value : undefined } ) ;
8283
8384 const divs = [ < div /> , < div /> ] ;
8485
85- expect ( ( ) => {
86- ReactTestUtils . renderIntoDocument ( < Anonymous > { divs } </ Anonymous > ) ;
86+ await expect ( async ( ) => {
87+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
88+ await act ( ( ) => root . render ( < Anonymous > { divs } </ Anonymous > ) ) ;
8789 } ) . toErrorDev (
8890 'Warning: Each child in a list should have a unique ' +
8991 '"key" prop. See https://reactjs.org/link/warning-keys for more information.\n' +
9092 ' in div (at **)' ,
9193 ) ;
9294 } ) ;
9395
94- it ( 'warns for keys for arrays of elements with no owner info' , ( ) => {
96+ it ( 'warns for keys for arrays of elements with no owner info' , async ( ) => {
9597 const divs = [ < div /> , < div /> ] ;
9698
97- expect ( ( ) => {
98- ReactTestUtils . renderIntoDocument ( < div > { divs } </ div > ) ;
99+ await expect ( async ( ) => {
100+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
101+
102+ await act ( ( ) => root . render ( < div > { divs } </ div > ) ) ;
99103 } ) . toErrorDev (
100104 'Warning: Each child in a list should have a unique ' +
101105 '"key" prop.\n\nCheck the top-level render call using <div>. See ' +
@@ -104,7 +108,7 @@ describe('ReactElementValidator', () => {
104108 ) ;
105109 } ) ;
106110
107- it ( 'warns for keys with component stack info' , ( ) => {
111+ it ( 'warns for keys with component stack info' , async ( ) => {
108112 function Component ( ) {
109113 return < div > { [ < div /> , < div /> ] } </ div > ;
110114 }
@@ -117,7 +121,10 @@ describe('ReactElementValidator', () => {
117121 return < Parent child = { < Component /> } /> ;
118122 }
119123
120- expect ( ( ) => ReactTestUtils . renderIntoDocument ( < GrandParent /> ) ) . toErrorDev (
124+ await expect ( async ( ) => {
125+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
126+ await act ( ( ) => root . render ( < GrandParent /> ) ) ;
127+ } ) . toErrorDev (
121128 'Warning: Each child in a list should have a unique ' +
122129 '"key" prop.\n\nCheck the render method of `Component`. See ' +
123130 'https://reactjs.org/link/warning-keys for more information.\n' +
@@ -128,7 +135,7 @@ describe('ReactElementValidator', () => {
128135 ) ;
129136 } ) ;
130137
131- it ( 'does not warn for keys when passing children down' , ( ) => {
138+ it ( 'does not warn for keys when passing children down' , async ( ) => {
132139 function Wrapper ( props ) {
133140 return (
134141 < div >
@@ -138,11 +145,14 @@ describe('ReactElementValidator', () => {
138145 ) ;
139146 }
140147
141- ReactTestUtils . renderIntoDocument (
142- < Wrapper >
143- < span />
144- < span />
145- </ Wrapper > ,
148+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
149+ await act ( ( ) =>
150+ root . render (
151+ < Wrapper >
152+ < span />
153+ < span />
154+ </ Wrapper > ,
155+ ) ,
146156 ) ;
147157 } ) ;
148158
@@ -208,7 +218,7 @@ describe('ReactElementValidator', () => {
208218 React . createElement ( ComponentClass , null , [ { } , { } ] ) ;
209219 } ) ;
210220
211- it ( 'should give context for PropType errors in nested components.' , ( ) => {
221+ it ( 'should give context for PropType errors in nested components.' , async ( ) => {
212222 // In this test, we're making sure that if a proptype error is found in a
213223 // component, we give a small hint as to which parent instantiated that
214224 // component as per warnings about key usage in ReactElementValidator.
@@ -221,8 +231,9 @@ describe('ReactElementValidator', () => {
221231 function ParentComp ( ) {
222232 return React . createElement ( MyComp , { color : 123 } ) ;
223233 }
224- expect ( ( ) => {
225- ReactTestUtils . renderIntoDocument ( React . createElement ( ParentComp ) ) ;
234+ await expect ( async ( ) => {
235+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
236+ await act ( ( ) => root . render ( React . createElement ( ParentComp ) ) ) ;
226237 } ) . toErrorDev (
227238 'Warning: Failed prop type: ' +
228239 'Invalid prop `color` of type `number` supplied to `MyComp`, ' +
@@ -288,28 +299,33 @@ describe('ReactElementValidator', () => {
288299 React . createElement ( 'div' ) ;
289300 } ) ;
290301
291- it ( 'includes the owner name when passing null, undefined, boolean, or number' , ( ) => {
302+ it ( 'includes the owner name when passing null, undefined, boolean, or number' , async ( ) => {
292303 function ParentComp ( ) {
293304 return React . createElement ( null ) ;
294305 }
295306
296- expect ( ( ) => {
297- expect ( ( ) => {
298- ReactTestUtils . renderIntoDocument ( React . createElement ( ParentComp ) ) ;
299- } ) . toThrowError (
307+ await expect ( async ( ) => {
308+ await expect ( async ( ) => {
309+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
310+ await act ( ( ) => root . render ( React . createElement ( ParentComp ) ) ) ;
311+ } ) . rejects . toThrowError (
300312 'Element type is invalid: expected a string (for built-in components) ' +
301313 'or a class/function (for composite components) but got: null.' +
302314 ( __DEV__ ? '\n\nCheck the render method of `ParentComp`.' : '' ) ,
303315 ) ;
304- } ) . toErrorDev (
316+ } ) . toErrorDev ( [
305317 'Warning: React.createElement: type is invalid -- expected a string ' +
306318 '(for built-in components) or a class/function (for composite ' +
307319 'components) but got: null.' +
308320 '\n\nCheck the render method of `ParentComp`.\n in ParentComp' ,
309- ) ;
321+ 'Warning: React.createElement: type is invalid -- expected a string ' +
322+ '(for built-in components) or a class/function (for composite ' +
323+ 'components) but got: null.' +
324+ '\n\nCheck the render method of `ParentComp`.\n in ParentComp' ,
325+ ] ) ;
310326 } ) ;
311327
312- it ( 'should check default prop values' , ( ) => {
328+ it ( 'should check default prop values' , async ( ) => {
313329 class Component extends React . Component {
314330 static propTypes = { prop : PropTypes . string . isRequired } ;
315331 static defaultProps = { prop : null } ;
@@ -318,16 +334,17 @@ describe('ReactElementValidator', () => {
318334 }
319335 }
320336
321- expect ( ( ) =>
322- ReactTestUtils . renderIntoDocument ( React . createElement ( Component ) ) ,
323- ) . toErrorDev (
337+ await expect ( async ( ) => {
338+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
339+ await act ( ( ) => root . render ( React . createElement ( Component ) ) ) ;
340+ } ) . toErrorDev (
324341 'Warning: Failed prop type: The prop `prop` is marked as required in ' +
325342 '`Component`, but its value is `null`.\n' +
326343 ' in Component' ,
327344 ) ;
328345 } ) ;
329346
330- it ( 'should not check the default for explicit null' , ( ) => {
347+ it ( 'should not check the default for explicit null' , async ( ) => {
331348 class Component extends React . Component {
332349 static propTypes = { prop : PropTypes . string . isRequired } ;
333350 static defaultProps = { prop : 'text' } ;
@@ -336,9 +353,10 @@ describe('ReactElementValidator', () => {
336353 }
337354 }
338355
339- expect ( ( ) => {
340- ReactTestUtils . renderIntoDocument (
341- React . createElement ( Component , { prop : null } ) ,
356+ await expect ( async ( ) => {
357+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
358+ await act ( ( ) =>
359+ root . render ( React . createElement ( Component , { prop : null } ) ) ,
342360 ) ;
343361 } ) . toErrorDev (
344362 'Warning: Failed prop type: The prop `prop` is marked as required in ' +
@@ -347,7 +365,7 @@ describe('ReactElementValidator', () => {
347365 ) ;
348366 } ) ;
349367
350- it ( 'should check declared prop types' , ( ) => {
368+ it ( 'should check declared prop types' , async ( ) => {
351369 class Component extends React . Component {
352370 static propTypes = {
353371 prop : PropTypes . string . isRequired ,
@@ -357,11 +375,10 @@ describe('ReactElementValidator', () => {
357375 }
358376 }
359377
360- expect ( ( ) => {
361- ReactTestUtils . renderIntoDocument ( React . createElement ( Component ) ) ;
362- ReactTestUtils . renderIntoDocument (
363- React . createElement ( Component , { prop : 42 } ) ,
364- ) ;
378+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
379+ await expect ( async ( ) => {
380+ await act ( ( ) => root . render ( React . createElement ( Component ) ) ) ;
381+ await act ( ( ) => root . render ( React . createElement ( Component , { prop : 42 } ) ) ) ;
365382 } ) . toErrorDev ( [
366383 'Warning: Failed prop type: ' +
367384 'The prop `prop` is marked as required in `Component`, but its value ' +
@@ -374,12 +391,12 @@ describe('ReactElementValidator', () => {
374391 ] ) ;
375392
376393 // Should not error for strings
377- ReactTestUtils . renderIntoDocument (
378- React . createElement ( Component , { prop : 'string' } ) ,
394+ await act ( ( ) =>
395+ root . render ( React . createElement ( Component , { prop : 'string' } ) ) ,
379396 ) ;
380397 } ) ;
381398
382- it ( 'should warn if a PropType creator is used as a PropType' , ( ) => {
399+ it ( 'should warn if a PropType creator is used as a PropType' , async ( ) => {
383400 class Component extends React . Component {
384401 static propTypes = {
385402 myProp : PropTypes . shape ,
@@ -389,9 +406,10 @@ describe('ReactElementValidator', () => {
389406 }
390407 }
391408
392- expect ( ( ) => {
393- ReactTestUtils . renderIntoDocument (
394- React . createElement ( Component , { myProp : { value : 'hi' } } ) ,
409+ await expect ( async ( ) => {
410+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
411+ await act ( ( ) =>
412+ root . render ( React . createElement ( Component , { myProp : { value : 'hi' } } ) ) ,
395413 ) ;
396414 } ) . toErrorDev (
397415 'Warning: Component: type specification of prop `myProp` is invalid; ' +
@@ -402,7 +420,7 @@ describe('ReactElementValidator', () => {
402420 ) ;
403421 } ) ;
404422
405- it ( 'should warn if component declares PropTypes instead of propTypes' , ( ) => {
423+ it ( 'should warn if component declares PropTypes instead of propTypes' , async ( ) => {
406424 class MisspelledPropTypesComponent extends React . Component {
407425 static PropTypes = {
408426 prop : PropTypes . string ,
@@ -412,9 +430,12 @@ describe('ReactElementValidator', () => {
412430 }
413431 }
414432
415- expect ( ( ) => {
416- ReactTestUtils . renderIntoDocument (
417- React . createElement ( MisspelledPropTypesComponent , { prop : 'Hi' } ) ,
433+ await expect ( async ( ) => {
434+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
435+ await act ( ( ) =>
436+ root . render (
437+ React . createElement ( MisspelledPropTypesComponent , { prop : 'Hi' } ) ,
438+ ) ,
418439 ) ;
419440 } ) . toErrorDev (
420441 'Warning: Component MisspelledPropTypesComponent declared `PropTypes` ' +
@@ -423,15 +444,16 @@ describe('ReactElementValidator', () => {
423444 ) ;
424445 } ) ;
425446
426- it ( 'warns for fragments with illegal attributes' , ( ) => {
447+ it ( 'warns for fragments with illegal attributes' , async ( ) => {
427448 class Foo extends React . Component {
428449 render ( ) {
429450 return React . createElement ( React . Fragment , { a : 1 } , '123' ) ;
430451 }
431452 }
432453
433- expect ( ( ) => {
434- ReactTestUtils . renderIntoDocument ( React . createElement ( Foo ) ) ;
454+ await expect ( async ( ) => {
455+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
456+ await act ( ( ) => root . render ( React . createElement ( Foo ) ) ) ;
435457 } ) . toErrorDev (
436458 'Invalid prop `a` supplied to `React.Fragment`. React.Fragment ' +
437459 'can only have `key` and `children` props.' ,
@@ -466,19 +488,23 @@ describe('ReactElementValidator', () => {
466488 } ) ;
467489 }
468490
469- it ( 'does not warn when using DOM node as children' , ( ) => {
491+ it ( 'does not warn when using DOM node as children' , async ( ) => {
470492 class DOMContainer extends React . Component {
493+ ref ;
471494 render ( ) {
472- return < div /> ;
495+ return < div ref = { n => ( this . ref = n ) } /> ;
473496 }
474497 componentDidMount ( ) {
475- ReactDOM . findDOMNode ( this ) . appendChild ( this . props . children ) ;
498+ this . ref . appendChild ( this . props . children ) ;
476499 }
477500 }
478501
479502 const node = document . createElement ( 'div' ) ;
480- // This shouldn't cause a stack overflow or any other problems (#3883)
481- ReactTestUtils . renderIntoDocument ( < DOMContainer > { node } </ DOMContainer > ) ;
503+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
504+ await act ( ( ) => {
505+ // This shouldn't cause a stack overflow or any other problems (#3883)
506+ root . render ( < DOMContainer > { node } </ DOMContainer > ) ;
507+ } ) ;
482508 } ) ;
483509
484510 it ( 'should not enumerate enumerable numbers (#4776)' , ( ) => {
0 commit comments