PettyUI/packages/core/tests/helpers.test.ts
Mats Bosson bf576905a7
Some checks are pending
CI / check (push) Waiting to run
All components, schemas, tests, MCP, and showcase
- 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
2026-03-31 20:21:41 +07:00

66 lines
2.2 KiB
TypeScript

import { describe, it, expect, beforeEach } from "vitest";
import { part, emit, initialValue, listen, wireLabel } from "../src/shared/helpers";
describe("shared helpers", () => {
beforeEach(() => { document.body.replaceChildren(); });
it("part() finds child by data-part attribute", () => {
const host = document.createElement("div");
const child = document.createElement("input");
child.dataset.part = "control";
host.appendChild(child);
expect(part(host, "control")).toBe(child);
expect(part(host, "missing")).toBeNull();
});
it("emit() dispatches a bubbling petty-prefixed event", () => {
const el = document.createElement("div");
document.body.appendChild(el);
let received: { value: unknown } | null = null;
document.body.addEventListener("petty-change", (e) => { received = (e as CustomEvent).detail; });
emit(el, "change", { value: "test" });
expect(received).toEqual({ value: "test" });
});
it("initialValue() reads default-value then value then empty", () => {
const el = document.createElement("div");
expect(initialValue(el)).toBe("");
el.setAttribute("value", "v");
expect(initialValue(el)).toBe("v");
el.setAttribute("default-value", "dv");
expect(initialValue(el)).toBe("dv");
});
it("listen() attaches and cleanup removes listeners", () => {
const el = document.createElement("button");
let count = 0;
const handler = () => { count++; };
const cleanup = listen(el, [["click", handler]]);
el.click();
expect(count).toBe(1);
cleanup();
el.click();
expect(count).toBe(1);
});
it("listen() returns noop for null element", () => {
const cleanup = listen(null, [["click", () => {}]]);
expect(typeof cleanup).toBe("function");
cleanup();
});
it("wireLabel() connects label htmlFor to control id", () => {
const control = document.createElement("input");
const label = document.createElement("label");
wireLabel(control, label, "test");
expect(control.id).toMatch(/^test-/);
expect(label.htmlFor).toBe(control.id);
});
it("wireLabel() does nothing with null label", () => {
const control = document.createElement("input");
wireLabel(control, null, "test");
expect(control.id).toBe("");
});
});