@@ -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