diff --git a/packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js b/packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js index 8a020b4e73c8..7adc0345729f 100644 --- a/packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js @@ -298,8 +298,8 @@ describe('ReactSuspense', () => { ); } - // throttling works on fallback committing - // here advance some time to skip the first threshold + // Committing fallbacks should be throttled. + // First, advance some time to skip the first threshold. jest.advanceTimersByTime(600); Scheduler.unstable_advanceTime(600); @@ -316,23 +316,83 @@ describe('ReactSuspense', () => { ]); expect(root).toMatchRenderedOutput('Loading...'); - // resolve A + // Resolve A. jest.advanceTimersByTime(200); Scheduler.unstable_advanceTime(200); expect(Scheduler).toHaveYielded(['Promise resolved [A]']); expect(Scheduler).toFlushAndYield(['A', 'Suspend! [B]', 'Loading more...']); - // should still renders previous fallback + // By this point, we have enough info to show "A" and "Loading more..." + // However, we've just shown the outer fallback. So we'll delay + // showing the inner fallback hoping that B will resolve soon enough. expect(root).toMatchRenderedOutput('Loading...'); - // resolve B + // Resolve B. jest.advanceTimersByTime(100); Scheduler.unstable_advanceTime(100); expect(Scheduler).toHaveYielded(['Promise resolved [B]']); - // before commiting we still shows previous fallback + // By this point, B has resolved. + // We're still showing the outer fallback. expect(root).toMatchRenderedOutput('Loading...'); expect(Scheduler).toFlushAndYield(['A', 'B']); + // Then contents of both should pop in together. + expect(root).toMatchRenderedOutput('AB'); + }); + + it('does not throttle fallback committing for too long', () => { + function Foo() { + Scheduler.unstable_yieldValue('Foo'); + return ( + }> + + }> + + + + ); + } + + // Committing fallbacks should be throttled. + // First, advance some time to skip the first threshold. + jest.advanceTimersByTime(600); + Scheduler.unstable_advanceTime(600); + + const root = ReactTestRenderer.create(, { + unstable_isConcurrent: true, + }); + + expect(Scheduler).toFlushAndYield([ + 'Foo', + 'Suspend! [A]', + 'Suspend! [B]', + 'Loading more...', + 'Loading...', + ]); + expect(root).toMatchRenderedOutput('Loading...'); + + // Resolve A. + jest.advanceTimersByTime(200); + Scheduler.unstable_advanceTime(200); + expect(Scheduler).toHaveYielded(['Promise resolved [A]']); + expect(Scheduler).toFlushAndYield(['A', 'Suspend! [B]', 'Loading more...']); + + // By this point, we have enough info to show "A" and "Loading more..." + // However, we've just shown the outer fallback. So we'll delay + // showing the inner fallback hoping that B will resolve soon enough. + expect(root).toMatchRenderedOutput('Loading...'); + + // Wait some more. B is still not resolving. + jest.advanceTimersByTime(500); + Scheduler.unstable_advanceTime(500); + // Give up and render A with a spinner for B. + expect(root).toMatchRenderedOutput('ALoading more...'); + + // Resolve B. + jest.advanceTimersByTime(500); + Scheduler.unstable_advanceTime(500); + expect(Scheduler).toHaveYielded(['Promise resolved [B]']); + expect(Scheduler).toFlushAndYield(['B']); expect(root).toMatchRenderedOutput('AB'); });