- 51 headless Web Components (45 core + 6 animation) - Shared helpers: emit(), part(), listen(), wireLabel(), initialValue() - Zero `new CustomEvent` or `static #counter` — all use shared utils - Zod schemas for all 44 core components - MCP package with discover, inspect, compose, validate tools - Showcase with Aperture Science theme, M3 Expressive motion - 81 tests passing, TypeScript strict mode clean - Signals (~500B), SPA router (~400B), zero dependencies
48 lines
1.6 KiB
TypeScript
48 lines
1.6 KiB
TypeScript
import { describe, it, expect, beforeEach } from "vitest";
|
|
import { PettyRadioGroup } from "../src/components/radio-group/index";
|
|
import { h } from "./helpers";
|
|
|
|
describe("petty-radio-group", () => {
|
|
let el: PettyRadioGroup;
|
|
|
|
beforeEach(() => {
|
|
document.body.textContent = "";
|
|
el = document.createElement("petty-radio-group") as PettyRadioGroup;
|
|
el.setAttribute("default-value", "a");
|
|
el.appendChild(h("petty-radio-item", { value: "a" }, "Option A"));
|
|
el.appendChild(h("petty-radio-item", { value: "b" }, "Option B"));
|
|
el.appendChild(h("petty-radio-item", { value: "c" }, "Option C"));
|
|
document.body.appendChild(el);
|
|
});
|
|
|
|
it("registers the custom elements", () => {
|
|
expect(customElements.get("petty-radio-group")).toBe(PettyRadioGroup);
|
|
expect(customElements.get("petty-radio-item")).toBeDefined();
|
|
});
|
|
|
|
it("sets role radiogroup on connect", () => {
|
|
expect(el.getAttribute("role")).toBe("radiogroup");
|
|
});
|
|
|
|
it("initializes with default-value", () => {
|
|
expect(el.value).toBe("a");
|
|
});
|
|
|
|
it("syncs aria-checked on radio items", () => {
|
|
const itemA = el.querySelector("[value=a]")!;
|
|
const itemB = el.querySelector("[value=b]")!;
|
|
expect(itemA.getAttribute("aria-checked")).toBe("true");
|
|
expect(itemB.getAttribute("aria-checked")).toBe("false");
|
|
});
|
|
|
|
it("fires petty-change on selectValue", () => {
|
|
let detail: { value: string } | null = null;
|
|
el.addEventListener("petty-change", ((e: CustomEvent) => {
|
|
detail = e.detail;
|
|
}) as EventListener);
|
|
el.selectValue("b");
|
|
expect(detail).toEqual({ value: "b" });
|
|
expect(el.value).toBe("b");
|
|
});
|
|
});
|