1// @effect-diagnostics nodeBuiltinImport:off -- Runs the actual QML geometry library without a desktop.
2import * as NodeFSP from "node:fs/promises";
3import * as NodeVM from "node:vm";
4import { expect, it } from "vite-plus/test";
5
6const source = await NodeFSP.readFile(new URL("./feedbackGeometry.js", import.meta.url), "utf8");
7const target = {
8 pid: 123,
9 caption: "Draft",
10 minimized: false,
11 clientGeometry: { x: -1920, y: 30, width: 1280, height: 900 },
12};
13const frame = { x: 0.25, y: 0.5, width: 0.2, height: 0.1 };
14function destination(windows = [target], relative = frame) {
15 return NodeVM.runInNewContext(`${source}\ndestination(windows, 123, "Draft", relative)`, {
16 windows,
17 relative,
18 });
19}
20it("maps normalized composer coordinates to the exact owning window's client area", () => {
21 expect(destination([{ ...target, pid: 999 }, target]).frame).toEqual({
22 x: -1600,
23 y: 480,
24 width: 256,
25 height: 90,
26 });
27});
28it("rejects lookalikes, ambiguous or hidden windows", () => {
29 for (const windows of [
30 [],
31 [{ ...target, pid: 999 }],
32 [target, target],
33 [{ ...target, minimized: true }],
34 ]) {
35 expect(() => destination(windows)).toThrow();
36 }
37});
38it("rejects invalid or out-of-bounds destinations instead of moving across unrelated windows", () => {
39 for (const invalid of [
40 { ...frame, x: -0.1 },
41 { ...frame, width: 2 },
42 { ...frame, height: 0 },
43 { ...frame, y: NaN },
44 ]) {
45 expect(() => destination([target], invalid)).toThrow("Invalid capture destination");
46 }
47});