muddle/tests/integrations.test.ts
2026-10-23 09:12:49 -04:00

81 lines
2.4 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import {
checkboxMarkup,
mouseTrackerMarkup,
mouseTrackerCss,
reactCss,
reactIntegration,
} from "../integrations/react.ts";
/**
* Tests of the reactivity integration: the state utilities, the native
* checkbox hack and the mouse tracker of the parent hack.
*/
describe("react integration", () => {
test("compiles the state utilities", () => {
const css = reactCss();
expect(css).toContain(".state-open");
expect(css).toContain(".state-closed");
expect(css).toContain('[data-state="open"]');
expect(css).toContain("--muddle-state: open;");
});
test("exposes checkbox state without prescribing visual styles", () => {
const css = reactCss();
expect(css).toContain('.peer:checked ~ [data-state="checked"]');
expect(css).not.toContain("background:");
expect(css).not.toContain("box-shadow:");
});
test("scopes the parent hack of the mouse tracker", () => {
const css = mouseTrackerCss({ columns: 4, rows: 3, scope: "card" });
const rules = css.match(/data-muddle-tracker="card"\]:has/g) ?? [];
expect(rules).toHaveLength(12);
expect(css).toContain("--muddle-mouse-x:");
expect(css).toContain("nth-child(1)");
expect(css).toContain("nth-child(12)");
});
test("renders the markup of the mouse tracker", () => {
const markup = mouseTrackerMarkup({ columns: 2, rows: 2 });
expect(markup.match(/mouse-tracker__cell/g) ?? []).toHaveLength(4);
expect(markup).toContain('class="mouse-tracker"');
expect(markup).toContain('data-muddle-capture="false"');
});
test("renders the markup of a checkbox", () => {
const markup = checkboxMarkup({
name: "published",
label: "Published",
checked: true,
});
expect(markup).toContain('type="checkbox"');
expect(markup).toContain('name="published"');
expect(markup).toContain("checked");
expect(markup).toContain("Published");
});
test("serves the stylesheet", async () => {
const routes: { method: string; path: string }[] = [];
const integration = reactIntegration();
await integration.setup?.({
config: {
root: process.cwd(),
views: "views",
components: "views/components",
content: "content",
styles: "styles",
publicDir: "public",
viewRoots: ["views"],
loaders: {},
collections: [],
integrations: [],
},
route: (method, path) => routes.push({ method, path }),
loader: () => undefined,
});
expect(routes).toEqual([{ method: "GET", path: "/_muddle/react.css" }]);
});
});