import React, { Dispatch, useEffect, useState } from "react"; import { act, render } from "@testing-library/react-native"; import { View } from "react-native"; import { FreezeWithCallback } from "../index"; const SimpleContent = () => ; interface InnerProps { value: number; } // eslint-disable-next-line unused-imports/no-unused-vars const Inner = ({ value }: InnerProps) => ( ); interface TestSubscriber { renderCount: number; subscription: Dispatch; } function createSubscriberComponent(): [React.FC, TestSubscriber] { const testState: TestSubscriber = { renderCount: 0, subscription: () => {}, }; const Subscriber: React.FC = () => { const [value, setValue] = useState(0); useEffect(() => { testState.subscription = setValue; }, []); testState.renderCount += 1; return ; }; return [Subscriber, testState]; } interface ContainerProps { freeze: boolean; children: React.ReactNode; } const Container = ({ freeze, children }: ContainerProps) => ( {children} ); function setupTest(initialFreeze: boolean = false) { const [Subscriber, subscriberState] = createSubscriberComponent(); const renderResult = render( ); return { renderResult, subscriberState, updateFreeze: (freeze: boolean) => { act(() => renderResult.rerender( ) ); }, }; } describe("FreezeWithCallback", () => { test("Renders stuff not frozen", () => { const { getByTestId } = render( ); expect(getByTestId("simple-content")).toBeTruthy(); }); test("Does not render stuff when frozen", () => { const { queryByTestId } = render( ); expect(queryByTestId("simple-content")).toBe(null); }); test("Stuff is gone after freeze", () => { const { toJSON, getByTestId, rerender } = render( ); expect(getByTestId("simple-content")).toBeTruthy(); act(() => rerender( ) ); expect(toJSON()).toBe(null); }); test("Updates work when not frozen", () => { const { renderResult, subscriberState } = setupTest(); expect( renderResult.getByTestId("inner-component").props["data-value"] ).toEqual(0); act(() => subscriberState.subscription(1)); expect( renderResult.getByTestId("inner-component").props["data-value"] ).toEqual(1); expect(subscriberState.renderCount).toBe(2); }); test("Updates does not propagate when frozen", () => { const { renderResult, subscriberState, updateFreeze } = setupTest(); expect( renderResult.getByTestId("inner-component").props["data-value"] ).toEqual(0); updateFreeze(true); act(() => subscriberState.subscription(1)); expect( renderResult.getByTestId("inner-component").props["data-value"] ).toEqual(0); expect(subscriberState.renderCount).toBe(1); }); test("State persists after defrost", () => { const { renderResult, subscriberState, updateFreeze } = setupTest(); expect( renderResult.getByTestId("inner-component").props["data-value"] ).toEqual(0); act(() => subscriberState.subscription(1)); expect( renderResult.getByTestId("inner-component").props["data-value"] ).toEqual(1); updateFreeze(true); expect(renderResult.toJSON()).toBe(null); updateFreeze(false); expect(renderResult.getByTestId("inner-component")).toBeTruthy(); expect( renderResult.getByTestId("inner-component").props["data-value"] ).toEqual(1); }); test("Update propagate after defrost", () => { const { renderResult, subscriberState, updateFreeze } = setupTest(); updateFreeze(true); act(() => subscriberState.subscription(1)); act(() => subscriberState.subscription(2)); act(() => subscriberState.subscription(3)); expect( renderResult.getByTestId("inner-component").props["data-value"] ).toEqual(0); updateFreeze(false); expect( renderResult.getByTestId("inner-component").props["data-value"] ).toEqual(3); expect(subscriberState.renderCount).toBe(2); }); });