Composes Calendar inside a floating dropdown anchored to an input, with Intl locale formatting, controlled/uncontrolled date+open state, createDismiss for outside-click handling, and hidden input for form submission.
101 lines
3.3 KiB
TypeScript
101 lines
3.3 KiB
TypeScript
import { fireEvent, render, screen } from "@solidjs/testing-library";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import { DatePicker } from "../../../src/components/date-picker/index";
|
|
import { DatePickerRootPropsSchema, DatePickerMeta } from "../../../src/components/date-picker/index";
|
|
|
|
function renderPicker(props: Record<string, unknown> = {}) {
|
|
return render(() => (
|
|
<DatePicker {...props}>
|
|
<DatePicker.Input data-testid="input" />
|
|
<DatePicker.Trigger data-testid="trigger">Open</DatePicker.Trigger>
|
|
<DatePicker.Content data-testid="content">
|
|
<span>Calendar goes here</span>
|
|
</DatePicker.Content>
|
|
</DatePicker>
|
|
));
|
|
}
|
|
|
|
describe("DatePicker — rendering", () => {
|
|
it("renders input with placeholder", () => {
|
|
renderPicker();
|
|
const input = screen.getByTestId("input") as HTMLInputElement;
|
|
expect(input.placeholder).toBe("Select date");
|
|
});
|
|
|
|
it("renders custom placeholder", () => {
|
|
renderPicker({ placeholder: "Pick a date" });
|
|
const input = screen.getByTestId("input") as HTMLInputElement;
|
|
expect(input.placeholder).toBe("Pick a date");
|
|
});
|
|
|
|
it("shows formatted date when value set", () => {
|
|
renderPicker({ value: "2024-01-15" });
|
|
const input = screen.getByTestId("input") as HTMLInputElement;
|
|
expect(input.value).toMatch(/january/i);
|
|
expect(input.value).toMatch(/15/);
|
|
expect(input.value).toMatch(/2024/);
|
|
});
|
|
|
|
it("content hidden when closed", () => {
|
|
renderPicker();
|
|
expect(screen.queryByTestId("content")).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("DatePicker — open/close", () => {
|
|
it("trigger click opens content", () => {
|
|
renderPicker();
|
|
fireEvent.click(screen.getByTestId("trigger"));
|
|
expect(screen.getByTestId("content")).toBeTruthy();
|
|
});
|
|
|
|
it("input click opens content", () => {
|
|
renderPicker();
|
|
fireEvent.click(screen.getByTestId("input"));
|
|
expect(screen.getByTestId("content")).toBeTruthy();
|
|
});
|
|
|
|
it("renders open when defaultOpen is true", () => {
|
|
renderPicker({ defaultOpen: true });
|
|
expect(screen.getByTestId("content")).toBeTruthy();
|
|
});
|
|
|
|
it("controlled open state shows content", () => {
|
|
renderPicker({ open: true, onOpenChange: vi.fn() });
|
|
expect(screen.getByTestId("content")).toBeTruthy();
|
|
});
|
|
|
|
it("open content has role=dialog", () => {
|
|
renderPicker({ defaultOpen: true });
|
|
expect(screen.getByRole("dialog")).toBeTruthy();
|
|
});
|
|
});
|
|
|
|
describe("DatePicker — schema and meta", () => {
|
|
it("schema validates valid ISO date", () => {
|
|
expect(DatePickerRootPropsSchema.safeParse({ value: "2024-06-01" }).success).toBe(true);
|
|
});
|
|
|
|
it("schema rejects non-string value", () => {
|
|
expect(DatePickerRootPropsSchema.safeParse({ value: 20240601 }).success).toBe(false);
|
|
});
|
|
|
|
it("schema accepts all optional fields absent", () => {
|
|
expect(DatePickerRootPropsSchema.safeParse({}).success).toBe(true);
|
|
});
|
|
|
|
it("meta has correct name", () => {
|
|
expect(DatePickerMeta.name).toBe("DatePicker");
|
|
});
|
|
|
|
it("meta contains required parts", () => {
|
|
expect(DatePickerMeta.parts).toContain("Root");
|
|
expect(DatePickerMeta.parts).toContain("Input");
|
|
expect(DatePickerMeta.parts).toContain("Content");
|
|
});
|
|
|
|
it("meta lists Calendar as a part", () => {
|
|
expect(DatePickerMeta.parts).toContain("Calendar");
|
|
});
|
|
});
|