| 1 | import { describe, expect, it } from "vite-plus/test"; |
| 2 | |
| 3 | import { |
| 4 | resizeBrowserViewportFromRail, |
| 5 | resizeFreeformViewport, |
| 6 | resolveBrowserDeviceViewportLayout, |
| 7 | resolveFittedBrowserViewport, |
| 8 | resolveBrowserViewportLayout, |
| 9 | resolveResponsiveBrowserViewportSize, |
| 10 | } from "./browserViewportLayout"; |
| 11 | |
| 12 | describe("resolveBrowserViewportLayout", () => { |
| 13 | it("uses the current fixed viewport instead of stale fitted source dimensions", () => { |
| 14 | expect( |
| 15 | resolveFittedBrowserViewport( |
| 16 | { _tag: "freeform", width: 900, height: 600 }, |
| 17 | { width: 1280, height: 800, scale: 1 }, |
| 18 | ), |
| 19 | ).toEqual({ _tag: "freeform", width: 900, height: 600 }); |
| 20 | }); |
| 21 | |
| 22 | it("preserves the last logical viewport when fitting a fill-mode surface", () => { |
| 23 | expect( |
| 24 | resolveFittedBrowserViewport({ _tag: "fill" }, { width: 320, height: 200, scale: 0.25 }), |
| 25 | ).toEqual({ _tag: "freeform", width: 1280, height: 800 }); |
| 26 | }); |
| 27 | |
| 28 | it("fills the available surface in fill mode", () => { |
| 29 | expect(resolveBrowserViewportLayout({ width: 700, height: 500 }, { _tag: "fill" })).toEqual({ |
| 30 | canvasWidth: 700, |
| 31 | canvasHeight: 500, |
| 32 | viewportX: 0, |
| 33 | viewportY: 0, |
| 34 | viewportWidth: 700, |
| 35 | viewportHeight: 500, |
| 36 | viewportScale: 1, |
| 37 | fillsPanel: true, |
| 38 | }); |
| 39 | }); |
| 40 | |
| 41 | it("centers a smaller fixed viewport", () => { |
| 42 | expect( |
| 43 | resolveBrowserViewportLayout( |
| 44 | { width: 700, height: 1000 }, |
| 45 | { _tag: "freeform", width: 393, height: 852 }, |
| 46 | ), |
| 47 | ).toMatchObject({ |
| 48 | canvasWidth: 700, |
| 49 | canvasHeight: 1000, |
| 50 | viewportX: 154, |
| 51 | viewportY: 74, |
| 52 | viewportWidth: 393, |
| 53 | viewportHeight: 852, |
| 54 | }); |
| 55 | }); |
| 56 | |
| 57 | it("scales a larger fixed viewport down to fit without creating overflow", () => { |
| 58 | const layout = resolveBrowserViewportLayout( |
| 59 | { width: 600, height: 700 }, |
| 60 | { _tag: "freeform", width: 1440, height: 900 }, |
| 61 | ); |
| 62 | expect(layout).toMatchObject({ |
| 63 | canvasWidth: 600, |
| 64 | canvasHeight: 700, |
| 65 | viewportX: 0, |
| 66 | viewportY: 163, |
| 67 | viewportWidth: 600, |
| 68 | viewportHeight: 375, |
| 69 | }); |
| 70 | expect(layout.viewportScale).toBeCloseTo(5 / 12); |
| 71 | }); |
| 72 | |
| 73 | it("keeps fixed dimensions in page CSS pixels when browser zoom changes", () => { |
| 74 | expect( |
| 75 | resolveBrowserViewportLayout( |
| 76 | { width: 800, height: 700 }, |
| 77 | { _tag: "freeform", width: 400, height: 300 }, |
| 78 | 1.5, |
| 79 | ), |
| 80 | ).toMatchObject({ |
| 81 | viewportX: 100, |
| 82 | viewportY: 125, |
| 83 | viewportWidth: 600, |
| 84 | viewportHeight: 450, |
| 85 | }); |
| 86 | expect(resizeFreeformViewport({ width: 400, height: 300 }, { x: 150, y: 75 }, 1.5)).toEqual({ |
| 87 | width: 500, |
| 88 | height: 350, |
| 89 | }); |
| 90 | }); |
| 91 | |
| 92 | it("bounds freeform drag sizes and total render area", () => { |
| 93 | expect(resizeFreeformViewport({ width: 1024, height: 768 }, { x: -2000, y: -2000 })).toEqual({ |
| 94 | width: 240, |
| 95 | height: 240, |
| 96 | }); |
| 97 | const large = resizeFreeformViewport({ width: 1920, height: 1080 }, { x: 2000, y: 2000 }); |
| 98 | expect(large.width * large.height).toBeLessThanOrEqual(3840 * 2160); |
| 99 | }); |
| 100 | |
| 101 | it("resizes only the axes controlled by each edge", () => { |
| 102 | expect( |
| 103 | resizeFreeformViewport({ width: 800, height: 600 }, { x: -100, y: 500 }, 1, "west"), |
| 104 | ).toEqual({ width: 900, height: 600 }); |
| 105 | expect( |
| 106 | resizeFreeformViewport({ width: 800, height: 600 }, { x: 500, y: 100 }, 1, "north"), |
| 107 | ).toEqual({ width: 800, height: 500 }); |
| 108 | expect( |
| 109 | resizeFreeformViewport({ width: 800, height: 600 }, { x: -100, y: -50 }, 1, "northwest"), |
| 110 | ).toEqual({ width: 900, height: 650 }); |
| 111 | }); |
| 112 | |
| 113 | it("preserves a locked aspect ratio from either axis", () => { |
| 114 | expect( |
| 115 | resizeFreeformViewport({ width: 800, height: 600 }, { x: 200, y: 0 }, 1, "east", 4 / 3), |
| 116 | ).toEqual({ width: 1000, height: 750 }); |
| 117 | expect( |
| 118 | resizeFreeformViewport({ width: 800, height: 600 }, { x: 0, y: 150 }, 1, "south", 4 / 3), |
| 119 | ).toEqual({ width: 1000, height: 750 }); |
| 120 | }); |
| 121 | |
| 122 | it("reserves persistent device-toolbar rails around the guest viewport", () => { |
| 123 | expect( |
| 124 | resolveBrowserDeviceViewportLayout( |
| 125 | { width: 1200, height: 900 }, |
| 126 | { _tag: "freeform", width: 1168, height: 846 }, |
| 127 | ), |
| 128 | ).toEqual({ |
| 129 | canvasWidth: 1200, |
| 130 | canvasHeight: 900, |
| 131 | viewportX: 16, |
| 132 | viewportY: 38, |
| 133 | viewportWidth: 1168, |
| 134 | viewportHeight: 846, |
| 135 | viewportScale: 1, |
| 136 | fillsPanel: false, |
| 137 | }); |
| 138 | }); |
| 139 | |
| 140 | it("captures the available framed area when responsive mode is enabled", () => { |
| 141 | expect(resolveResponsiveBrowserViewportSize({ width: 1200, height: 900 })).toEqual({ |
| 142 | width: 1168, |
| 143 | height: 846, |
| 144 | }); |
| 145 | expect(resolveResponsiveBrowserViewportSize({ width: 1200, height: 900 }, 2)).toEqual({ |
| 146 | width: 584, |
| 147 | height: 423, |
| 148 | }); |
| 149 | }); |
| 150 | |
| 151 | it("keeps the grabbed rail under the pointer across centered layout boundaries", () => { |
| 152 | const available = { width: 1120, height: 818 }; |
| 153 | expect( |
| 154 | resizeBrowserViewportFromRail( |
| 155 | { width: 1120, height: 818 }, |
| 156 | { x: -100, y: -50 }, |
| 157 | available, |
| 158 | 1, |
| 159 | "southeast", |
| 160 | ), |
| 161 | ).toEqual({ width: 920, height: 718 }); |
| 162 | expect( |
| 163 | resizeBrowserViewportFromRail( |
| 164 | { width: 800, height: 600 }, |
| 165 | { x: 300, y: 0 }, |
| 166 | { width: 1200, height: 800 }, |
| 167 | 1, |
| 168 | "east", |
| 169 | ), |
| 170 | ).toEqual({ width: 1300, height: 600 }); |
| 171 | expect( |
| 172 | resizeBrowserViewportFromRail( |
| 173 | { width: 560, height: 409 }, |
| 174 | { x: -100, y: 0 }, |
| 175 | available, |
| 176 | 2, |
| 177 | "east", |
| 178 | ), |
| 179 | ).toEqual({ width: 460, height: 409 }); |
| 180 | }); |
| 181 | }); |