import { renderHook } from "@testing-library/react";
import fc from "fast-check";
import { describe, expect, it, vi } from "vitest";
import { useKeyCallback, useEnterCallback } from "./index";
describe("hook:useKeyCallback", () => {
    it("calls callback when key matches", () => {
        let callback = vi.fn();
        let { result } = renderHook(() => useKeyCallback(["Enter"], callback));
        let event = { key: "Enter" };
        result.current(event);
        expect(callback).toHaveBeenCalledTimes(1);
        expect(callback.mock.calls[0][0]).toBe(event);
    });
    it("does not call callback when key does not match", () => {
        let callback = vi.fn();
        let { result } = renderHook(() => useKeyCallback(["Enter"], callback));
        let event = { key: "Escape" };
        result.current(event);
        expect(callback).toHaveBeenCalledTimes(0);
    });
    it("handles multiple keys", () => {
        let callback = vi.fn();
        let { result } = renderHook(() => useKeyCallback(["Enter", "Escape"], callback));
        result.current({ key: "Enter" });
        expect(callback).toHaveBeenCalledTimes(1);
        result.current({ key: "Escape" });
        expect(callback).toHaveBeenCalledTimes(2);
        result.current({ key: "Space" });
        expect(callback).toHaveBeenCalledTimes(2);
    });
    it("fuzzing: handles random keys", () => {
        fc.assert(fc.property(fc.array(fc.string(), { minLength: 1 }), fc.string(), (keys, inputKey) => {
            // We need to cast keys to any because we are passing random strings, 
            // but the hook expects KeyValues type. Runtime it should be fine.
            let callback = vi.fn();
            let { result } = renderHook(() => useKeyCallback(keys, callback));
            result.current({ key: inputKey });
            if (keys.includes(inputKey)) {
                expect(callback).toHaveBeenCalledTimes(1);
            }
            else {
                expect(callback).toHaveBeenCalledTimes(0);
            }
        }));
    });
});
describe("hook:useEnterCallback", () => {
    it("calls callback on Enter", () => {
        let callback = vi.fn();
        let { result } = renderHook(() => useEnterCallback(callback));
        result.current({ key: "Enter" });
        expect(callback).toHaveBeenCalledTimes(1);
    });
    it("does not call callback on other keys", () => {
        let callback = vi.fn();
        let { result } = renderHook(() => useEnterCallback(callback));
        result.current({ key: "Escape" });
        expect(callback).toHaveBeenCalledTimes(0);
    });
});
