import { act, renderHook } from "@testing-library/react";

import { useControllableObjectState } from "./useControllableState";

describe("useControllableObjectState", () => {
  it("keeps controlled setters stable when the external value changes", () => {
    const onChange = jest.fn();
    const { result, rerender } = renderHook(
      ({ value }: { value: { count: number } }) =>
        useControllableObjectState(value, onChange, { count: 0 }),
      {
        initialProps: { value: { count: 0 } },
      },
    );

    const initialSetValue = result.current[1];
    const initialSetField = result.current[2];

    act(() => {
      result.current[2]("count", 1);
    });
    expect(onChange).toHaveBeenCalledWith({ count: 1 });

    rerender({ value: { count: 1 } });

    expect(result.current[1]).toBe(initialSetValue);
    expect(result.current[2]).toBe(initialSetField);
  });

  it("does not publish unchanged object fields", () => {
    const onChange = jest.fn();
    const { result } = renderHook(() =>
      useControllableObjectState({ count: 1 }, onChange, { count: 0 }),
    );

    act(() => {
      result.current[2]("count", 1);
    });

    expect(onChange).not.toHaveBeenCalled();
  });
});
