test(web): cover area layout operations and document round three
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
67
web/tests/unit/area-layout.test.mjs
Normal file
67
web/tests/unit/area-layout.test.mjs
Normal file
@@ -0,0 +1,67 @@
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import test from "node:test";
|
||||
import ts from "typescript";
|
||||
|
||||
const repoRoot = path.resolve(import.meta.dirname, "../../..");
|
||||
const sourcePath = path.join(repoRoot, "web/protocol/area-layout.ts");
|
||||
const transpiled = ts.transpileModule(fs.readFileSync(sourcePath, "utf8"), {
|
||||
compilerOptions: { module: ts.ModuleKind.ES2022, target: ts.ScriptTarget.ES2022 },
|
||||
fileName: sourcePath,
|
||||
reportDiagnostics: true,
|
||||
});
|
||||
assert.deepEqual(transpiled.diagnostics, []);
|
||||
const moduleUrl = "data:text/javascript;base64," + Buffer.from(transpiled.outputText).toString("base64");
|
||||
const { applyAreaOperation, findAreaNeighbor, measureAreaRects } = await import(moduleUrl);
|
||||
|
||||
function area(id, x, y, width, height, editor = "3D Viewport") {
|
||||
return { id, editor, regions: [], rect: { x, y, width, height }, maximized: false, contentKey: id };
|
||||
}
|
||||
function workspace(areas) {
|
||||
return { id: "Layout", name: "Layout", areas, activeAreaId: areas[0].id, revision: 0 };
|
||||
}
|
||||
|
||||
test("split creates a new generic area inside the active rect", () => {
|
||||
const state = workspace([area("viewport", 0, 0, 1, 1)]);
|
||||
const next = applyAreaOperation(state, { type: "SPLIT_AREA", areaId: "viewport", direction: "VERTICAL", factor: 0.5 });
|
||||
assert.equal(next.areas.length, 2);
|
||||
assert.equal(next.areas[0].rect.width, 0.5);
|
||||
assert.equal(next.areas[1].rect.x, 0.5);
|
||||
assert.equal(next.areas[1].contentKey, null);
|
||||
assert.equal(next.areas[1].editor, "3D Viewport");
|
||||
});
|
||||
|
||||
test("neighbor lookup uses perpendicular overlap and join unions rects", () => {
|
||||
const state = workspace([area("left", 0, 0, 0.5, 1), area("right", 0.5, 0, 0.5, 1, "Properties")]);
|
||||
assert.equal(findAreaNeighbor(state.areas, "right", "LEFT")?.id, "left");
|
||||
const next = applyAreaOperation(state, { type: "JOIN_AREA", areaId: "right", targetAreaId: "left" });
|
||||
assert.equal(next.areas.length, 1);
|
||||
assert.deepEqual(next.areas[0].rect, { x: 0, y: 0, width: 1, height: 1 });
|
||||
assert.equal(next.areas[0].editor, "Properties");
|
||||
});
|
||||
|
||||
test("swap exchanges editors but keeps slot identity", () => {
|
||||
const state = workspace([area("left", 0, 0, 0.5, 1), area("right", 0.5, 0, 0.5, 1, "Properties")]);
|
||||
const next = applyAreaOperation(state, { type: "SWAP_AREAS", areaId: "left", targetAreaId: "right" });
|
||||
assert.equal(next.areas.find((item) => item.id === "left")?.editor, "Properties");
|
||||
assert.equal(next.areas.find((item) => item.id === "right")?.editor, "3D Viewport");
|
||||
assert.equal(next.areas.find((item) => item.id === "left")?.contentKey, "left");
|
||||
});
|
||||
|
||||
test("close keeps at least one area and maximize toggles", () => {
|
||||
const state = workspace([area("viewport", 0, 0, 1, 1)]);
|
||||
assert.equal(applyAreaOperation(state, { type: "CLOSE_AREA", areaId: "viewport" }).areas.length, 1);
|
||||
const maximized = applyAreaOperation(state, { type: "TOGGLE_MAXIMIZE_AREA", areaId: "viewport" });
|
||||
assert.equal(maximized.areas[0].maximized, true);
|
||||
assert.equal(applyAreaOperation(maximized, { type: "TOGGLE_MAXIMIZE_AREA", areaId: "viewport" }).areas[0].maximized, false);
|
||||
});
|
||||
|
||||
test("DOM rect measurement converts to bottom-left normalized Blender rects", () => {
|
||||
const rect = (left, top, width, height) => ({ left, top, width, height, right: left + width, bottom: top + height });
|
||||
const rects = measureAreaRects([{ id: "viewport", editor: "3D Viewport", contentKey: "viewport", rect: rect(100, 50, 800, 600) }], rect(100, 50, 1000, 800));
|
||||
assert.equal(rects[0].rect.x, 0);
|
||||
assert.equal(rects[0].rect.width, 0.8);
|
||||
assert.equal(rects[0].rect.height, 0.75);
|
||||
assert.equal(rects[0].rect.y, 0.25);
|
||||
});
|
||||
Reference in New Issue
Block a user