@@ -36,13 +36,9 @@ describe('ReactIncrementalUpdates', () => {
36
36
assertLog = InternalTestUtils . assertLog ;
37
37
} ) ;
38
38
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 ;
46
42
}
47
43
48
44
it ( 'applies updates in order of priority' , async ( ) => {
@@ -528,35 +524,38 @@ describe('ReactIncrementalUpdates', () => {
528
524
setCount = _setCount ;
529
525
Scheduler . log ( 'Render: ' + count ) ;
530
526
useLayoutEffect ( ( ) => {
531
- setCount ( prevCount => prevCount + 1 ) ;
527
+ setCount ( 1 ) ;
532
528
Scheduler . log ( 'Commit: ' + count ) ;
533
529
} , [ ] ) ;
534
- return null ;
530
+ return < Text text = "Child" /> ;
535
531
}
536
532
537
533
await act ( async ( ) => {
538
534
React . startTransition ( ( ) => {
539
535
ReactNoop . render ( < App /> ) ;
540
536
} ) ;
541
- flushNextRenderIfExpired ( ) ;
542
537
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
+ ] ) ;
544
545
545
546
Scheduler . unstable_advanceTime ( 10000 ) ;
546
547
React . startTransition ( ( ) => {
547
548
setCount ( 2 ) ;
548
549
} ) ;
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' ] ) ;
551
555
} ) ;
552
556
} ) ;
553
557
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 ( ) => {
560
559
ReactNoop . flushSync ( ( ) => {
561
560
ReactNoop . render ( < Text text = "A" /> ) ;
562
561
} ) ;
@@ -565,32 +564,70 @@ describe('ReactIncrementalUpdates', () => {
565
564
Scheduler . unstable_advanceTime ( 10000 ) ;
566
565
567
566
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' ] ,
569
591
} ) ;
570
- flushNextRenderIfExpired ( ) ;
571
- assertLog ( [ ] ) ;
572
592
} ) ;
573
593
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 ( ) => {
580
595
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
+ ) ;
582
604
} ) ;
605
+ await waitFor ( [ 'A' ] ) ;
606
+
607
+ // This will expire the rest of the update
583
608
Scheduler . unstable_advanceTime ( 10000 ) ;
584
- flushNextRenderIfExpired ( ) ;
585
- assertLog ( [ 'A' ] ) ;
609
+ await waitFor ( [ 'B' ] , {
610
+ additionalLogsAfterAttemptingToYield : [ 'C' , 'D' ] ,
611
+ } ) ;
586
612
587
613
Scheduler . unstable_advanceTime ( 10000 ) ;
588
614
615
+ // Now do another transition. This one should not expire.
589
616
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
+ ) ;
591
625
} ) ;
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' ] ) ;
594
631
} ) ;
595
632
596
633
it ( 'when rebasing, does not exclude updates that were already committed, regardless of priority' , async ( ) => {
0 commit comments