14
14
15
15
let PropTypes ;
16
16
let React ;
17
- let ReactDOM ;
18
- let ReactTestUtils ;
17
+ let ReactDOMClient ;
18
+ let act ;
19
19
20
20
let ReactFeatureFlags = require ( 'shared/ReactFeatureFlags' ) ;
21
21
@@ -29,8 +29,8 @@ describe('ReactElementValidator', () => {
29
29
ReactFeatureFlags = require ( 'shared/ReactFeatureFlags' ) ;
30
30
ReactFeatureFlags . replayFailedUnitOfWorkWithInvokeGuardedCallback = false ;
31
31
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 ;
34
34
ComponentClass = class extends React . Component {
35
35
render ( ) {
36
36
return React . createElement ( 'div' ) ;
@@ -47,7 +47,7 @@ describe('ReactElementValidator', () => {
47
47
} ) . toErrorDev ( 'Each child in a list should have a unique "key" prop.' ) ;
48
48
} ) ;
49
49
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 ( ) => {
51
51
class InnerClass extends React . Component {
52
52
render ( ) {
53
53
return React . createElement ( ComponentClass , null , this . props . childSet ) ;
@@ -65,37 +65,41 @@ describe('ReactElementValidator', () => {
65
65
}
66
66
}
67
67
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 ) ) ) ;
70
71
} ) . toErrorDev (
71
72
'Each child in a list should have a unique "key" prop.' +
72
73
'\n\nCheck the render method of `InnerClass`. ' +
73
74
'It was passed a child from ComponentWrapper. ' ,
74
75
) ;
75
76
} ) ;
76
77
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 ( ) => {
78
79
function Anonymous ( ) {
79
80
return < div /> ;
80
81
}
81
82
Object . defineProperty ( Anonymous , 'name' , { value : undefined } ) ;
82
83
83
84
const divs = [ < div /> , < div /> ] ;
84
85
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 > ) ) ;
87
89
} ) . toErrorDev (
88
90
'Warning: Each child in a list should have a unique ' +
89
91
'"key" prop. See https://reactjs.org/link/warning-keys for more information.\n' +
90
92
' in div (at **)' ,
91
93
) ;
92
94
} ) ;
93
95
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 ( ) => {
95
97
const divs = [ < div /> , < div /> ] ;
96
98
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 > ) ) ;
99
103
} ) . toErrorDev (
100
104
'Warning: Each child in a list should have a unique ' +
101
105
'"key" prop.\n\nCheck the top-level render call using <div>. See ' +
@@ -104,7 +108,7 @@ describe('ReactElementValidator', () => {
104
108
) ;
105
109
} ) ;
106
110
107
- it ( 'warns for keys with component stack info' , ( ) => {
111
+ it ( 'warns for keys with component stack info' , async ( ) => {
108
112
function Component ( ) {
109
113
return < div > { [ < div /> , < div /> ] } </ div > ;
110
114
}
@@ -117,7 +121,10 @@ describe('ReactElementValidator', () => {
117
121
return < Parent child = { < Component /> } /> ;
118
122
}
119
123
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 (
121
128
'Warning: Each child in a list should have a unique ' +
122
129
'"key" prop.\n\nCheck the render method of `Component`. See ' +
123
130
'https://reactjs.org/link/warning-keys for more information.\n' +
@@ -128,7 +135,7 @@ describe('ReactElementValidator', () => {
128
135
) ;
129
136
} ) ;
130
137
131
- it ( 'does not warn for keys when passing children down' , ( ) => {
138
+ it ( 'does not warn for keys when passing children down' , async ( ) => {
132
139
function Wrapper ( props ) {
133
140
return (
134
141
< div >
@@ -138,11 +145,14 @@ describe('ReactElementValidator', () => {
138
145
) ;
139
146
}
140
147
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
+ ) ,
146
156
) ;
147
157
} ) ;
148
158
@@ -208,7 +218,7 @@ describe('ReactElementValidator', () => {
208
218
React . createElement ( ComponentClass , null , [ { } , { } ] ) ;
209
219
} ) ;
210
220
211
- it ( 'should give context for PropType errors in nested components.' , ( ) => {
221
+ it ( 'should give context for PropType errors in nested components.' , async ( ) => {
212
222
// In this test, we're making sure that if a proptype error is found in a
213
223
// component, we give a small hint as to which parent instantiated that
214
224
// component as per warnings about key usage in ReactElementValidator.
@@ -221,8 +231,9 @@ describe('ReactElementValidator', () => {
221
231
function ParentComp ( ) {
222
232
return React . createElement ( MyComp , { color : 123 } ) ;
223
233
}
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 ) ) ) ;
226
237
} ) . toErrorDev (
227
238
'Warning: Failed prop type: ' +
228
239
'Invalid prop `color` of type `number` supplied to `MyComp`, ' +
@@ -288,28 +299,33 @@ describe('ReactElementValidator', () => {
288
299
React . createElement ( 'div' ) ;
289
300
} ) ;
290
301
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 ( ) => {
292
303
function ParentComp ( ) {
293
304
return React . createElement ( null ) ;
294
305
}
295
306
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 (
300
312
'Element type is invalid: expected a string (for built-in components) ' +
301
313
'or a class/function (for composite components) but got: null.' +
302
314
( __DEV__ ? '\n\nCheck the render method of `ParentComp`.' : '' ) ,
303
315
) ;
304
- } ) . toErrorDev (
316
+ } ) . toErrorDev ( [
305
317
'Warning: React.createElement: type is invalid -- expected a string ' +
306
318
'(for built-in components) or a class/function (for composite ' +
307
319
'components) but got: null.' +
308
320
'\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
+ ] ) ;
310
326
} ) ;
311
327
312
- it ( 'should check default prop values' , ( ) => {
328
+ it ( 'should check default prop values' , async ( ) => {
313
329
class Component extends React . Component {
314
330
static propTypes = { prop : PropTypes . string . isRequired } ;
315
331
static defaultProps = { prop : null } ;
@@ -318,16 +334,17 @@ describe('ReactElementValidator', () => {
318
334
}
319
335
}
320
336
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 (
324
341
'Warning: Failed prop type: The prop `prop` is marked as required in ' +
325
342
'`Component`, but its value is `null`.\n' +
326
343
' in Component' ,
327
344
) ;
328
345
} ) ;
329
346
330
- it ( 'should not check the default for explicit null' , ( ) => {
347
+ it ( 'should not check the default for explicit null' , async ( ) => {
331
348
class Component extends React . Component {
332
349
static propTypes = { prop : PropTypes . string . isRequired } ;
333
350
static defaultProps = { prop : 'text' } ;
@@ -336,9 +353,10 @@ describe('ReactElementValidator', () => {
336
353
}
337
354
}
338
355
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 } ) ) ,
342
360
) ;
343
361
} ) . toErrorDev (
344
362
'Warning: Failed prop type: The prop `prop` is marked as required in ' +
@@ -347,7 +365,7 @@ describe('ReactElementValidator', () => {
347
365
) ;
348
366
} ) ;
349
367
350
- it ( 'should check declared prop types' , ( ) => {
368
+ it ( 'should check declared prop types' , async ( ) => {
351
369
class Component extends React . Component {
352
370
static propTypes = {
353
371
prop : PropTypes . string . isRequired ,
@@ -357,11 +375,10 @@ describe('ReactElementValidator', () => {
357
375
}
358
376
}
359
377
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 } ) ) ) ;
365
382
} ) . toErrorDev ( [
366
383
'Warning: Failed prop type: ' +
367
384
'The prop `prop` is marked as required in `Component`, but its value ' +
@@ -374,12 +391,12 @@ describe('ReactElementValidator', () => {
374
391
] ) ;
375
392
376
393
// 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' } ) ) ,
379
396
) ;
380
397
} ) ;
381
398
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 ( ) => {
383
400
class Component extends React . Component {
384
401
static propTypes = {
385
402
myProp : PropTypes . shape ,
@@ -389,9 +406,10 @@ describe('ReactElementValidator', () => {
389
406
}
390
407
}
391
408
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' } } ) ) ,
395
413
) ;
396
414
} ) . toErrorDev (
397
415
'Warning: Component: type specification of prop `myProp` is invalid; ' +
@@ -402,7 +420,7 @@ describe('ReactElementValidator', () => {
402
420
) ;
403
421
} ) ;
404
422
405
- it ( 'should warn if component declares PropTypes instead of propTypes' , ( ) => {
423
+ it ( 'should warn if component declares PropTypes instead of propTypes' , async ( ) => {
406
424
class MisspelledPropTypesComponent extends React . Component {
407
425
static PropTypes = {
408
426
prop : PropTypes . string ,
@@ -412,9 +430,12 @@ describe('ReactElementValidator', () => {
412
430
}
413
431
}
414
432
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
+ ) ,
418
439
) ;
419
440
} ) . toErrorDev (
420
441
'Warning: Component MisspelledPropTypesComponent declared `PropTypes` ' +
@@ -423,15 +444,16 @@ describe('ReactElementValidator', () => {
423
444
) ;
424
445
} ) ;
425
446
426
- it ( 'warns for fragments with illegal attributes' , ( ) => {
447
+ it ( 'warns for fragments with illegal attributes' , async ( ) => {
427
448
class Foo extends React . Component {
428
449
render ( ) {
429
450
return React . createElement ( React . Fragment , { a : 1 } , '123' ) ;
430
451
}
431
452
}
432
453
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 ) ) ) ;
435
457
} ) . toErrorDev (
436
458
'Invalid prop `a` supplied to `React.Fragment`. React.Fragment ' +
437
459
'can only have `key` and `children` props.' ,
@@ -466,19 +488,23 @@ describe('ReactElementValidator', () => {
466
488
} ) ;
467
489
}
468
490
469
- it ( 'does not warn when using DOM node as children' , ( ) => {
491
+ it ( 'does not warn when using DOM node as children' , async ( ) => {
470
492
class DOMContainer extends React . Component {
493
+ ref ;
471
494
render ( ) {
472
- return < div /> ;
495
+ return < div ref = { n => ( this . ref = n ) } /> ;
473
496
}
474
497
componentDidMount ( ) {
475
- ReactDOM . findDOMNode ( this ) . appendChild ( this . props . children ) ;
498
+ this . ref . appendChild ( this . props . children ) ;
476
499
}
477
500
}
478
501
479
502
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
+ } ) ;
482
508
} ) ;
483
509
484
510
it ( 'should not enumerate enumerable numbers (#4776)' , ( ) => {
0 commit comments