import { describe, it, expect } from "vitest"; import { buildWaterfall, criticalPath, recordLabel } from "../waterfall"; import type { TelemetryRecord, TraceNode } from "../telemetry"; function rec(over: Partial & { kind: string }): TelemetryRecord { return over; } function node(record: TelemetryRecord, children: TraceNode[] = []): TraceNode { return { record, children }; } const t = (ms: number) => new Date(Date.UTC(2026, 0, 1, 0, 0, 0, ms)).toISOString(); describe("recordLabel", () => { it("prefers a name/handler field over the kind", () => { expect(recordLabel(rec({ kind: "action.completed", name: "orders.place" }))).toBe( "orders.place", ); expect(recordLabel(rec({ kind: "event.published", event: "orders.placed" }))).toBe( "orders.placed", ); }); it("falls back to the kind when no name is carried", () => { expect(recordLabel(rec({ kind: "timer.fired" }))).toBe("timer.fired"); }); }); describe("buildWaterfall", () => { it("flattens the forest in pre-order with depth", () => { const forest = [ node( rec({ kind: "action.dispatched", name: "a", envelope: { messageId: "m1", causationId: "m1", correlationId: "c" }, }), [ node( rec({ kind: "event.published", name: "b", envelope: { messageId: "m2", causationId: "m1", correlationId: "c" }, }), [ node( rec({ kind: "listener.fired", name: "c", envelope: { messageId: "m3", causationId: "m2", correlationId: "c" }, }), ), ], ), ], ), ]; const { rows } = buildWaterfall(forest); expect(rows.map((r) => r.label)).toEqual(["a", "b", "c"]); expect(rows.map((r) => r.depth)).toEqual([0, 1, 2]); }); it("positions bars against the trace span when records carry ts", () => { const forest = [ node( rec({ kind: "action.dispatched", ts: t(0), durationMs: 100, envelope: { messageId: "m1", causationId: "m1", correlationId: "c" }, }), [ node( rec({ kind: "query.executed", ts: t(50), durationMs: 50, envelope: { messageId: "m2", causationId: "m1", correlationId: "c" }, }), ), ], ), ]; const { rows, spanMs } = buildWaterfall(forest); expect(spanMs).toBe(100); expect(rows[0]!.offsetPct).toBe(0); expect(rows[0]!.widthPct).toBe(100); expect(rows[1]!.offsetPct).toBe(50); expect(rows[1]!.widthPct).toBe(50); }); it("clamps a zero-duration span to a visible minimum width", () => { const forest = [ node( rec({ kind: "event.emitted", ts: t(0), durationMs: 0, envelope: { messageId: "m1", causationId: "m1", correlationId: "c" }, }), ), ]; const { rows } = buildWaterfall(forest); expect(rows[0]!.widthPct).toBeGreaterThan(0); }); it("falls back to full-width bars when no record carries a ts", () => { const forest = [ node( rec({ kind: "action.completed", envelope: { messageId: "m1", causationId: "m1", correlationId: "c" }, }), ), ]; const { rows } = buildWaterfall(forest); expect(rows[0]!.offsetPct).toBe(0); expect(rows[0]!.widthPct).toBe(100); }); it("marks failures", () => { const forest = [ node( rec({ kind: "action.failed", error: { name: "E", message: "boom" }, envelope: { messageId: "m1", causationId: "m1", correlationId: "c" }, }), ), ]; const { rows } = buildWaterfall(forest); expect(rows[0]!.failed).toBe(true); }); }); describe("criticalPath", () => { it("selects the longest-duration root→leaf chain", () => { const slow = rec({ kind: "query.executed", name: "slow", durationMs: 90, envelope: { messageId: "m2", causationId: "m1", correlationId: "c" }, }); const fast = rec({ kind: "query.executed", name: "fast", durationMs: 5, envelope: { messageId: "m3", causationId: "m1", correlationId: "c" }, }); const root = rec({ kind: "action.dispatched", name: "root", durationMs: 10, envelope: { messageId: "m1", causationId: "m1", correlationId: "c" }, }); const forest = [node(root, [node(fast), node(slow)])]; const crit = criticalPath(forest); const { rows } = buildWaterfall(forest); const byLabel = Object.fromEntries(rows.map((r) => [r.label, r.critical])); expect(byLabel.root).toBe(true); expect(byLabel.slow).toBe(true); expect(byLabel.fast).toBe(false); expect(crit.size).toBe(2); }); });