From bf8c304f293a2428954ed643ccfc14997066656d Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 20 Nov 2023 15:43:31 -0700 Subject: [PATCH 01/14] Use shorthand return in peekRender --- src/testing/internal/profile/profile.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/testing/internal/profile/profile.tsx b/src/testing/internal/profile/profile.tsx index f4abb64af0e..ebcd1b840b3 100644 --- a/src/testing/internal/profile/profile.tsx +++ b/src/testing/internal/profile/profile.tsx @@ -196,11 +196,10 @@ export function profile< } return render; } - const render = Profiled.waitForNextRender({ + return Profiled.waitForNextRender({ [_stackTrace]: captureStackTrace(Profiled.peekRender), ...options, }); - return render; }, async takeRender(options: NextRenderOptions = {}) { let error: unknown = undefined; From d1976a9cf06be9c38a048d8c5795aaddec7f2c97 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 20 Nov 2023 15:45:39 -0700 Subject: [PATCH 02/14] Use the iteratorPosition in getCurrentRender as the current render --- src/testing/internal/profile/profile.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/testing/internal/profile/profile.tsx b/src/testing/internal/profile/profile.tsx index ebcd1b840b3..cd911fe6b07 100644 --- a/src/testing/internal/profile/profile.tsx +++ b/src/testing/internal/profile/profile.tsx @@ -221,7 +221,12 @@ export function profile< if (!currentRender) { throw new Error("Has not been rendered yet!"); } - return currentRender; + + const render = Profiled.renders[iteratorPosition]; + if (render.phase === "snapshotError") { + throw render.error; + } + return render; }, async takeUntilRenderCount( count: number, From 53333ca16e37608aac14fd0ce11bdf9a860c0a47 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 20 Nov 2023 15:50:37 -0700 Subject: [PATCH 03/14] Rename currentRenderCount to totalRenderCount to clarify intent & update matchers --- src/testing/internal/profile/profile.tsx | 8 ++++---- src/testing/matchers/ProfiledComponent.ts | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/testing/internal/profile/profile.tsx b/src/testing/internal/profile/profile.tsx index cd911fe6b07..68a0c3b0cec 100644 --- a/src/testing/internal/profile/profile.tsx +++ b/src/testing/internal/profile/profile.tsx @@ -54,9 +54,9 @@ interface ProfiledComponentFields { */ takeRender(options?: NextRenderOptions): Promise>; /** - * Returns the current render count. + * Returns the total number of renders. */ - currentRenderCount(): number; + totalRenderCount(): number; /** * Returns the current render. * @throws {Error} if no render has happened yet @@ -185,7 +185,7 @@ export function profile< | Render | { phase: "snapshotError"; count: number; error: unknown } >(), - currentRenderCount() { + totalRenderCount() { return Profiled.renders.length; }, async peekRender(options: NextRenderOptions = {}) { @@ -326,7 +326,7 @@ export function profileHook( }, { renders: ProfiledComponent.renders, - currentSnapshotCount: ProfiledComponent.currentRenderCount, + totalSnapshotCount: ProfiledComponent.totalRenderCount, async peekSnapshot(options) { return (await ProfiledComponent.peekRender(options)).snapshot; }, diff --git a/src/testing/matchers/ProfiledComponent.ts b/src/testing/matchers/ProfiledComponent.ts index 469cfe00995..8a4e72025a9 100644 --- a/src/testing/matchers/ProfiledComponent.ts +++ b/src/testing/matchers/ProfiledComponent.ts @@ -52,11 +52,11 @@ export const toRenderExactlyTimes: MatcherFunction< const hint = this.utils.matcherHint("toRenderExactlyTimes"); let pass = true; try { - if (profiled.currentRenderCount() > times) { + if (profiled.totalRenderCount() > times) { throw failed; } try { - while (profiled.currentRenderCount() < times) { + while (profiled.totalRenderCount() < times) { await profiled.waitForNextRender(options); } } catch (e) { @@ -84,7 +84,7 @@ export const toRenderExactlyTimes: MatcherFunction< return ( hint + ` Expected component to${pass ? " not" : ""} render exactly ${times}.` + - ` It rendered ${profiled.currentRenderCount()} times.` + ` It rendered ${profiled.totalRenderCount()} times.` ); }, }; From 3a48eadc0cf12e219df4d9996679db0321f278a1 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 20 Nov 2023 15:59:11 -0700 Subject: [PATCH 04/14] Remove takeUntilRenderCount function for now --- src/testing/internal/profile/profile.tsx | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/testing/internal/profile/profile.tsx b/src/testing/internal/profile/profile.tsx index 68a0c3b0cec..cc6bc56bd03 100644 --- a/src/testing/internal/profile/profile.tsx +++ b/src/testing/internal/profile/profile.tsx @@ -62,13 +62,6 @@ interface ProfiledComponentFields { * @throws {Error} if no render has happened yet */ getCurrentRender(): Render; - /** - * Iterates the renders until the render count is reached. - */ - takeUntilRenderCount( - count: number, - optionsPerRender?: NextRenderOptions - ): Promise; /** * Waits for the next render to happen. * Does not advance the render iterator. @@ -228,14 +221,6 @@ export function profile< } return render; }, - async takeUntilRenderCount( - count: number, - optionsPerRender?: NextRenderOptions - ) { - while (Profiled.renders.length < count) { - await Profiled.takeRender(optionsPerRender); - } - }, waitForNextRender({ timeout = 1000, // capture the stack trace here so its stack trace is as close to the calling code as possible @@ -336,7 +321,6 @@ export function profileHook( getCurrentSnapshot() { return ProfiledComponent.getCurrentRender().snapshot; }, - takeUntilSnapshotCount: ProfiledComponent.takeUntilRenderCount, async waitForNextSnapshot(options) { return (await ProfiledComponent.waitForNextRender(options)).snapshot; }, From d0c4238dfdbb7acd971b04a89e4bc576bece2521 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 20 Nov 2023 16:10:21 -0700 Subject: [PATCH 05/14] Implement peekRender with this.getCurrentRender() --- src/testing/internal/profile/profile.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/testing/internal/profile/profile.tsx b/src/testing/internal/profile/profile.tsx index cc6bc56bd03..74eec613a88 100644 --- a/src/testing/internal/profile/profile.tsx +++ b/src/testing/internal/profile/profile.tsx @@ -183,11 +183,7 @@ export function profile< }, async peekRender(options: NextRenderOptions = {}) { if (iteratorPosition < Profiled.renders.length) { - const render = Profiled.renders[iteratorPosition]; - if (render.phase === "snapshotError") { - throw render.error; - } - return render; + return this.getCurrentRender(); } return Profiled.waitForNextRender({ [_stackTrace]: captureStackTrace(Profiled.peekRender), From 28d24c879565c4cb5fd07b4b5a8c1eeb0e120104 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 20 Nov 2023 16:15:44 -0700 Subject: [PATCH 06/14] Fix typo in type name --- src/testing/internal/profile/profile.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/testing/internal/profile/profile.tsx b/src/testing/internal/profile/profile.tsx index 74eec613a88..01b6d8ea2cf 100644 --- a/src/testing/internal/profile/profile.tsx +++ b/src/testing/internal/profile/profile.tsx @@ -23,14 +23,14 @@ export interface NextRenderOptions { export interface ProfiledComponent extends React.FC, ProfiledComponentFields, - ProfiledComponenOnlyFields {} + ProfiledComponentOnlyFields {} interface UpdateSnapshot { (newSnapshot: Snapshot): void; (updateSnapshot: (lastSnapshot: Readonly) => Snapshot): void; } -interface ProfiledComponenOnlyFields { +interface ProfiledComponentOnlyFields { updateSnapshot: UpdateSnapshot; } interface ProfiledComponentFields { @@ -172,7 +172,7 @@ export function profile< ), { updateSnapshot, - } satisfies ProfiledComponenOnlyFields, + } satisfies ProfiledComponentOnlyFields, { renders: new Array< | Render From d1ec7f94321c4f146c17958287236766f73e956c Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 20 Nov 2023 16:30:03 -0700 Subject: [PATCH 07/14] Add a setSnapshot function to set partial data on snapshot --- src/testing/internal/profile/profile.tsx | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/testing/internal/profile/profile.tsx b/src/testing/internal/profile/profile.tsx index 01b6d8ea2cf..068a464bd8f 100644 --- a/src/testing/internal/profile/profile.tsx +++ b/src/testing/internal/profile/profile.tsx @@ -30,7 +30,19 @@ interface UpdateSnapshot { (updateSnapshot: (lastSnapshot: Readonly) => Snapshot): void; } +interface SetSnapshot { + (partialSnapshot: Partial): void; + ( + updatePartialSnapshot: ( + lastSnapshot: Readonly + ) => Partial + ): void; +} + interface ProfiledComponentOnlyFields { + // Allows for partial updating of the snapshot by shallow merging the results + setSnapshot: SetSnapshot; + // Performs a full replacement of the snapshot updateSnapshot: UpdateSnapshot; } interface ProfiledComponentFields { @@ -111,6 +123,16 @@ export function profile< snapshotRef.current = snap; } }; + + const setSnapshot: SetSnapshot = (partialSnapshot) => { + updateSnapshot((snapshot) => ({ + ...snapshot, + ...(typeof partialSnapshot === "function" + ? partialSnapshot(snapshot) + : partialSnapshot), + })); + }; + const profilerOnRender: React.ProfilerOnRenderCallback = ( id, phase, @@ -172,6 +194,7 @@ export function profile< ), { updateSnapshot, + setSnapshot, } satisfies ProfiledComponentOnlyFields, { renders: new Array< From dbc20fd5f484557f341473dc3eb0601abbca22d0 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 20 Nov 2023 16:30:19 -0700 Subject: [PATCH 08/14] Update some uses of updateSnapshot with setSnapshot in useBackgroundQuery tests --- src/react/hooks/__tests__/useBackgroundQuery.test.tsx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/react/hooks/__tests__/useBackgroundQuery.test.tsx b/src/react/hooks/__tests__/useBackgroundQuery.test.tsx index 08121af7f27..695921deab3 100644 --- a/src/react/hooks/__tests__/useBackgroundQuery.test.tsx +++ b/src/react/hooks/__tests__/useBackgroundQuery.test.tsx @@ -434,8 +434,7 @@ function renderPaginatedIntegrationTest({ } function SuspenseFallback() { - ProfiledApp.updateSnapshot((snapshot) => ({ - ...snapshot, + ProfiledApp.setSnapshot((snapshot) => ({ suspenseCount: snapshot.suspenseCount + 1, })); return
loading
; @@ -450,8 +449,7 @@ function renderPaginatedIntegrationTest({ }) { const { data, error } = useReadQuery(queryRef); // count renders in the child component - ProfiledApp.updateSnapshot((snapshot) => ({ - ...snapshot, + ProfiledApp.setSnapshot((snapshot) => ({ count: snapshot.count + 1, })); return ( @@ -504,8 +502,7 @@ function renderPaginatedIntegrationTest({ Error} onError={(error) => { - ProfiledApp.updateSnapshot((snapshot) => ({ - ...snapshot, + ProfiledApp.setSnapshot((snapshot) => ({ errorCount: snapshot.errorCount + 1, errors: snapshot.errors.concat(error), })); From 737b5b234d7bb6bf8b95fdaa3344bab1e38a1385 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 20 Nov 2023 17:23:49 -0700 Subject: [PATCH 09/14] Destructure in setSnapshot --- .../hooks/__tests__/useBackgroundQuery.test.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/react/hooks/__tests__/useBackgroundQuery.test.tsx b/src/react/hooks/__tests__/useBackgroundQuery.test.tsx index 695921deab3..d2ee0109c86 100644 --- a/src/react/hooks/__tests__/useBackgroundQuery.test.tsx +++ b/src/react/hooks/__tests__/useBackgroundQuery.test.tsx @@ -434,8 +434,8 @@ function renderPaginatedIntegrationTest({ } function SuspenseFallback() { - ProfiledApp.setSnapshot((snapshot) => ({ - suspenseCount: snapshot.suspenseCount + 1, + ProfiledApp.setSnapshot(({ suspenseCount }) => ({ + suspenseCount: suspenseCount + 1, })); return
loading
; } @@ -449,8 +449,8 @@ function renderPaginatedIntegrationTest({ }) { const { data, error } = useReadQuery(queryRef); // count renders in the child component - ProfiledApp.setSnapshot((snapshot) => ({ - count: snapshot.count + 1, + ProfiledApp.setSnapshot(({ count }) => ({ + count: count + 1, })); return (
@@ -502,9 +502,9 @@ function renderPaginatedIntegrationTest({ Error
} onError={(error) => { - ProfiledApp.setSnapshot((snapshot) => ({ - errorCount: snapshot.errorCount + 1, - errors: snapshot.errors.concat(error), + ProfiledApp.setSnapshot(({ errorCount, errors }) => ({ + errorCount: errorCount + 1, + errors: errors.concat(error), })); }} > From 1f0d2bd1e86f85989383b79a37152ab405279fda Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 20 Nov 2023 17:47:38 -0700 Subject: [PATCH 10/14] Update getCurrentRender to use the previous iterator position. --- src/testing/internal/profile/profile.tsx | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/testing/internal/profile/profile.tsx b/src/testing/internal/profile/profile.tsx index 068a464bd8f..c75555519e5 100644 --- a/src/testing/internal/profile/profile.tsx +++ b/src/testing/internal/profile/profile.tsx @@ -206,7 +206,13 @@ export function profile< }, async peekRender(options: NextRenderOptions = {}) { if (iteratorPosition < Profiled.renders.length) { - return this.getCurrentRender(); + const render = Profiled.renders[iteratorPosition]; + + if (render.phase === "snapshotError") { + throw render.error; + } + + return render; } return Profiled.waitForNextRender({ [_stackTrace]: captureStackTrace(Profiled.peekRender), @@ -230,11 +236,21 @@ export function profile< } }, getCurrentRender() { - if (!currentRender) { - throw new Error("Has not been rendered yet!"); + // The "current" render should point at the same render that the most + // recent `takeRender` call returned, so we need to get the "previous" + // iterator position, otherwise `takeRender` advances the iterator + // to the next render. This means we need to call `takeRender` at least + // once before we can get a current render. + const currentPosition = iteratorPosition - 1; + + if (currentPosition < 0) { + throw new Error( + "No render has occurred yet. You may need to call `takeRender` before you can get the current render." + ); } - const render = Profiled.renders[iteratorPosition]; + const render = Profiled.renders[currentPosition]; + if (render.phase === "snapshotError") { throw render.error; } From 88e2e477b0f913afcfe8e7897ccc558e3cb225f1 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 20 Nov 2023 17:49:23 -0700 Subject: [PATCH 11/14] Update test to use peekRender to get execute function --- src/react/hooks/__tests__/useLazyQuery.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/react/hooks/__tests__/useLazyQuery.test.tsx b/src/react/hooks/__tests__/useLazyQuery.test.tsx index a36c0725bea..150ce125fca 100644 --- a/src/react/hooks/__tests__/useLazyQuery.test.tsx +++ b/src/react/hooks/__tests__/useLazyQuery.test.tsx @@ -1115,7 +1115,7 @@ describe("useLazyQuery Hook", () => { ), }); - const [execute] = ProfiledHook.getCurrentSnapshot(); + const [execute] = await ProfiledHook.peekSnapshot(); { const [, result] = await ProfiledHook.takeSnapshot(); From d74c6917a11b289b7c4441be7051022dc913e9a7 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 20 Nov 2023 17:51:45 -0700 Subject: [PATCH 12/14] Minor tweak to error message --- src/testing/internal/profile/profile.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testing/internal/profile/profile.tsx b/src/testing/internal/profile/profile.tsx index c75555519e5..63da2d7f16e 100644 --- a/src/testing/internal/profile/profile.tsx +++ b/src/testing/internal/profile/profile.tsx @@ -245,7 +245,7 @@ export function profile< if (currentPosition < 0) { throw new Error( - "No render has occurred yet. You may need to call `takeRender` before you can get the current render." + "No current render available. You need to call `takeRender` before you can get the current render." ); } From 40a47f8a1ef0cef7617a14afa2398c052d3a536e Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 20 Nov 2023 17:59:55 -0700 Subject: [PATCH 13/14] Remove unused currentRender variable --- src/testing/internal/profile/profile.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/testing/internal/profile/profile.tsx b/src/testing/internal/profile/profile.tsx index 63da2d7f16e..8645f0b281c 100644 --- a/src/testing/internal/profile/profile.tsx +++ b/src/testing/internal/profile/profile.tsx @@ -101,7 +101,6 @@ export function profile< snapshotDOM?: boolean; initialSnapshot?: Snapshot; }) { - let currentRender: Render | undefined; let nextRender: Promise> | undefined; let resolveNextRender: ((render: Render) => void) | undefined; let rejectNextRender: ((error: unknown) => void) | undefined; @@ -169,8 +168,6 @@ export function profile< ? window.document.body.innerHTML : undefined; const render = new RenderInstance(baseRender, snapshot, domSnapshot); - // eslint-disable-next-line testing-library/render-result-naming-convention - currentRender = render; Profiled.renders.push(render); resolveNextRender?.(render); } catch (error) { From c29eb1d377ab7bf5d91e94b4cffb6f68aa99175d Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Tue, 21 Nov 2023 12:07:33 -0700 Subject: [PATCH 14/14] Rename setSnapshot to mergeSnapshot and updateSnapshot to replaceSnapshot --- .../__tests__/client/Query.test.tsx | 2 +- .../hoc/__tests__/queries/lifecycle.test.tsx | 2 +- .../hoc/__tests__/queries/loading.test.tsx | 2 +- .../__tests__/useBackgroundQuery.test.tsx | 8 +++--- .../hooks/__tests__/useFragment.test.tsx | 2 +- .../hooks/__tests__/useSuspenseQuery.test.tsx | 2 +- src/testing/internal/profile/profile.tsx | 26 ++++++++++--------- 7 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/react/components/__tests__/client/Query.test.tsx b/src/react/components/__tests__/client/Query.test.tsx index 3aee25d2685..acdd2015301 100644 --- a/src/react/components/__tests__/client/Query.test.tsx +++ b/src/react/components/__tests__/client/Query.test.tsx @@ -1491,7 +1491,7 @@ describe("Query component", () => { return ( {(r: any) => { - ProfiledContainer.updateSnapshot(r); + ProfiledContainer.replaceSnapshot(r); return null; }} diff --git a/src/react/hoc/__tests__/queries/lifecycle.test.tsx b/src/react/hoc/__tests__/queries/lifecycle.test.tsx index 99e7fbc6c5e..cf460af964a 100644 --- a/src/react/hoc/__tests__/queries/lifecycle.test.tsx +++ b/src/react/hoc/__tests__/queries/lifecycle.test.tsx @@ -52,7 +52,7 @@ describe("[queries] lifecycle", () => { })( class extends React.Component> { render() { - ProfiledApp.updateSnapshot(this.props.data!); + ProfiledApp.replaceSnapshot(this.props.data!); return null; } } diff --git a/src/react/hoc/__tests__/queries/loading.test.tsx b/src/react/hoc/__tests__/queries/loading.test.tsx index c2a40c0b9ec..387a6803fb5 100644 --- a/src/react/hoc/__tests__/queries/loading.test.tsx +++ b/src/react/hoc/__tests__/queries/loading.test.tsx @@ -407,7 +407,7 @@ describe("[queries] loading", () => { })( class extends React.Component> { render() { - ProfiledContainer.updateSnapshot(this.props.data!); + ProfiledContainer.replaceSnapshot(this.props.data!); return null; } } diff --git a/src/react/hooks/__tests__/useBackgroundQuery.test.tsx b/src/react/hooks/__tests__/useBackgroundQuery.test.tsx index d2ee0109c86..131364939cd 100644 --- a/src/react/hooks/__tests__/useBackgroundQuery.test.tsx +++ b/src/react/hooks/__tests__/useBackgroundQuery.test.tsx @@ -335,7 +335,7 @@ function renderVariablesIntegrationTest({ const ProfiledApp = profile>({ Component: App, snapshotDOM: true, - onRender: ({ updateSnapshot }) => updateSnapshot(cloneDeep(renders)), + onRender: ({ replaceSnapshot }) => replaceSnapshot(cloneDeep(renders)), }); const { ...rest } = render( @@ -434,7 +434,7 @@ function renderPaginatedIntegrationTest({ } function SuspenseFallback() { - ProfiledApp.setSnapshot(({ suspenseCount }) => ({ + ProfiledApp.mergeSnapshot(({ suspenseCount }) => ({ suspenseCount: suspenseCount + 1, })); return
loading
; @@ -449,7 +449,7 @@ function renderPaginatedIntegrationTest({ }) { const { data, error } = useReadQuery(queryRef); // count renders in the child component - ProfiledApp.setSnapshot(({ count }) => ({ + ProfiledApp.mergeSnapshot(({ count }) => ({ count: count + 1, })); return ( @@ -502,7 +502,7 @@ function renderPaginatedIntegrationTest({ Error} onError={(error) => { - ProfiledApp.setSnapshot(({ errorCount, errors }) => ({ + ProfiledApp.mergeSnapshot(({ errorCount, errors }) => ({ errorCount: errorCount + 1, errors: errors.concat(error), })); diff --git a/src/react/hooks/__tests__/useFragment.test.tsx b/src/react/hooks/__tests__/useFragment.test.tsx index 6ef04ad4d01..21b9e083a03 100644 --- a/src/react/hooks/__tests__/useFragment.test.tsx +++ b/src/react/hooks/__tests__/useFragment.test.tsx @@ -1476,7 +1476,7 @@ describe("has the same timing as `useQuery`", () => { from: initialItem, }); - ProfiledComponent.updateSnapshot({ queryData, fragmentData }); + ProfiledComponent.replaceSnapshot({ queryData, fragmentData }); return complete ? JSON.stringify(fragmentData) : "loading"; } diff --git a/src/react/hooks/__tests__/useSuspenseQuery.test.tsx b/src/react/hooks/__tests__/useSuspenseQuery.test.tsx index 468fe8f4fc5..642be7d023a 100644 --- a/src/react/hooks/__tests__/useSuspenseQuery.test.tsx +++ b/src/react/hooks/__tests__/useSuspenseQuery.test.tsx @@ -357,7 +357,7 @@ describe("useSuspenseQuery", () => { const Component = () => { const result = useSuspenseQuery(query); - ProfiledApp.updateSnapshot(result); + ProfiledApp.replaceSnapshot(result); return
{result.data.greeting}
; }; diff --git a/src/testing/internal/profile/profile.tsx b/src/testing/internal/profile/profile.tsx index 8645f0b281c..8ae43b64c01 100644 --- a/src/testing/internal/profile/profile.tsx +++ b/src/testing/internal/profile/profile.tsx @@ -25,12 +25,12 @@ export interface ProfiledComponent ProfiledComponentFields, ProfiledComponentOnlyFields {} -interface UpdateSnapshot { +interface ReplaceSnapshot { (newSnapshot: Snapshot): void; (updateSnapshot: (lastSnapshot: Readonly) => Snapshot): void; } -interface SetSnapshot { +interface MergeSnapshot { (partialSnapshot: Partial): void; ( updatePartialSnapshot: ( @@ -41,9 +41,9 @@ interface SetSnapshot { interface ProfiledComponentOnlyFields { // Allows for partial updating of the snapshot by shallow merging the results - setSnapshot: SetSnapshot; + mergeSnapshot: MergeSnapshot; // Performs a full replacement of the snapshot - updateSnapshot: UpdateSnapshot; + replaceSnapshot: ReplaceSnapshot; } interface ProfiledComponentFields { /** @@ -95,7 +95,8 @@ export function profile< onRender?: ( info: BaseRender & { snapshot: Snapshot; - updateSnapshot: UpdateSnapshot; + replaceSnapshot: ReplaceSnapshot; + mergeSnapshot: MergeSnapshot; } ) => void; snapshotDOM?: boolean; @@ -105,7 +106,7 @@ export function profile< let resolveNextRender: ((render: Render) => void) | undefined; let rejectNextRender: ((error: unknown) => void) | undefined; const snapshotRef = { current: initialSnapshot }; - const updateSnapshot: UpdateSnapshot = (snap) => { + const replaceSnapshot: ReplaceSnapshot = (snap) => { if (typeof snap === "function") { if (!initialSnapshot) { throw new Error( @@ -123,8 +124,8 @@ export function profile< } }; - const setSnapshot: SetSnapshot = (partialSnapshot) => { - updateSnapshot((snapshot) => ({ + const mergeSnapshot: MergeSnapshot = (partialSnapshot) => { + replaceSnapshot((snapshot) => ({ ...snapshot, ...(typeof partialSnapshot === "function" ? partialSnapshot(snapshot) @@ -159,7 +160,8 @@ export function profile< */ onRender?.({ ...baseRender, - updateSnapshot, + replaceSnapshot, + mergeSnapshot, snapshot: snapshotRef.current!, }); @@ -190,8 +192,8 @@ export function profile< ), { - updateSnapshot, - setSnapshot, + replaceSnapshot, + mergeSnapshot, } satisfies ProfiledComponentOnlyFields, { renders: new Array< @@ -327,7 +329,7 @@ export function profileHook( ): ProfiledHook { let returnValue: ReturnValue; const Component = (props: Props) => { - ProfiledComponent.updateSnapshot(renderCallback(props)); + ProfiledComponent.replaceSnapshot(renderCallback(props)); return null; }; const ProfiledComponent = profile({