@@ -748,6 +748,52 @@ describe('Profiler', () => {
748748 expect ( onRender . mock . calls [ 2 ] [ 1 ] ) . toBe ( 'update' ) ;
749749 } ) ;
750750
751+ it ( 'is properly distinguish updates and nested-updates when there is more than sync remaining work' , ( ) => {
752+ loadModules ( {
753+ enableSchedulerTracing,
754+ useNoopRenderer : true ,
755+ } ) ;
756+
757+ function Component ( ) {
758+ const [ didMount , setDidMount ] = React . useState ( false ) ;
759+
760+ React . useLayoutEffect ( ( ) => {
761+ setDidMount ( true ) ;
762+ } , [ ] ) ;
763+ Scheduler . unstable_yieldValue ( didMount ) ;
764+ return didMount ;
765+ }
766+
767+ const onRender = jest . fn ( ) ;
768+
769+ // Schedule low-priority work.
770+ Scheduler . unstable_runWithPriority (
771+ Scheduler . unstable_LowPriority ,
772+ ( ) => {
773+ ReactNoop . render (
774+ < React . Profiler id = "root" onRender = { onRender } >
775+ < Component />
776+ </ React . Profiler > ,
777+ ) ;
778+ } ,
779+ ) ;
780+
781+ // Flush sync work with a nested upate
782+ ReactNoop . flushSync ( ( ) => {
783+ ReactNoop . render (
784+ < React . Profiler id = "root" onRender = { onRender } >
785+ < Component />
786+ </ React . Profiler > ,
787+ ) ;
788+ } ) ;
789+ expect ( Scheduler ) . toHaveYielded ( [ false , true ] ) ;
790+
791+ // Verify that the nested update inside of the sync work is appropriately tagged.
792+ expect ( onRender ) . toHaveBeenCalledTimes ( 2 ) ;
793+ expect ( onRender . mock . calls [ 0 ] [ 1 ] ) . toBe ( 'mount' ) ;
794+ expect ( onRender . mock . calls [ 1 ] [ 1 ] ) . toBe ( 'nested-update' ) ;
795+ } ) ;
796+
751797 describe ( 'with regard to interruptions' , ( ) => {
752798 it ( 'should accumulate actual time after a scheduling interruptions' , ( ) => {
753799 const callback = jest . fn ( ) ;
@@ -2582,14 +2628,50 @@ describe('Profiler', () => {
25822628
25832629 expect ( Scheduler ) . toHaveYielded ( [ 'Component:false' , 'Component:true' ] ) ;
25842630 expect ( onNestedUpdateScheduled ) . toHaveBeenCalledTimes ( 1 ) ;
2631+ expect ( onNestedUpdateScheduled . mock . calls [ 0 ] [ 0 ] ) . toBe ( 'test' ) ;
25852632 if ( ReactFeatureFlags . enableSchedulerTracing ) {
2586- expect ( onNestedUpdateScheduled . mock . calls [ 0 ] [ 0 ] ) . toBe ( 'test' ) ;
25872633 expect ( onNestedUpdateScheduled . mock . calls [ 0 ] [ 1 ] ) . toMatchInteractions ( [
25882634 interactionCreation ,
25892635 ] ) ;
25902636 }
25912637 } ) ;
25922638
2639+ it ( 'is called when a function component schedules a batched update during a layout effect' , ( ) => {
2640+ function Component ( ) {
2641+ const [ didMount , setDidMount ] = React . useState ( false ) ;
2642+ React . useLayoutEffect ( ( ) => {
2643+ ReactNoop . batchedUpdates ( ( ) => {
2644+ setDidMount ( true ) ;
2645+ } ) ;
2646+ } , [ ] ) ;
2647+ Scheduler . unstable_yieldValue ( `Component:${ didMount } ` ) ;
2648+ return didMount ;
2649+ }
2650+
2651+ const onNestedUpdateScheduled = jest . fn ( ) ;
2652+ const onRender = jest . fn ( ) ;
2653+
2654+ ReactNoop . render (
2655+ < React . Profiler
2656+ id = "root"
2657+ onNestedUpdateScheduled = { onNestedUpdateScheduled }
2658+ onRender = { onRender } >
2659+ < Component />
2660+ </ React . Profiler > ,
2661+ ) ;
2662+ expect ( Scheduler ) . toFlushAndYield ( [
2663+ 'Component:false' ,
2664+ 'Component:true' ,
2665+ ] ) ;
2666+
2667+ expect ( onRender ) . toHaveBeenCalledTimes ( 2 ) ;
2668+ expect ( onRender . mock . calls [ 0 ] [ 1 ] ) . toBe ( 'mount' ) ;
2669+ expect ( onRender . mock . calls [ 1 ] [ 1 ] ) . toBe ( 'nested-update' ) ;
2670+
2671+ expect ( onNestedUpdateScheduled ) . toHaveBeenCalledTimes ( 1 ) ;
2672+ expect ( onNestedUpdateScheduled . mock . calls [ 0 ] [ 0 ] ) . toBe ( 'root' ) ;
2673+ } ) ;
2674+
25932675 it ( 'bubbles up and calls all ancestor Profilers' , ( ) => {
25942676 function Component ( ) {
25952677 const [ didMount , setDidMount ] = React . useState ( false ) ;
@@ -2819,8 +2901,8 @@ describe('Profiler', () => {
28192901 'Component:true:false' ,
28202902 ] ) ;
28212903 expect ( onNestedUpdateScheduled ) . toHaveBeenCalledTimes ( 1 ) ;
2904+ expect ( onNestedUpdateScheduled . mock . calls [ 0 ] [ 0 ] ) . toBe ( 'test' ) ;
28222905 if ( ReactFeatureFlags . enableSchedulerTracing ) {
2823- expect ( onNestedUpdateScheduled . mock . calls [ 0 ] [ 0 ] ) . toBe ( 'test' ) ;
28242906 expect ( onNestedUpdateScheduled . mock . calls [ 0 ] [ 1 ] ) . toMatchInteractions ( [
28252907 interactionCreation ,
28262908 ] ) ;
@@ -2853,8 +2935,8 @@ describe('Profiler', () => {
28532935 'Component:true:true' ,
28542936 ] ) ;
28552937 expect ( onNestedUpdateScheduled ) . toHaveBeenCalledTimes ( 2 ) ;
2938+ expect ( onNestedUpdateScheduled . mock . calls [ 1 ] [ 0 ] ) . toBe ( 'test' ) ;
28562939 if ( ReactFeatureFlags . enableSchedulerTracing ) {
2857- expect ( onNestedUpdateScheduled . mock . calls [ 1 ] [ 0 ] ) . toBe ( 'test' ) ;
28582940 expect ( onNestedUpdateScheduled . mock . calls [ 1 ] [ 1 ] ) . toMatchInteractions ( [
28592941 interactionUpdate ,
28602942 ] ) ;
@@ -2902,8 +2984,8 @@ describe('Profiler', () => {
29022984
29032985 expect ( Scheduler ) . toHaveYielded ( [ 'Component:false' , 'Component:true' ] ) ;
29042986 expect ( onNestedUpdateScheduled ) . toHaveBeenCalledTimes ( 1 ) ;
2987+ expect ( onNestedUpdateScheduled . mock . calls [ 0 ] [ 0 ] ) . toBe ( 'test' ) ;
29052988 if ( ReactFeatureFlags . enableSchedulerTracing ) {
2906- expect ( onNestedUpdateScheduled . mock . calls [ 0 ] [ 0 ] ) . toBe ( 'test' ) ;
29072989 expect ( onNestedUpdateScheduled . mock . calls [ 0 ] [ 1 ] ) . toMatchInteractions ( [
29082990 interactionCreation ,
29092991 ] ) ;
@@ -2974,8 +3056,8 @@ describe('Profiler', () => {
29743056 'Component:true:true' ,
29753057 ] ) ;
29763058 expect ( onNestedUpdateScheduled ) . toHaveBeenCalledTimes ( 1 ) ;
3059+ expect ( onNestedUpdateScheduled . mock . calls [ 0 ] [ 0 ] ) . toBe ( 'test' ) ;
29773060 if ( ReactFeatureFlags . enableSchedulerTracing ) {
2978- expect ( onNestedUpdateScheduled . mock . calls [ 0 ] [ 0 ] ) . toBe ( 'test' ) ;
29793061 expect ( onNestedUpdateScheduled . mock . calls [ 0 ] [ 1 ] ) . toMatchInteractions ( [
29803062 interactionCreation ,
29813063 ] ) ;
@@ -3016,6 +3098,8 @@ describe('Profiler', () => {
30163098 expect ( Scheduler ) . toHaveYielded ( [ 'Component:true' ] ) ;
30173099 expect ( onNestedUpdateScheduled ) . not . toHaveBeenCalled ( ) ;
30183100 } ) ;
3101+
3102+ // TODO Add hydration tests to ensure we don't have false positives called.
30193103 } ) ;
30203104 } ) ;
30213105
0 commit comments