Files
nxdns/admin/src/features/overview/donutLayout.test.ts
T
mokhtar 648d9b4496
Gates / frontend (push) Successful in 1m32s
Gates / test (push) Successful in 1m54s
Gates / package (push) Successful in 5m28s
Gates / container (push) Successful in 14s
Gates / test-aarch64 (push) Failing after 3h10m0s
CI / gates (push) Failing after 3h11m55s
milestone 30: overview as a dashboard, explicit health contract, period aggregations
2026-08-22 16:45:15 +02:00

48 lines
2.0 KiB
TypeScript

import { layoutDonut, type DonutSlice } from "./donutLayout";
function slice(key: string, value: number): DonutSlice {
return { key, label: key, value, color: "#000000" };
}
test("an empty breakdown has no total and no arcs to draw", () => {
expect(layoutDonut([], 100, 20)).toEqual({ size: 100, total: 0, arcs: [] });
});
test("a breakdown of nothing but zeroes is empty, not a division by zero", () => {
const layout = layoutDonut([slice("a", 0), slice("b", 0)], 100, 20);
expect(layout.total).toBe(0);
expect(layout.arcs).toEqual([]);
});
test("zero-valued entries are dropped rather than legended at 0%", () => {
const layout = layoutDonut([slice("a", 3), slice("b", 0), slice("c", 1)], 100, 20);
expect(layout.arcs.map((arc) => arc.slice.key)).toEqual(["a", "c"]);
expect(layout.total).toBe(4);
});
test("shares are of the drawn total and add up to one", () => {
const layout = layoutDonut([slice("a", 3), slice("b", 1)], 100, 20);
expect(layout.arcs.map((arc) => arc.share)).toEqual([0.75, 0.25]);
});
test("slices keep the order they were ranked in, starting at twelve o'clock", () => {
const layout = layoutDonut([slice("a", 1), slice("b", 1)], 100, 20);
expect(layout.arcs[0].d.startsWith("M 50.000 0.000")).toBe(true);
// The second slice begins where the first ended, half a turn round.
expect(layout.arcs[1].d.startsWith("M 50.000 100.000")).toBe(true);
});
test("a slice over half the ring takes the large-arc flag", () => {
const layout = layoutDonut([slice("a", 9), slice("b", 1)], 100, 20);
expect(layout.arcs[0].d).toContain("A 50 50 0 1 1");
expect(layout.arcs[1].d).toContain("A 50 50 0 0 1");
});
test("a single entry is a closed ring, not a zero-length arc that draws nothing", () => {
const layout = layoutDonut([slice("only", 7)], 100, 20);
expect(layout.arcs).toHaveLength(1);
expect(layout.arcs[0].share).toBe(1);
// Two half arcs out and two back: a lone `A` from a point to itself is a no-op.
expect(layout.arcs[0].d.match(/A /g)).toHaveLength(4);
});