feat(charts): manage investigation charts in a scrolling workspace
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { columnsForLayout, reconcileChartSlots, swapChartSlots, type ChartSlot } from "./chart-window-slots";
|
||||
|
||||
describe("fixed chart slots", () => {
|
||||
it("maps supported layouts to grid columns", () => {
|
||||
expect([columnsForLayout("one"), columnsForLayout("two"), columnsForLayout("four")]).toEqual([1, 2, 2]);
|
||||
});
|
||||
|
||||
it("keeps chart positions when publications update in another order", () => {
|
||||
const slots: ChartSlot[] = ["flow", null, "pressure", "plans"];
|
||||
expect(reconcileChartSlots(slots, ["plans", "pressure", "flow"], 2)).toBe(slots);
|
||||
});
|
||||
|
||||
it("leaves deleted positions vacant without moving surviving charts", () => {
|
||||
expect(reconcileChartSlots(["pressure", "flow", "plans", null], ["pressure", "plans"], 2))
|
||||
.toEqual(["pressure", null, "plans", null]);
|
||||
});
|
||||
|
||||
it("fills the earliest vacant slots before appending a padded row", () => {
|
||||
expect(reconcileChartSlots(["pressure", null, "flow", null], ["new-1", "flow", "new-2", "pressure", "new-3"], 2))
|
||||
.toEqual(["pressure", "new-1", "flow", "new-2", "new-3", null]);
|
||||
});
|
||||
|
||||
it("uses vacancies created by a deletion in the same update", () => {
|
||||
expect(reconcileChartSlots(["pressure", "removed", "flow", null], ["pressure", "flow", "new"], 2))
|
||||
.toEqual(["pressure", "new", "flow", null]);
|
||||
});
|
||||
|
||||
it("preserves linear positions when the column count changes", () => {
|
||||
const slots: ChartSlot[] = ["a", null, "b", "c", "d", null];
|
||||
expect(reconcileChartSlots(slots, ["a", "b", "c", "d"], 1)).toEqual(["a", null, "b", "c", "d"]);
|
||||
expect(reconcileChartSlots(slots, ["a", "b", "c", "d"], 2)).toBe(slots);
|
||||
});
|
||||
|
||||
it("trims only empty trailing rows, retaining leading and middle vacancies", () => {
|
||||
expect(reconcileChartSlots([null, null, "a", null, null, null, null, null], ["a"], 2))
|
||||
.toEqual([null, null, "a", null]);
|
||||
expect(reconcileChartSlots(["a", null, null, null], ["a"], 2)).toEqual(["a", null]);
|
||||
expect(reconcileChartSlots(["a", null, null, null], [], 2)).toEqual([]);
|
||||
});
|
||||
|
||||
it("builds default slots in available order and never duplicates a chart", () => {
|
||||
expect(reconcileChartSlots([], ["a", "b", "a"], 2)).toEqual(["a", "b"]);
|
||||
expect(reconcileChartSlots(["a", "a", "b", null], ["a", "b", "c"], 2)).toEqual(["a", "c", "b", null]);
|
||||
});
|
||||
|
||||
it("swaps occupied slots without inserting or shifting adjacent charts", () => {
|
||||
const slots: ChartSlot[] = ["a", "b", "c", "d"];
|
||||
expect(swapChartSlots(slots, 0, 2)).toEqual(["c", "b", "a", "d"]);
|
||||
expect(slots).toEqual(["a", "b", "c", "d"]);
|
||||
});
|
||||
|
||||
it("swaps across rows and permits an empty destination", () => {
|
||||
expect(swapChartSlots(["a", "b", "c", "d", "e", null, null, null], 0, 5))
|
||||
.toEqual([null, "b", "c", "d", "e", "a", null, null]);
|
||||
});
|
||||
|
||||
it("keeps the original array for invalid or unchanged swaps", () => {
|
||||
const slots: ChartSlot[] = ["a", null, null];
|
||||
for (const [source, target] of [[-1, 1], [0, 3], [3, 0], [0.5, 1], [0, Number.NaN], [0, 0], [1, 2]]) {
|
||||
expect(swapChartSlots(slots, source, target)).toBe(slots);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user