import { render, screen } from "@testing-library/react";
import { userEvent } from "@testing-library/user-event";
import { useKeyboardControls } from "./useKeyboardControls";
describe("useKeyboardControls()", () => {
const activate = vi.fn();
const start = vi.fn();
const end = vi.fn();
const up = vi.fn();
const down = vi.fn();
const left = vi.fn();
const right = vi.fn();
beforeEach(() => {
vi.clearAllMocks();
});
const Test = () => {
const handle = useKeyboardControls({ activate, start, end, up, down, left, right });
return (
Test
);
};
describe("on Enter", () => {
it('call the "activate" callback', async () => {
render();
const button = screen.getByRole("button");
button.focus();
await userEvent.keyboard("[Enter]{Enter}");
expect(activate).toHaveBeenCalledTimes(2);
expect(start).not.toHaveBeenCalled();
expect(end).not.toHaveBeenCalled();
expect(up).not.toHaveBeenCalled();
expect(down).not.toHaveBeenCalled();
expect(left).not.toHaveBeenCalled();
expect(right).not.toHaveBeenCalled();
});
});
describe("on Spacebar", () => {
it('call the "activate" callback', async () => {
render();
const button = screen.getByRole("button");
button.focus();
await userEvent.keyboard("[Space]{ }{Spacebar}");
expect(activate).toHaveBeenCalledTimes(3);
expect(start).not.toHaveBeenCalled();
expect(end).not.toHaveBeenCalled();
expect(up).not.toHaveBeenCalled();
expect(down).not.toHaveBeenCalled();
expect(left).not.toHaveBeenCalled();
expect(right).not.toHaveBeenCalled();
});
});
describe("on Home", () => {
it('call the "start" callback', async () => {
render();
const button = screen.getByRole("button");
button.focus();
await userEvent.keyboard("[Home]");
expect(activate).not.toHaveBeenCalled();
expect(start).toHaveBeenCalledTimes(1);
expect(end).not.toHaveBeenCalled();
expect(up).not.toHaveBeenCalled();
expect(down).not.toHaveBeenCalled();
expect(left).not.toHaveBeenCalled();
expect(right).not.toHaveBeenCalled();
});
});
describe("on End", () => {
it('call the "end" callback', async () => {
render();
const button = screen.getByRole("button");
button.focus();
await userEvent.keyboard("[End]");
expect(activate).not.toHaveBeenCalled();
expect(start).not.toHaveBeenCalled();
expect(end).toHaveBeenCalledTimes(1);
expect(up).not.toHaveBeenCalled();
expect(down).not.toHaveBeenCalled();
expect(left).not.toHaveBeenCalled();
expect(right).not.toHaveBeenCalled();
});
});
describe("on Arrow Up", () => {
it('call the "up" callback', async () => {
render();
const button = screen.getByRole("button");
button.focus();
await userEvent.keyboard("[ArrowUp]");
expect(activate).not.toHaveBeenCalled();
expect(start).not.toHaveBeenCalled();
expect(end).not.toHaveBeenCalled();
expect(up).toHaveBeenCalledTimes(1);
expect(down).not.toHaveBeenCalled();
expect(left).not.toHaveBeenCalled();
expect(right).not.toHaveBeenCalled();
});
});
describe("on Arrow Down", () => {
it('call the "down" callback', async () => {
render();
const button = screen.getByRole("button");
button.focus();
await userEvent.keyboard("[ArrowDown]");
expect(activate).not.toHaveBeenCalled();
expect(start).not.toHaveBeenCalled();
expect(end).not.toHaveBeenCalled();
expect(up).not.toHaveBeenCalled();
expect(down).toHaveBeenCalledTimes(1);
expect(left).not.toHaveBeenCalled();
expect(right).not.toHaveBeenCalled();
});
});
describe("on Arrow Left", () => {
it('call the "left" callback', async () => {
render();
const button = screen.getByRole("button");
button.focus();
await userEvent.keyboard("[ArrowLeft]");
expect(activate).not.toHaveBeenCalled();
expect(start).not.toHaveBeenCalled();
expect(end).not.toHaveBeenCalled();
expect(up).not.toHaveBeenCalled();
expect(down).not.toHaveBeenCalled();
expect(left).toHaveBeenCalledTimes(1);
expect(right).not.toHaveBeenCalled();
});
});
describe("on Arrow Right", () => {
it('call the "right" callback', async () => {
render();
const button = screen.getByRole("button");
button.focus();
await userEvent.keyboard("[ArrowRight]");
expect(activate).not.toHaveBeenCalled();
expect(start).not.toHaveBeenCalled();
expect(end).not.toHaveBeenCalled();
expect(up).not.toHaveBeenCalled();
expect(down).not.toHaveBeenCalled();
expect(left).not.toHaveBeenCalled();
expect(right).toHaveBeenCalledTimes(1);
});
});
describe("without any callback", () => {
it("does nothing", async () => {
const Test = () => {
const handle = useKeyboardControls({ activate });
return (
Test
);
};
render();
const button = screen.getByRole("button");
button.focus();
await userEvent.keyboard("[ArrowUp][ArrowUp][ArrowDown][ArrowDown][ArrowLeft][ArrowRight][ArrowLeft][ArrowRight]{b}{a}[Enter]");
expect(activate).toHaveBeenCalledTimes(1);
expect(start).not.toHaveBeenCalled();
expect(end).not.toHaveBeenCalled();
expect(up).not.toHaveBeenCalled();
expect(down).not.toHaveBeenCalled();
expect(left).not.toHaveBeenCalled();
expect(right).not.toHaveBeenCalledTimes(1);
});
});
});