import { expect, test } from "bun:test";
import { predictLayout } from "../adapters/prediction.ts";
test("prediction measures desktop and mobile geometry and restores closed disclosure", async () => {
const html =
'
Menu
Content
';
const result = await predictLayout(html, {
selectors: [".panel"],
strict: true,
});
expect(result.predictions.map((prediction) => prediction.width)).toEqual([
400, 200,
]);
expect(result.predictions.map((prediction) => prediction.height)).toEqual([
180, 240,
]);
expect(result.html).not.toContain(" {
const html = `
`;
const result = await predictLayout(html, {
selectors: [".target"],
strict: true,
});
const target = result.predictions.filter(
(prediction) =>
prediction.selector === '[data-muddle-predicted="predict-0"]',
);
expect(target.map((prediction) => prediction.width)).toEqual([240, 160]);
expect(target.map((prediction) => prediction.x)).toEqual([100, 24]);
expect(result.html).toContain("--muddle-predicted-desktop-width: 240px");
expect(result.html).toContain("--muddle-predicted-mobile-width: 160px");
});
test("prediction settles chained relations before writing the static page", async () => {
const html = `
`;
const result = await predictLayout(html, {
selectors: [".target"],
strict: true,
});
const target = result.predictions.filter(
(prediction) =>
prediction.selector === '[data-muddle-predicted="predict-0"]',
);
expect(target.map((prediction) => prediction.width)).toEqual([216, 216]);
expect(target.map((prediction) => prediction.x)).toEqual([72, 72]);
});
test("prediction follows the page's widest mobile breakpoint", async () => {
const html =
'';
const result = await predictLayout(html, {
selectors: [".panel"],
strict: true,
});
expect(result.predictions.map((prediction) => prediction.width)).toEqual([
500, 280,
]);
expect(result.html).toContain("@media (max-width: 40rem)");
});
test("prediction emits each selected breakpointAcc relation layer", async () => {
const html =
'';
const result = await predictLayout(html, {
selectors: [".panel"],
breakpointAcc: ["LG", "MD"],
strict: true,
});
expect(result.html).toContain("--muddle-relate-panel-lg-width: 420px");
expect(result.html).toContain("--muddle-relate-panel-md-width: 300px");
expect(result.html).toContain("@media (max-width: 64rem)");
expect(result.html).toContain("@media (max-width: 48rem)");
});
test("prediction discovers dotted anchor groups and emits reflective metadata", async () => {
const html =
'';
const result = await predictLayout(html, { strict: true });
expect(result.groups).toEqual([
{ name: "docs", anchors: ["docs.intro", "docs.api"] },
]);
expect(result.html).toContain('data-muddle-group="docs"');
expect(result.html).toContain("--muddle-reflect-docs-count: 2");
});