import { renderHook } from '@testing-library/react';
import { useSyncEffect } from '../hooks/useSyncEffect';

describe('useSyncEffect', () => {
  it('should execute effect synchronously', () => {
    const effect = jest.fn(() => {
      return () => {}; // cleanup function
    });

    renderHook(() => {
      useSyncEffect(effect, []);
    });

    expect(effect).toHaveBeenCalledTimes(1);
  });

  it('should execute cleanup function on unmount', () => {
    const cleanup = jest.fn();
    const effect = jest.fn(() => cleanup);

    const { unmount } = renderHook(() => {
      useSyncEffect(effect, []);
    });

    unmount();

    expect(cleanup).toHaveBeenCalledTimes(1);
  });

  it('should re-execute effect when dependencies change', () => {
    const effect = jest.fn(() => {
      return () => {}; // cleanup function
    });

    const { rerender } = renderHook(
      ({ deps }) => {
        useSyncEffect(effect, deps);
      },
      {
        initialProps: { deps: [1] },
      }
    );

    expect(effect).toHaveBeenCalledTimes(1);

    rerender({ deps: [2] });

    expect(effect).toHaveBeenCalledTimes(2);
  });

  it('should call cleanup before re-executing effect', () => {
    const cleanup = jest.fn();
    const effect = jest.fn(() => cleanup);

    const { rerender } = renderHook(
      ({ deps }) => {
        useSyncEffect(effect, deps);
      },
      {
        initialProps: { deps: [1] },
      }
    );

    rerender({ deps: [2] });

    // Cleanup should be called before new effect
    expect(cleanup).toHaveBeenCalled();
  });
});

