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"); });