import { test, expect } from "bun:test"; import { Window } from "happy-dom"; import { REACTIVE_RUNTIME } from "../src/reactive-runtime.ts"; function fixture(panel: Record, clipped = false) { const win = new Window(); win.document.body.innerHTML = '
'; const element = win.document.querySelector("[data-wrn-anchored]")! as any; const host = element.parentElement; const rect = (left: number, top: number, width: number, height: number) => ({ left, top, width, height, right: left + width, bottom: top + height, }); host.getBoundingClientRect = () => rect(270, 170, 40, 30); element.getBoundingClientRect = () => rect( panel.left, panel.top, Math.min(panel.width, parseFloat(element.style.maxWidth) || Infinity), Math.min(panel.height, parseFloat(element.style.maxHeight) || Infinity), ); if (clipped) { const clip = win.document.querySelector("#clip")! as any; clip.style.overflow = "hidden"; clip.getBoundingClientRect = () => rect(100, 50, 220, 220); Object.defineProperty(clip, "clientWidth", { value: 220 }); Object.defineProperty(clip, "clientHeight", { value: 220 }); } const start = REACTIVE_RUNTIME.indexOf(" function isRenderedElement("); const end = REACTIVE_RUNTIME.indexOf(" function repositionAnchored(", start); const clamp = new Function( "window", "document", "ANCHOR_MARGIN", REACTIVE_RUNTIME.slice(start, end) + "; return clampAnchored;", )(win, win.document, 8); return { win, element, clamp }; } test("anchored panels fit clipping containers and positioning does not drift", async () => { const { win, element, clamp } = fixture({ left: 40, top: 208, width: 180, height: 100 }, true); clamp(element); expect(element.style.translate).toBe("68px -146px"); clamp(element); expect(element.style.translate).toBe("68px -146px"); await win.happyDOM.close(); }); test("oversized panels become scrollable and recover authored sizing when space returns", async () => { const { win, element, clamp } = fixture({ left: 40, top: 60, width: 500, height: 400 }, true); element.style.minWidth = "300px"; clamp(element); expect(element.style.maxWidth).toBe("204px"); expect(element.style.maxHeight).toBe("204px"); expect(element.style.overflow).toBe("auto"); element.parentElement.parentElement.style.overflow = "visible"; clamp(element); expect(element.style.minWidth).toBe("300px"); expect(element.style.maxWidth).toBe(""); await win.happyDOM.close(); });