@@ -36,13 +36,9 @@ describe('ReactIncrementalUpdates', () => {
3636    assertLog  =  InternalTestUtils . assertLog ; 
3737  } ) ; 
3838
39-   function  flushNextRenderIfExpired ( )  { 
40-     // This will start rendering the next level of work. If the work hasn't 
41-     // expired yet, React will exit without doing anything. If it has expired, 
42-     // it will schedule a sync task. 
43-     Scheduler . unstable_flushExpired ( ) ; 
44-     // Flush the sync task. 
45-     ReactNoop . flushSync ( ) ; 
39+   function  Text ( { text} )  { 
40+     Scheduler . log ( text ) ; 
41+     return  text ; 
4642  } 
4743
4844  it ( 'applies updates in order of priority' ,  async  ( )  =>  { 
@@ -528,35 +524,38 @@ describe('ReactIncrementalUpdates', () => {
528524      setCount  =  _setCount ; 
529525      Scheduler . log ( 'Render: '  +  count ) ; 
530526      useLayoutEffect ( ( )  =>  { 
531-         setCount ( prevCount   =>   prevCount   +   1 ) ; 
527+         setCount ( 1 ) ; 
532528        Scheduler . log ( 'Commit: '  +  count ) ; 
533529      } ,  [ ] ) ; 
534-       return  null ; 
530+       return  < Text   text = "Child"   /> ; 
535531    } 
536532
537533    await  act ( async  ( )  =>  { 
538534      React . startTransition ( ( )  =>  { 
539535        ReactNoop . render ( < App  /> ) ; 
540536      } ) ; 
541-       flushNextRenderIfExpired ( ) ; 
542537      assertLog ( [ ] ) ; 
543-       await  waitForAll ( [ 'Render: 0' ,  'Commit: 0' ,  'Render: 1' ] ) ; 
538+       await  waitForAll ( [ 
539+         'Render: 0' , 
540+         'Child' , 
541+         'Commit: 0' , 
542+         'Render: 1' , 
543+         'Child' , 
544+       ] ) ; 
544545
545546      Scheduler . unstable_advanceTime ( 10000 ) ; 
546547      React . startTransition ( ( )  =>  { 
547548        setCount ( 2 ) ; 
548549      } ) ; 
549-       flushNextRenderIfExpired ( ) ; 
550-       assertLog ( [ ] ) ; 
550+       // The transition should not have expired, so we should be able to 
551+       // partially render it. 
552+       await  waitFor ( [ 'Render: 2' ] ) ; 
553+       // Now do the rest 
554+       await  waitForAll ( [ 'Child' ] ) ; 
551555    } ) ; 
552556  } ) ; 
553557
554-   it ( 'regression: does not expire soon due to previous flushSync' ,  ( )  =>  { 
555-     function  Text ( { text} )  { 
556-       Scheduler . log ( text ) ; 
557-       return  text ; 
558-     } 
559- 
558+   it ( 'regression: does not expire soon due to previous flushSync' ,  async  ( )  =>  { 
560559    ReactNoop . flushSync ( ( )  =>  { 
561560      ReactNoop . render ( < Text  text = "A"  /> ) ; 
562561    } ) ; 
@@ -565,32 +564,70 @@ describe('ReactIncrementalUpdates', () => {
565564    Scheduler . unstable_advanceTime ( 10000 ) ; 
566565
567566    React . startTransition ( ( )  =>  { 
568-       ReactNoop . render ( < Text  text = "B"  /> ) ; 
567+       ReactNoop . render ( 
568+         < > 
569+           < Text  text = "A"  /> 
570+           < Text  text = "B"  /> 
571+           < Text  text = "C"  /> 
572+           < Text  text = "D"  /> 
573+         </ > , 
574+       ) ; 
575+     } ) ; 
576+     // The transition should not have expired, so we should be able to 
577+     // partially render it. 
578+     await  waitFor ( [ 'A' ] ) ; 
579+ 
580+     // FIXME:  We should be able to partially render B, too, but currently it 
581+     // expires. This is an existing bug that I discovered, which will be fixed 
582+     // in a PR that I'm currently working on. 
583+     // 
584+     // Correct behavior: 
585+     //   await waitFor(['B']); 
586+     //   await waitForAll(['C', 'D']); 
587+     // 
588+     // Current behavior: 
589+     await  waitFor ( [ 'B' ] ,  { 
590+       additionalLogsAfterAttemptingToYield : [ 'C' ,  'D' ] , 
569591    } ) ; 
570-     flushNextRenderIfExpired ( ) ; 
571-     assertLog ( [ ] ) ; 
572592  } ) ; 
573593
574-   it ( 'regression: does not expire soon due to previous expired work' ,  ( )  =>  { 
575-     function  Text ( { text} )  { 
576-       Scheduler . log ( text ) ; 
577-       return  text ; 
578-     } 
579- 
594+   it ( 'regression: does not expire soon due to previous expired work' ,  async  ( )  =>  { 
580595    React . startTransition ( ( )  =>  { 
581-       ReactNoop . render ( < Text  text = "A"  /> ) ; 
596+       ReactNoop . render ( 
597+         < > 
598+           < Text  text = "A"  /> 
599+           < Text  text = "B"  /> 
600+           < Text  text = "C"  /> 
601+           < Text  text = "D"  /> 
602+         </ > , 
603+       ) ; 
582604    } ) ; 
605+     await  waitFor ( [ 'A' ] ) ; 
606+ 
607+     // This will expire the rest of the update 
583608    Scheduler . unstable_advanceTime ( 10000 ) ; 
584-     flushNextRenderIfExpired ( ) ; 
585-     assertLog ( [ 'A' ] ) ; 
609+     await  waitFor ( [ 'B' ] ,  { 
610+       additionalLogsAfterAttemptingToYield : [ 'C' ,  'D' ] , 
611+     } ) ; 
586612
587613    Scheduler . unstable_advanceTime ( 10000 ) ; 
588614
615+     // Now do another transition. This one should not expire. 
589616    React . startTransition ( ( )  =>  { 
590-       ReactNoop . render ( < Text  text = "B"  /> ) ; 
617+       ReactNoop . render ( 
618+         < > 
619+           < Text  text = "A"  /> 
620+           < Text  text = "B"  /> 
621+           < Text  text = "C"  /> 
622+           < Text  text = "D"  /> 
623+         </ > , 
624+       ) ; 
591625    } ) ; 
592-     flushNextRenderIfExpired ( ) ; 
593-     assertLog ( [ ] ) ; 
626+     // The transition should not have expired, so we should be able to 
627+     // partially render it. 
628+     await  waitFor ( [ 'A' ] ) ; 
629+     await  waitFor ( [ 'B' ] ) ; 
630+     await  waitForAll ( [ 'C' ,  'D' ] ) ; 
594631  } ) ; 
595632
596633  it ( 'when rebasing, does not exclude updates that were already committed, regardless of priority' ,  async  ( )  =>  { 
0 commit comments