From 64dde70827117fbe15df2a05c618d01d81fcbbf6 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Sat, 4 Mar 2023 18:04:43 -0500 Subject: [PATCH] Codemod tests to waitFor pattern (8/?) (#26308) This converts some of our test suite to use the `waitFor` test pattern, instead of the `expect(Scheduler).toFlushAndYield` pattern. Most of these changes are automated with jscodeshift, with some slight manual cleanup in certain cases. See #26285 for full context. --- .../src/__tests__/preprocessData-test.js | 65 ++--- .../ReactDOMFizzShellHydration-test.js | 24 +- .../ReactSuspenseEffectsSemantics-test.js | 239 ++++++++-------- .../useMutableSource-test.internal.js | 267 +++++++++--------- .../useMutableSourceHydration-test.js | 38 +-- .../src/__tests__/useRef-test.internal.js | 22 +- .../__tests__/useSyncExternalStore-test.js | 22 +- .../src/__tests__/ReactFresh-test.js | 15 +- .../ReactTestRenderer-test.internal.js | 8 +- .../__tests__/ReactTestRendererAct-test.js | 6 +- .../__tests__/ReactTestRendererAsync-test.js | 34 ++- .../src/__tests__/SchedulerMock-test.js | 160 +++++------ .../src/__tests__/SchedulerProfiling-test.js | 50 ++-- .../src/__tests__/useSubscription-test.js | 96 ++++--- .../useSyncExternalStoreNative-test.js | 12 +- .../useSyncExternalStoreShared-test.js | 84 +++--- .../useSyncExternalStoreShimServer-test.js | 6 +- 17 files changed, 591 insertions(+), 557 deletions(-) diff --git a/packages/react-devtools-shared/src/__tests__/preprocessData-test.js b/packages/react-devtools-shared/src/__tests__/preprocessData-test.js index 1464912034efa..1f713b51e08b3 100644 --- a/packages/react-devtools-shared/src/__tests__/preprocessData-test.js +++ b/packages/react-devtools-shared/src/__tests__/preprocessData-test.js @@ -17,6 +17,8 @@ describe('Timeline profiler', () => { let ReactDOMClient; let Scheduler; let utils; + let assertLog; + let waitFor; describe('User Timing API', () => { let clearedMarks; @@ -82,6 +84,10 @@ describe('Timeline profiler', () => { ReactDOMClient = require('react-dom/client'); Scheduler = require('scheduler'); + const InternalTestUtils = require('internal-test-utils'); + assertLog = InternalTestUtils.assertLog; + waitFor = InternalTestUtils.waitFor; + setPerformanceMock = require('react-devtools-shared/src/backend/profilingHooks').setPerformanceMock_ONLY_FOR_TESTING; setPerformanceMock(createUserTimingPolyfill()); @@ -1372,28 +1378,29 @@ describe('Timeline profiler', () => { , ); - expect(Scheduler).toFlushAndYieldThrough(['A:1']); + }); - testMarks.push(...createUserTimingData(clearedMarks)); - clearPendingMarks(); + await waitFor(['A:1']); - // Advance the clock some more to make the pending React update seem long. - startTime += 20000; + testMarks.push(...createUserTimingData(clearedMarks)); + clearPendingMarks(); - // Fake a long "click" event in the middle - // and schedule a sync update that will also flush the previous work. - testMarks.push(createNativeEventEntry('click', 25000)); - ReactDOM.flushSync(() => { - root.render( - <> - - - , - ); - }); + // Advance the clock some more to make the pending React update seem long. + startTime += 20000; + + // Fake a long "click" event in the middle + // and schedule a sync update that will also flush the previous work. + testMarks.push(createNativeEventEntry('click', 25000)); + ReactDOM.flushSync(() => { + root.render( + <> + + + , + ); }); - expect(Scheduler).toHaveYielded(['A:2', 'B:2']); + assertLog(['A:2', 'B:2']); testMarks.push(...createUserTimingData(clearedMarks)); @@ -1424,10 +1431,7 @@ describe('Timeline profiler', () => { root.render(); }); - expect(Scheduler).toHaveYielded([ - 'Component mount', - 'Component update', - ]); + assertLog(['Component mount', 'Component update']); const data = await preprocessData([ ...createBoilerplateEntries(), @@ -1463,10 +1467,7 @@ describe('Timeline profiler', () => { root.render(); }); - expect(Scheduler).toHaveYielded([ - 'Component mount', - 'Component update', - ]); + assertLog(['Component mount', 'Component update']); const data = await preprocessData([ ...createBoilerplateEntries(), @@ -1504,10 +1505,7 @@ describe('Timeline profiler', () => { root.render(); }); - expect(Scheduler).toHaveYielded([ - 'Component mount', - 'Component update', - ]); + assertLog(['Component mount', 'Component update']); const testMarks = []; clearedMarks.forEach(markName => { @@ -1567,10 +1565,7 @@ describe('Timeline profiler', () => { root.render(); }); - expect(Scheduler).toHaveYielded([ - 'Component mount', - 'Component update', - ]); + assertLog(['Component mount', 'Component update']); const testMarks = []; clearedMarks.forEach(markName => { @@ -1639,7 +1634,7 @@ describe('Timeline profiler', () => { root.render(); }); - expect(Scheduler).toHaveYielded([ + assertLog([ 'Component rendered with value 0', 'Component rendered with value 0', 'Component rendered with value 1', @@ -1708,7 +1703,7 @@ describe('Timeline profiler', () => { root.render(); }); - expect(Scheduler).toHaveYielded([ + assertLog([ 'Component rendered with value 0 and deferredValue 0', 'Component rendered with value 1 and deferredValue 0', 'Component rendered with value 1 and deferredValue 1', diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzShellHydration-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzShellHydration-test.js index a6580d58d9ebd..812946c6e4b03 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzShellHydration-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzShellHydration-test.js @@ -23,6 +23,7 @@ let buffer = ''; let hasErrored = false; let fatalError = undefined; let textCache; +let assertLog; describe('ReactDOMFizzShellHydration', () => { beforeEach(() => { @@ -35,6 +36,9 @@ describe('ReactDOMFizzShellHydration', () => { ReactDOMFizzServer = require('react-dom/server'); Stream = require('stream'); + const InternalTestUtils = require('internal-test-utils'); + assertLog = InternalTestUtils.assertLog; + startTransition = React.startTransition; textCache = new Map(); @@ -180,7 +184,7 @@ describe('ReactDOMFizzShellHydration', () => { const {pipe} = ReactDOMFizzServer.renderToPipeableStream(); pipe(writable); }); - expect(Scheduler).toHaveYielded(['Shell']); + assertLog(['Shell']); const dehydratedDiv = container.getElementsByTagName('div')[0]; // Clear the cache and start rendering on the client @@ -190,7 +194,7 @@ describe('ReactDOMFizzShellHydration', () => { await clientAct(async () => { ReactDOMClient.hydrateRoot(container, ); }); - expect(Scheduler).toHaveYielded(['Suspend! [Shell]']); + assertLog(['Suspend! [Shell]']); expect(div.current).toBe(null); expect(container.textContent).toBe('Shell'); @@ -198,7 +202,7 @@ describe('ReactDOMFizzShellHydration', () => { await clientAct(async () => { await resolveText('Shell'); }); - expect(Scheduler).toHaveYielded(['Shell']); + assertLog(['Shell']); expect(div.current).toBe(dehydratedDiv); expect(container.textContent).toBe('Shell'); }); @@ -213,12 +217,12 @@ describe('ReactDOMFizzShellHydration', () => { await clientAct(async () => { root.render(); }); - expect(Scheduler).toHaveYielded(['Suspend! [Shell]']); + assertLog(['Suspend! [Shell]']); await clientAct(async () => { await resolveText('Shell'); }); - expect(Scheduler).toHaveYielded(['Shell']); + assertLog(['Shell']); expect(container.textContent).toBe('Shell'); }); @@ -236,7 +240,7 @@ describe('ReactDOMFizzShellHydration', () => { const {pipe} = ReactDOMFizzServer.renderToPipeableStream(); pipe(writable); }); - expect(Scheduler).toHaveYielded(['Initial']); + assertLog(['Initial']); await clientAct(async () => { const root = ReactDOMClient.hydrateRoot(container, ); @@ -246,7 +250,7 @@ describe('ReactDOMFizzShellHydration', () => { root.render(); }); }); - expect(Scheduler).toHaveYielded(['Initial', 'Updated']); + assertLog(['Initial', 'Updated']); expect(container.textContent).toBe('Updated'); }, ); @@ -262,7 +266,7 @@ describe('ReactDOMFizzShellHydration', () => { const {pipe} = ReactDOMFizzServer.renderToPipeableStream(); pipe(writable); }); - expect(Scheduler).toHaveYielded(['Shell']); + assertLog(['Shell']); // Clear the cache and start rendering on the client resetTextCache(); @@ -275,13 +279,13 @@ describe('ReactDOMFizzShellHydration', () => { }, }); }); - expect(Scheduler).toHaveYielded(['Suspend! [Shell]']); + assertLog(['Suspend! [Shell]']); expect(container.textContent).toBe('Shell'); await clientAct(async () => { root.render(); }); - expect(Scheduler).toHaveYielded([ + assertLog([ 'New screen', 'This root received an early update, before anything was able ' + 'hydrate. Switched the entire root to client rendering.', diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseEffectsSemantics-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseEffectsSemantics-test.js index 76a6b7794be61..2193275bd687b 100644 --- a/packages/react-reconciler/src/__tests__/ReactSuspenseEffectsSemantics-test.js +++ b/packages/react-reconciler/src/__tests__/ReactSuspenseEffectsSemantics-test.js @@ -16,6 +16,8 @@ let getCacheForType; let caches; let seededCache; let ErrorBoundary; +let waitForAll; +let assertLog; // TODO: These tests don't pass in persistent mode yet. Need to implement. @@ -31,6 +33,10 @@ describe('ReactSuspenseEffectsSemantics', () => { getCacheForType = React.unstable_getCacheForType; + const InternalTestUtils = require('internal-test-utils'); + waitForAll = InternalTestUtils.waitForAll; + assertLog = InternalTestUtils.assertLog; + caches = []; seededCache = null; @@ -256,7 +262,7 @@ describe('ReactSuspenseEffectsSemantics', () => { , ); }); - expect(Scheduler).toHaveYielded([ + assertLog([ 'App render', 'Text:Inside:Before render', 'Suspend:Async', @@ -281,7 +287,7 @@ describe('ReactSuspenseEffectsSemantics', () => { await act(async () => { await resolveText('Async'); }); - expect(Scheduler).toHaveYielded([ + assertLog([ 'Text:Inside:Before render', 'AsyncText:Async render', 'ClassText:Inside:After render', @@ -305,7 +311,7 @@ describe('ReactSuspenseEffectsSemantics', () => { await act(async () => { ReactNoop.render(null); }); - expect(Scheduler).toHaveYielded([ + assertLog([ 'App destroy layout', 'Text:Inside:Before destroy layout', 'AsyncText:Async destroy layout', @@ -377,7 +383,7 @@ describe('ReactSuspenseEffectsSemantics', () => { , ); }); - expect(Scheduler).toHaveYielded([ + assertLog([ 'App render', 'Text:Inside:Before render', 'Suspend:Async', @@ -407,7 +413,7 @@ describe('ReactSuspenseEffectsSemantics', () => { await act(async () => { await resolveText('Async'); }); - expect(Scheduler).toHaveYielded([ + assertLog([ 'AsyncText:Async render', 'Text:Fallback destroy layout', 'AsyncText:Async create layout', @@ -426,7 +432,7 @@ describe('ReactSuspenseEffectsSemantics', () => { await act(async () => { ReactNoop.renderLegacySyncRoot(null); }); - expect(Scheduler).toHaveYielded([ + assertLog([ 'App destroy layout', 'Text:Inside:Before destroy layout', 'AsyncText:Async destroy layout', @@ -474,7 +480,7 @@ describe('ReactSuspenseEffectsSemantics', () => { act(() => { ReactNoop.renderLegacySyncRoot(); }); - expect(Scheduler).toHaveYielded([ + assertLog([ 'App render', 'Text:Inside:Before render', 'Text:Inside:After render', @@ -504,7 +510,7 @@ describe('ReactSuspenseEffectsSemantics', () => { , ); }); - expect(Scheduler).toHaveYielded([ + assertLog([ 'App render', 'Text:Inside:Before render', 'Suspend:Async', @@ -526,7 +532,7 @@ describe('ReactSuspenseEffectsSemantics', () => { await advanceTimers(1000); // Noop since sync root has already committed - expect(Scheduler).toHaveYielded([]); + assertLog([]); expect(ReactNoop).toMatchRenderedOutput( <>