PettyUI/packages/core/tests/collapsible.test.ts
Mats Bosson 168b5642d0 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 21:42:29 +07:00

99 lines
3.3 KiB
TypeScript

import { describe, it, expect, beforeEach } from "vitest";
import { PettyCollapsible } from "../src/components/collapsible/index";
import { PettyProgress } from "../src/components/progress/index";
import "../src/components/alert/index";
describe("petty-collapsible", () => {
let el: PettyCollapsible;
beforeEach(() => {
document.body.textContent = "";
el = document.createElement("petty-collapsible") as PettyCollapsible;
const d = document.createElement("details");
const s = document.createElement("summary");
s.textContent = "Toggle";
const c = document.createElement("div");
c.setAttribute("data-part", "content");
c.textContent = "Content";
d.appendChild(s);
d.appendChild(c);
el.appendChild(d);
document.body.appendChild(el);
});
it("registers and defaults to closed", () => {
expect(customElements.get("petty-collapsible")).toBe(PettyCollapsible);
expect(el.isOpen).toBe(false);
});
it("open/close/toggle lifecycle", () => {
el.open();
expect(el.detailsElement!.open).toBe(true);
el.close();
expect(el.detailsElement!.open).toBe(false);
el.toggle();
expect(el.detailsElement!.open).toBe(true);
});
it("blocks open when disabled", () => {
el.setAttribute("disabled", "");
el.open();
expect(el.detailsElement!.open).toBe(false);
el.removeAttribute("disabled");
el.open();
expect(el.detailsElement!.open).toBe(true);
});
});
describe("petty-alert", () => {
let el: HTMLElement;
beforeEach(() => {
document.body.textContent = "";
el = document.createElement("petty-alert");
el.appendChild(document.createTextNode("msg"));
document.body.appendChild(el);
});
it("defaults to status role", () => {
expect(el.getAttribute("role")).toBe("status");
});
it("error and warning get alert role", () => {
el.setAttribute("variant", "error");
expect(el.getAttribute("role")).toBe("alert");
el.setAttribute("variant", "warning");
expect(el.getAttribute("role")).toBe("alert");
});
it("info gets status role then reverts on removal", () => {
el.setAttribute("variant", "info");
expect(el.getAttribute("role")).toBe("status");
el.removeAttribute("variant");
expect(el.getAttribute("role")).toBe("status");
});
});
describe("petty-progress", () => {
let el: PettyProgress;
beforeEach(() => {
document.body.textContent = "";
el = document.createElement("petty-progress") as PettyProgress;
const fill = document.createElement("div");
fill.setAttribute("data-part", "fill");
const label = document.createElement("span");
label.setAttribute("data-part", "label");
el.appendChild(fill);
el.appendChild(label);
document.body.appendChild(el);
});
it("sets progressbar ARIA", () => {
expect(el.getAttribute("role")).toBe("progressbar");
expect(el.getAttribute("aria-valuemin")).toBe("0");
});
it("tracks value and max", () => {
el.setAttribute("value", "50");
el.setAttribute("max", "200");
expect(el.value).toBe(50);
expect(el.dataset.state).toBe("loading");
});
it("complete state at max", () => {
el.setAttribute("value", "100");
expect(el.dataset.state).toBe("complete");
});
it("returns to indeterminate when value removed", () => {
el.setAttribute("value", "50");
el.removeAttribute("value");
expect(el.dataset.state).toBe("indeterminate");
});
});