import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' import { renderHook, act } from '@testing-library/react' import { useDebouncedValue } from './useDebouncedValue' describe('useDebouncedValue', () => { beforeEach(() => { vi.useFakeTimers() }) afterEach(() => { vi.useRealTimers() }) it('returns initial value immediately', () => { const { result } = renderHook(() => useDebouncedValue('hello')) expect(result.current).toBe('hello') }) it('debounces value updates', () => { const { result, rerender } = renderHook( ({ value }) => useDebouncedValue(value, 300), { initialProps: { value: 'a' } }, ) expect(result.current).toBe('a') rerender({ value: 'b' }) expect(result.current).toBe('a') act(() => { vi.advanceTimersByTime(299) }) expect(result.current).toBe('a') act(() => { vi.advanceTimersByTime(1) }) expect(result.current).toBe('b') }) it('resets timer on rapid updates', () => { const { result, rerender } = renderHook( ({ value }) => useDebouncedValue(value, 200), { initialProps: { value: 'a' } }, ) rerender({ value: 'b' }) act(() => { vi.advanceTimersByTime(100) }) rerender({ value: 'c' }) act(() => { vi.advanceTimersByTime(100) }) expect(result.current).toBe('a') act(() => { vi.advanceTimersByTime(100) }) expect(result.current).toBe('c') }) it('uses custom delay', () => { const { result, rerender } = renderHook( ({ value }) => useDebouncedValue(value, 500), { initialProps: { value: 'x' } }, ) rerender({ value: 'y' }) act(() => { vi.advanceTimersByTime(499) }) expect(result.current).toBe('x') act(() => { vi.advanceTimersByTime(1) }) expect(result.current).toBe('y') }) it('works with numeric values', () => { const { result, rerender } = renderHook( ({ value }) => useDebouncedValue(value, 100), { initialProps: { value: 0 } }, ) rerender({ value: 42 }) act(() => { vi.advanceTimersByTime(100) }) expect(result.current).toBe(42) }) })