Files
test/frontend/__tests__/components/common/anime/AnimeShow.spec.tsx
Benjamin Falch 2bc741fb78
Some checks failed
Mark Stale PRs / stale (push) Has been cancelled
adding monkeytype
2026-04-23 13:53:44 +02:00

158 lines
4.2 KiB
TypeScript

import { cleanup, render, screen } from "@solidjs/testing-library";
import { createSignal } from "solid-js";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const { mockAnimate } = vi.hoisted(() => ({
mockAnimate: vi.fn().mockImplementation(() => {
const callbacks: Array<() => void> = [];
const animation = {
pause: vi.fn(),
then: vi.fn((cb: () => void) => {
callbacks.push(cb);
// Invoke immediately so exit animations complete synchronously in tests
cb();
return Promise.resolve();
}),
};
return animation;
}),
}));
vi.mock("animejs", () => ({
animate: mockAnimate,
}));
vi.mock("../../../../src/ts/utils/misc", () => ({
applyReducedMotion: vi.fn((duration: number) => duration),
}));
import { AnimeShow } from "../../../../src/ts/components/common/anime/AnimeShow";
describe("AnimeShow", () => {
beforeEach(() => {
vi.clearAllMocks();
});
afterEach(() => {
cleanup();
});
it("renders children when `when` is true", () => {
render(() => (
<AnimeShow when={true}>
<div data-testid="content">hello</div>
</AnimeShow>
));
expect(screen.getByTestId("content")).toBeInTheDocument();
});
it("does not render children when `when` is false", () => {
render(() => (
<AnimeShow when={false}>
<div data-testid="content">hello</div>
</AnimeShow>
));
expect(screen.queryByTestId("content")).not.toBeInTheDocument();
});
it("shows and hides reactively", () => {
const [visible, setVisible] = createSignal(true);
render(() => (
<AnimeShow when={visible()}>
<div data-testid="content">hello</div>
</AnimeShow>
));
expect(screen.getByTestId("content")).toBeInTheDocument();
setVisible(false);
expect(screen.queryByTestId("content")).not.toBeInTheDocument();
setVisible(true);
expect(screen.getByTestId("content")).toBeInTheDocument();
});
it("applies class to the wrapper element when visible", () => {
const { container } = render(() => (
<AnimeShow when={true} class="my-class">
<span>content</span>
</AnimeShow>
));
expect(container.querySelector(".my-class")).toBeTruthy();
});
it("does not throw on mount/unmount", () => {
const [show, setShow] = createSignal(true);
expect(() => {
render(() => (
<AnimeShow when={show()}>
<div>content</div>
</AnimeShow>
));
}).not.toThrow();
expect(() => setShow(false)).not.toThrow();
});
describe("slide mode", () => {
it("renders children when `when` is true in slide mode", () => {
render(() => (
<AnimeShow when={true} slide>
<div data-testid="slide-content">slide</div>
</AnimeShow>
));
expect(screen.getByTestId("slide-content")).toBeInTheDocument();
});
it("does not render children when `when` is false in slide mode", () => {
render(() => (
<AnimeShow when={false} slide>
<div data-testid="slide-content">slide</div>
</AnimeShow>
));
expect(screen.queryByTestId("slide-content")).not.toBeInTheDocument();
});
it("animates height in slide mode", () => {
render(() => (
<AnimeShow when={true} slide>
<div>content</div>
</AnimeShow>
));
const heightCalls = mockAnimate.mock.calls.filter(
([, params]) => params.height !== undefined,
);
expect(heightCalls.length).toBeGreaterThan(0);
});
});
describe("duration prop", () => {
it("uses the provided duration", () => {
render(() => (
<AnimeShow when={true} duration={400}>
<div>content</div>
</AnimeShow>
));
const durationCalls = mockAnimate.mock.calls.filter(
([, params]) => params.duration === 400,
);
expect(durationCalls.length).toBeGreaterThan(0);
});
it("defaults to 125ms when no duration is provided", () => {
render(() => (
<AnimeShow when={true}>
<div>content</div>
</AnimeShow>
));
const defaultDurationCalls = mockAnimate.mock.calls.filter(
([, params]) => params.duration === 125,
);
expect(defaultDurationCalls.length).toBeGreaterThan(0);
});
});
});