mirror of
https://github.com/jhbruhn/respira.git
synced 2026-01-27 02:13:41 +00:00
Add tests for all hooks with @testing-library/react: - utility hooks: usePrevious, useAutoScroll, useClickOutside - domain hooks: useErrorPopoverState, useMachinePolling - platform hooks: useBluetoothDeviceListener Changes: - Install @testing-library/react and jsdom for React hook testing - Configure vitest to use jsdom environment for React testing - Add 91 tests covering all hook functionality - Test state management, effects, event listeners, and async behavior - Verify proper cleanup and edge cases All tests passing. Coverage includes error states, polling intervals, click-outside detection, auto-scroll behavior, and IPC integration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
75 lines
2.1 KiB
TypeScript
75 lines
2.1 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
import { renderHook } from "@testing-library/react";
|
|
import { useAutoScroll } from "./useAutoScroll";
|
|
|
|
describe("useAutoScroll", () => {
|
|
beforeEach(() => {
|
|
// Mock scrollIntoView
|
|
Element.prototype.scrollIntoView = vi.fn();
|
|
});
|
|
|
|
it("should return a ref object", () => {
|
|
const { result } = renderHook(() => useAutoScroll(0));
|
|
expect(result.current).toHaveProperty("current");
|
|
});
|
|
|
|
it("should call scrollIntoView when dependency changes", () => {
|
|
const mockElement = document.createElement("div");
|
|
const scrollIntoViewMock = vi.fn();
|
|
mockElement.scrollIntoView = scrollIntoViewMock;
|
|
|
|
const { result, rerender } = renderHook(
|
|
({ dep }) => useAutoScroll(dep),
|
|
{ initialProps: { dep: 0 } },
|
|
);
|
|
|
|
// Attach mock element to ref
|
|
(result.current as { current: HTMLElement }).current = mockElement;
|
|
|
|
// Change dependency to trigger effect
|
|
rerender({ dep: 1 });
|
|
|
|
expect(scrollIntoViewMock).toHaveBeenCalledWith({
|
|
behavior: "smooth",
|
|
block: "nearest",
|
|
inline: undefined,
|
|
});
|
|
});
|
|
|
|
it("should use custom scroll options", () => {
|
|
const mockElement = document.createElement("div");
|
|
const scrollIntoViewMock = vi.fn();
|
|
mockElement.scrollIntoView = scrollIntoViewMock;
|
|
|
|
const { result, rerender } = renderHook(
|
|
({ dep }) =>
|
|
useAutoScroll(dep, {
|
|
behavior: "auto",
|
|
block: "start",
|
|
inline: "center",
|
|
}),
|
|
{ initialProps: { dep: 0 } },
|
|
);
|
|
|
|
(result.current as { current: HTMLElement }).current = mockElement;
|
|
rerender({ dep: 1 });
|
|
|
|
expect(scrollIntoViewMock).toHaveBeenCalledWith({
|
|
behavior: "auto",
|
|
block: "start",
|
|
inline: "center",
|
|
});
|
|
});
|
|
|
|
it("should not call scrollIntoView if ref is not attached", () => {
|
|
const { rerender } = renderHook(({ dep }) => useAutoScroll(dep), {
|
|
initialProps: { dep: 0 },
|
|
});
|
|
|
|
// Change dependency without attaching ref
|
|
rerender({ dep: 1 });
|
|
|
|
// Should not throw or cause errors
|
|
expect(true).toBe(true);
|
|
});
|
|
});
|