PettyUI/packages/core/tests/form.test.ts
2026-03-31 23:03:52 +07:00

62 lines
2.4 KiB
TypeScript

import { describe, it, expect, beforeEach } from "vitest";
import { PettyForm } from "../src/components/form/index";
import { h } from "./helpers";
describe("petty-form", () => {
let el: PettyForm;
beforeEach(() => {
document.body.textContent = "";
el = document.createElement("petty-form") as PettyForm;
const label = h("label", { "data-part": "label" }, "Email");
const input = h("input", { "data-part": "control", type: "email", name: "email" });
const error = h("span", { "data-part": "error" });
const field = h("petty-form-field", { name: "email" }, label, input, error);
const submit = h("button", { type: "submit" }, "Submit");
const form = h("form", {}, field, submit);
el.appendChild(form);
document.body.appendChild(el);
});
it("registers the custom elements", () => {
expect(customElements.get("petty-form")).toBe(PettyForm);
expect(customElements.get("petty-form-field")).toBeDefined();
});
it("sets novalidate on the form", () => {
const form = el.querySelector("form")!;
expect(form.hasAttribute("novalidate")).toBe(true);
});
it("dispatches petty-submit with form data when no schema set", () => {
let detail: { data: Record<string, unknown> } | null = null;
el.addEventListener("petty-submit", ((e: CustomEvent) => {
detail = e.detail;
}) as EventListener);
const input = el.querySelector("input") as HTMLInputElement;
input.value = "test@example.com";
const form = el.querySelector("form")!;
form.dispatchEvent(new Event("submit", { cancelable: true }));
expect(detail!.data.email).toBe("test@example.com");
});
it("dispatches petty-invalid on schema failure and shows error", () => {
const mockSchema = {
safeParse: () => ({
success: false,
error: { issues: [{ path: ["email"], message: "Invalid email" }] },
}),
};
el.setSchema(mockSchema);
let detail: { errors: Array<{ path: Array<string | number>; message: string }> } | null = null;
el.addEventListener("petty-invalid", ((e: CustomEvent) => {
detail = e.detail;
}) as EventListener);
const form = el.querySelector("form")!;
form.dispatchEvent(new Event("submit", { cancelable: true }));
expect(detail!.errors[0].message).toBe("Invalid email");
expect(el.querySelector("[data-part=error]")!.textContent).toBe("Invalid email");
expect(el.querySelector("[data-part=control]")!.getAttribute("aria-invalid")).toBe("true");
});
});