This repository has been archived on 2026-10-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
maestro/web/src/layout.test.ts
Miguel PalhasandClaude Sonnet 5 0cc25d7e1c
ci / rust (push) Successful in 9m12s
ci / web (push) Successful in 33s
ci / flake (push) Successful in 2m37s
fix(maestro): equalize split widths after spawning a session
splitLeaf always halved just the target pane, so repeated splits left
one pane at 50% and the rest squeezed into shrinking fractions instead
of equal columns.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 13:29:03 +01:00

108 lines
3.1 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
emptyLayout,
equalizeRatios,
leaves,
locateSession,
openSessions,
removeLeaf,
splitLeaf,
type Tab,
} from "./layout.js";
function tabWithOneLeaf(sessionId: string | null = null): Tab {
const layout = emptyLayout();
const tab = layout.tabs[0];
splitLeaf(tab, "", sessionId, "row", true);
return tab;
}
describe("splitLeaf", () => {
it("seeds an empty tab with a single leaf", () => {
const tab = tabWithOneLeaf("s1");
expect(leaves(tab.root)).toHaveLength(1);
expect(leaves(tab.root)[0].sessionId).toBe("s1");
});
it("splits a leaf in two and returns the new id", () => {
const tab = tabWithOneLeaf("s1");
const target = leaves(tab.root)[0].id;
const fresh = splitLeaf(tab, target, "s2", "row", true);
const ids = leaves(tab.root).map((l) => l.id);
expect(ids).toHaveLength(2);
expect(ids).toContain(fresh);
});
it("honours the side the caller asked for", () => {
const tab = tabWithOneLeaf("s1");
const target = leaves(tab.root)[0].id;
const fresh = splitLeaf(tab, target, "s2", "row", false);
expect(leaves(tab.root)[0].id).toBe(fresh);
});
});
describe("equalizeRatios", () => {
it("resets nested splits to equal width, not just the newest one", () => {
const tab = tabWithOneLeaf("s1");
const first = leaves(tab.root)[0].id;
splitLeaf(tab, first, "s2", "row", true); // A|B, 0.5/0.5
const second = leaves(tab.root)[1].id;
splitLeaf(tab, second, "s3", "row", true); // A(0.5) | (B|C, 0.5/0.5) -> B,C at 0.25 each
equalizeRatios(tab.root);
const root = tab.root as Extract<typeof tab.root, { kind: "split" }>;
expect(root.ratio).toBeCloseTo(1 / 3);
const inner = root.b as Extract<typeof root.b, { kind: "split" }>;
expect(inner.ratio).toBeCloseTo(1 / 2);
});
});
describe("removeLeaf", () => {
it("collapses the parent split into the surviving sibling", () => {
const tab = tabWithOneLeaf("s1");
const first = leaves(tab.root)[0].id;
splitLeaf(tab, first, "s2", "row", true);
removeLeaf(tab, first);
const remaining = leaves(tab.root);
expect(remaining).toHaveLength(1);
expect(remaining[0].sessionId).toBe("s2");
expect(tab.root?.kind).toBe("leaf");
});
it("empties the tab when the last leaf goes", () => {
const tab = tabWithOneLeaf("s1");
removeLeaf(tab, leaves(tab.root)[0].id);
expect(tab.root).toBeNull();
});
});
describe("locateSession / openSessions", () => {
it("finds the tab and leaf showing a session", () => {
const layout = emptyLayout();
const tab = layout.tabs[0];
splitLeaf(tab, "", "s1", "row", true);
const hit = locateSession(layout, "s1");
expect(hit?.tab.id).toBe(tab.id);
expect(hit?.leaf.sessionId).toBe("s1");
expect(locateSession(layout, "nope")).toBeNull();
});
it("reports every open session once", () => {
const layout = emptyLayout();
const tab = layout.tabs[0];
splitLeaf(tab, "", "s1", "row", true);
const first = leaves(tab.root)[0].id;
splitLeaf(tab, first, "s2", "row", true);
expect(openSessions(layout)).toEqual(new Set(["s1", "s2"]));
});
});