99
1010'use strict' ;
1111
12+ let act ;
13+
1214let PropTypes ;
1315let React ;
14- let ReactDOM ;
16+ let ReactDOMClient ;
1517let ReactTestUtils ;
1618let createReactClass ;
1719
1820describe ( 'create-react-class-integration' , ( ) => {
1921 beforeEach ( ( ) => {
2022 jest . resetModules ( ) ;
23+ ( { act} = require ( 'internal-test-utils' ) ) ;
2124 PropTypes = require ( 'prop-types' ) ;
2225 React = require ( 'react' ) ;
23- ReactDOM = require ( 'react-dom' ) ;
26+ ReactDOMClient = require ( 'react-dom/client ' ) ;
2427 ReactTestUtils = require ( 'react-dom/test-utils' ) ;
2528 createReactClass = require ( 'create-react-class/factory' ) (
2629 React . Component ,
@@ -292,7 +295,7 @@ describe('create-react-class-integration', () => {
292295 } ) ;
293296
294297 // @gate !disableLegacyContext
295- it ( 'renders based on context getInitialState' , ( ) => {
298+ it ( 'renders based on context getInitialState' , async ( ) => {
296299 const Foo = createReactClass ( {
297300 contextTypes : {
298301 className : PropTypes . string ,
@@ -318,7 +321,10 @@ describe('create-react-class-integration', () => {
318321 } ) ;
319322
320323 const container = document . createElement ( 'div' ) ;
321- ReactDOM . render ( < Outer /> , container ) ;
324+ const root = ReactDOMClient . createRoot ( container ) ;
325+ await act ( ( ) => {
326+ root . render ( < Outer /> ) ;
327+ } ) ;
322328 expect ( container . firstChild . className ) . toBe ( 'foo' ) ;
323329 } ) ;
324330
@@ -388,7 +394,7 @@ describe('create-react-class-integration', () => {
388394 expect ( ops ) . toEqual ( [ 'Render: 0' , 'Render: 1' , 'Callback: 1' ] ) ;
389395 } ) ;
390396
391- it ( 'getDerivedStateFromProps updates state when props change' , ( ) => {
397+ it ( 'getDerivedStateFromProps updates state when props change' , async ( ) => {
392398 const Component = createReactClass ( {
393399 getInitialState ( ) {
394400 return {
@@ -404,23 +410,26 @@ describe('create-react-class-integration', () => {
404410 } ) ;
405411
406412 const container = document . createElement ( 'div' ) ;
407- const instance = ReactDOM . render (
408- < div >
409- < Component incrementBy = { 0 } />
410- </ div > ,
411- container ,
412- ) ;
413- expect ( instance . textContent ) . toEqual ( 'count:1' ) ;
414- ReactDOM . render (
415- < div >
416- < Component incrementBy = { 2 } />
417- </ div > ,
418- container ,
419- ) ;
420- expect ( instance . textContent ) . toEqual ( 'count:3' ) ;
413+ const root = ReactDOMClient . createRoot ( container ) ;
414+ await act ( ( ) => {
415+ root . render (
416+ < div >
417+ < Component incrementBy = { 0 } />
418+ </ div > ,
419+ ) ;
420+ } ) ;
421+ expect ( container . firstChild . textContent ) . toEqual ( 'count:1' ) ;
422+ await act ( ( ) => {
423+ root . render (
424+ < div >
425+ < Component incrementBy = { 2 } />
426+ </ div > ,
427+ ) ;
428+ } ) ;
429+ expect ( container . firstChild . textContent ) . toEqual ( 'count:3' ) ;
421430 } ) ;
422431
423- it ( 'should support the new static getDerivedStateFromProps method' , ( ) => {
432+ it ( 'should support the new static getDerivedStateFromProps method' , async ( ) => {
424433 let instance ;
425434 const Component = createReactClass ( {
426435 statics : {
@@ -438,11 +447,14 @@ describe('create-react-class-integration', () => {
438447 return null ;
439448 } ,
440449 } ) ;
441- ReactDOM . render ( < Component /> , document . createElement ( 'div' ) ) ;
450+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
451+ await act ( ( ) => {
452+ root . render ( < Component /> ) ;
453+ } ) ;
442454 expect ( instance . state . foo ) . toBe ( 'bar' ) ;
443455 } ) ;
444456
445- it ( 'warns if getDerivedStateFromProps is not static' , ( ) => {
457+ it ( 'warns if getDerivedStateFromProps is not static' , async ( ) => {
446458 const Foo = createReactClass ( {
447459 displayName : 'Foo' ,
448460 getDerivedStateFromProps ( ) {
@@ -452,15 +464,18 @@ describe('create-react-class-integration', () => {
452464 return < div /> ;
453465 } ,
454466 } ) ;
455- expect ( ( ) =>
456- ReactDOM . render ( < Foo foo = "foo" /> , document . createElement ( 'div' ) ) ,
457- ) . toErrorDev (
467+ await expect ( async ( ) => {
468+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
469+ await act ( ( ) => {
470+ root . render ( < Foo foo = "foo" /> ) ;
471+ } ) ;
472+ } ) . toErrorDev (
458473 'Foo: getDerivedStateFromProps() is defined as an instance method ' +
459474 'and will be ignored. Instead, declare it as a static method.' ,
460475 ) ;
461476 } ) ;
462477
463- it ( 'warns if getDerivedStateFromError is not static' , ( ) => {
478+ it ( 'warns if getDerivedStateFromError is not static' , async ( ) => {
464479 const Foo = createReactClass ( {
465480 displayName : 'Foo' ,
466481 getDerivedStateFromError ( ) {
@@ -470,15 +485,18 @@ describe('create-react-class-integration', () => {
470485 return < div /> ;
471486 } ,
472487 } ) ;
473- expect ( ( ) =>
474- ReactDOM . render ( < Foo foo = "foo" /> , document . createElement ( 'div' ) ) ,
475- ) . toErrorDev (
488+ await expect ( async ( ) => {
489+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
490+ await act ( ( ) => {
491+ root . render ( < Foo foo = "foo" /> ) ;
492+ } ) ;
493+ } ) . toErrorDev (
476494 'Foo: getDerivedStateFromError() is defined as an instance method ' +
477495 'and will be ignored. Instead, declare it as a static method.' ,
478496 ) ;
479497 } ) ;
480498
481- it ( 'warns if getSnapshotBeforeUpdate is static' , ( ) => {
499+ it ( 'warns if getSnapshotBeforeUpdate is static' , async ( ) => {
482500 const Foo = createReactClass ( {
483501 displayName : 'Foo' ,
484502 statics : {
@@ -490,15 +508,18 @@ describe('create-react-class-integration', () => {
490508 return < div /> ;
491509 } ,
492510 } ) ;
493- expect ( ( ) =>
494- ReactDOM . render ( < Foo foo = "foo" /> , document . createElement ( 'div' ) ) ,
495- ) . toErrorDev (
511+ await expect ( async ( ) => {
512+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
513+ await act ( ( ) => {
514+ root . render ( < Foo foo = "foo" /> ) ;
515+ } ) ;
516+ } ) . toErrorDev (
496517 'Foo: getSnapshotBeforeUpdate() is defined as a static method ' +
497518 'and will be ignored. Instead, declare it as an instance method.' ,
498519 ) ;
499520 } ) ;
500521
501- it ( 'should warn if state is not properly initialized before getDerivedStateFromProps' , ( ) => {
522+ it ( 'should warn if state is not properly initialized before getDerivedStateFromProps' , async ( ) => {
502523 const Component = createReactClass ( {
503524 displayName : 'Component' ,
504525 statics : {
@@ -510,17 +531,20 @@ describe('create-react-class-integration', () => {
510531 return null ;
511532 } ,
512533 } ) ;
513- expect ( ( ) =>
514- ReactDOM . render ( < Component /> , document . createElement ( 'div' ) ) ,
515- ) . toErrorDev (
534+ await expect ( async ( ) => {
535+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
536+ await act ( ( ) => {
537+ root . render ( < Component /> ) ;
538+ } ) ;
539+ } ) . toErrorDev (
516540 '`Component` uses `getDerivedStateFromProps` but its initial state is ' +
517541 'null. This is not recommended. Instead, define the initial state by ' +
518542 'assigning an object to `this.state` in the constructor of `Component`. ' +
519543 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.' ,
520544 ) ;
521545 } ) ;
522546
523- it ( 'should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new static gDSFP is present' , ( ) => {
547+ it ( 'should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new static gDSFP is present' , async ( ) => {
524548 const Component = createReactClass ( {
525549 statics : {
526550 getDerivedStateFromProps : function ( ) {
@@ -544,9 +568,12 @@ describe('create-react-class-integration', () => {
544568 } ,
545569 } ) ;
546570
547- expect ( ( ) => {
548- expect ( ( ) => {
549- ReactDOM . render ( < Component /> , document . createElement ( 'div' ) ) ;
571+ await expect ( async ( ) => {
572+ await expect ( async ( ) => {
573+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
574+ await act ( ( ) => {
575+ root . render ( < Component /> ) ;
576+ } ) ;
550577 } ) . toErrorDev (
551578 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
552579 'Component uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
@@ -564,10 +591,13 @@ describe('create-react-class-integration', () => {
564591 ] ,
565592 { withoutStack : true } ,
566593 ) ;
567- ReactDOM . render ( < Component foo = { 1 } /> , document . createElement ( 'div' ) ) ;
594+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
595+ await act ( ( ) => {
596+ root . render ( < Component foo = { 1 } /> ) ;
597+ } ) ;
568598 } ) ;
569599
570- it ( 'should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new getSnapshotBeforeUpdate is present' , ( ) => {
600+ it ( 'should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new getSnapshotBeforeUpdate is present' , async ( ) => {
571601 const Component = createReactClass ( {
572602 getSnapshotBeforeUpdate : function ( ) {
573603 return null ;
@@ -587,9 +617,12 @@ describe('create-react-class-integration', () => {
587617 } ,
588618 } ) ;
589619
590- expect ( ( ) => {
591- expect ( ( ) => {
592- ReactDOM . render ( < Component /> , document . createElement ( 'div' ) ) ;
620+ await expect ( async ( ) => {
621+ await expect ( async ( ) => {
622+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
623+ await act ( ( ) => {
624+ root . render ( < Component /> ) ;
625+ } ) ;
593626 } ) . toErrorDev (
594627 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
595628 'Component uses getSnapshotBeforeUpdate() but also contains the following legacy lifecycles:\n' +
@@ -607,10 +640,13 @@ describe('create-react-class-integration', () => {
607640 ] ,
608641 { withoutStack : true } ,
609642 ) ;
610- ReactDOM . render ( < Component foo = { 1 } /> , document . createElement ( 'div' ) ) ;
643+ await act ( ( ) => {
644+ const root2 = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
645+ root2 . render ( < Component foo = { 1 } /> ) ;
646+ } ) ;
611647 } ) ;
612648
613- it ( 'should invoke both deprecated and new lifecycles if both are present' , ( ) => {
649+ it ( 'should invoke both deprecated and new lifecycles if both are present' , async ( ) => {
614650 const log = [ ] ;
615651
616652 const Component = createReactClass ( {
@@ -641,8 +677,13 @@ describe('create-react-class-integration', () => {
641677 } ,
642678 } ) ;
643679
644- const div = document . createElement ( 'div' ) ;
645- expect ( ( ) => ReactDOM . render ( < Component foo = "bar" /> , div ) ) . toWarnDev (
680+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
681+
682+ await expect ( async ( ) => {
683+ await act ( ( ) => {
684+ root . render ( < Component foo = "bar" /> ) ;
685+ } ) ;
686+ } ) . toWarnDev (
646687 [
647688 'componentWillMount has been renamed' ,
648689 'componentWillReceiveProps has been renamed' ,
@@ -654,7 +695,9 @@ describe('create-react-class-integration', () => {
654695
655696 log . length = 0 ;
656697
657- ReactDOM . render ( < Component foo = "baz" /> , div ) ;
698+ await act ( ( ) => {
699+ root . render ( < Component foo = "baz" /> ) ;
700+ } ) ;
658701 expect ( log ) . toEqual ( [
659702 'componentWillReceiveProps' ,
660703 'UNSAFE_componentWillReceiveProps' ,
@@ -663,7 +706,7 @@ describe('create-react-class-integration', () => {
663706 ] ) ;
664707 } ) ;
665708
666- it ( 'isMounted works' , ( ) => {
709+ it ( 'isMounted works' , async ( ) => {
667710 const ops = [ ] ;
668711 let instance ;
669712 const Component = createReactClass ( {
@@ -716,19 +759,28 @@ describe('create-react-class-integration', () => {
716759 } ,
717760 } ) ;
718761
719- const container = document . createElement ( 'div' ) ;
762+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
720763
721- expect ( ( ) => ReactDOM . render ( < Component /> , container ) ) . toErrorDev (
764+ await expect ( async ( ) => {
765+ await act ( ( ) => {
766+ root . render ( < Component /> ) ;
767+ } ) ;
768+ } ) . toErrorDev (
722769 'Warning: MyComponent: isMounted is deprecated. Instead, make sure to ' +
723770 'clean up subscriptions and pending requests in componentWillUnmount ' +
724771 'to prevent memory leaks.' ,
725772 { withoutStack : true } ,
726773 ) ;
727774
728775 // Dedupe
729- ReactDOM . render ( < Component /> , container ) ;
730776
731- ReactDOM . unmountComponentAtNode ( container ) ;
777+ await act ( ( ) => {
778+ root . render ( < Component /> ) ;
779+ } ) ;
780+
781+ await act ( ( ) => {
782+ root . unmount ( ) ;
783+ } ) ;
732784 instance . log ( 'after unmount' ) ;
733785 expect ( ops ) . toEqual ( [
734786 'getInitialState: false' ,
0 commit comments