import { describe, it, expect, vi } from 'vitest'
import { debounce } from '../debounce'

describe('debounce', () => {
    it('attend delay ms avant d\'appeler fn une seule fois apres plusieurs invocations rapides', () => {
        vi.useFakeTimers()
        const fn = vi.fn()
        const debounced = debounce(fn, 100)

        debounced()
        debounced()
        debounced()
        expect(fn).not.toHaveBeenCalled()

        vi.advanceTimersByTime(100)
        expect(fn).toHaveBeenCalledTimes(1)

        vi.useRealTimers()
    })

    it('passe les arguments du dernier appel a fn', () => {
        vi.useFakeTimers()
        const fn = vi.fn<(a: string, b: number) => void>()
        const debounced = debounce(fn, 50)

        debounced('first', 1)
        debounced('second', 2)
        debounced('third', 3)
        vi.advanceTimersByTime(50)

        expect(fn).toHaveBeenCalledTimes(1)
        expect(fn).toHaveBeenCalledWith('third', 3)

        vi.useRealTimers()
    })

    it('autorise plusieurs executions espacees dans le temps', () => {
        vi.useFakeTimers()
        const fn = vi.fn()
        const debounced = debounce(fn, 50)

        debounced()
        vi.advanceTimersByTime(50)
        expect(fn).toHaveBeenCalledTimes(1)

        debounced()
        vi.advanceTimersByTime(50)
        expect(fn).toHaveBeenCalledTimes(2)

        vi.useRealTimers()
    })
})
