diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-26 22:45:23 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-26 22:45:23 +0300 |
| commit | fb5a9c1f5c99559cb013a6ff396eb56a7d1f7be6 (patch) | |
| tree | d1f7bc3667ea20799893148b40bc936303d60f67 /internal/tui/flamegraph/renderer_test.go | |
| parent | 5533d521ae2183342771ace001624c89e75a994f (diff) | |
flamegraph: variable leaf bar heights for height metric (uo)
Diffstat (limited to 'internal/tui/flamegraph/renderer_test.go')
| -rw-r--r-- | internal/tui/flamegraph/renderer_test.go | 70 |
1 files changed, 64 insertions, 6 deletions
diff --git a/internal/tui/flamegraph/renderer_test.go b/internal/tui/flamegraph/renderer_test.go index 354b40a..f34d23d 100644 --- a/internal/tui/flamegraph/renderer_test.go +++ b/internal/tui/flamegraph/renderer_test.go @@ -152,7 +152,7 @@ func TestTerminalFrameColorSemanticPalette(t *testing.T) { } func TestRenderTerminalViewShowsNarrowMessage(t *testing.T) { - out := RenderTerminalView(nil, 50, 10, 0, nil, nil, nil, 0, "events", true, false, "") + out := RenderTerminalView(nil, 50, 10, 0, nil, nil, nil, 0, "events", false, true, false, "") if !strings.Contains(out, "terminal too narrow") { t.Fatalf("expected narrow terminal warning, got %q", out) } @@ -177,7 +177,7 @@ func TestRenderTerminalViewIncludesToolbarAndStatus(t *testing.T) { } frames := BuildTerminalLayout(snapshot, 80, 6) - out := RenderTerminalView(frames, 80, 6, 1, nil, nil, nil, 0, "events", true, false, "") + out := RenderTerminalView(frames, 80, 6, 1, nil, nil, nil, 0, "events", false, true, false, "") if !strings.Contains(out, "Flame | view:root | frames:2") { t.Fatalf("expected toolbar to include frame count, got %q", out) } @@ -196,7 +196,7 @@ func TestRenderTerminalViewFillsAvailableHeightForShallowTree(t *testing.T) { } frames := BuildTerminalLayout(snapshot, 100, 20) - out := RenderTerminalView(frames, 100, 20, 1, nil, nil, nil, 0, "events", true, false, "") + out := RenderTerminalView(frames, 100, 20, 1, nil, nil, nil, 0, "events", false, true, false, "") lines := strings.Split(out, "\n") if got, want := len(lines), 20; got != want { t.Fatalf("expected render to fill viewport height (%d lines), got %d", want, got) @@ -245,7 +245,7 @@ func TestRenderTerminalViewShowsPersistentFilterContext(t *testing.T) { frames := BuildTerminalLayout(snapshot, 80, 6) matchSet := map[int]bool{1: true} - out := RenderTerminalView(frames, 140, 6, 1, nil, matchSet, nil, 0, "events", true, false, "child") + out := RenderTerminalView(frames, 140, 6, 1, nil, matchSet, nil, 0, "events", false, true, false, "child") if !strings.Contains(out, `Filter "child"`) { t.Fatalf("expected filter context in status line, got %q", out) } @@ -279,7 +279,7 @@ func TestRenderTerminalViewFilterKeepsNonMatchingBranchesVisible(t *testing.T) { } matchSet := map[int]bool{needleIdx: true} - out := RenderTerminalView(frames, 180, 8, needleIdx, nil, matchSet, nil, 100, "bytes", true, false, "needle") + out := RenderTerminalView(frames, 180, 8, needleIdx, nil, matchSet, nil, 100, "bytes", false, true, false, "needle") if !strings.Contains(out, `Filter "needle": 60.0% bytes`) { t.Fatalf("expected filter status to report 60.0%% bytes share, got %q", out) } @@ -368,7 +368,7 @@ func TestRenderTerminalViewShowsDeepLevelTruncationHint(t *testing.T) { }, } frames := BuildTerminalLayout(snapshot, 80, 10) - out := RenderTerminalView(frames, 80, 4, 0, nil, nil, nil, 0, "events", true, false, "") + out := RenderTerminalView(frames, 80, 4, 0, nil, nil, nil, 0, "events", false, true, false, "") if !strings.Contains(out, "showing deepest levels") { t.Fatalf("expected truncation hint in toolbar, got %q", out) } @@ -391,6 +391,64 @@ func TestComputeSubtreeSetIncludesAncestorsAndDescendants(t *testing.T) { } } +func TestComputeRenderParamsHeightMetricExpandsLeafBand(t *testing.T) { + frames := []tuiFrame{ + {Name: "root", Row: 0, Col: 0, Width: 20, Path: "root"}, + {Name: "leaf", Row: 1, Col: 0, Width: 20, Path: "root" + pathSeparator + "leaf", HeightTotal: 100}, + } + + params := computeRenderParams(frames, 8, true) // availableRows=6 + if got, want := params.barHeight, 1; got != want { + t.Fatalf("height metric active: barHeight=%d want=%d", got, want) + } + if got, want := params.leafBarHeight, 5; got != want { + t.Fatalf("height metric active: leafBarHeight=%d want=%d", got, want) + } +} + +func TestLeafFrameHeightsScaledByHeightTotal(t *testing.T) { + frames := []indexedFrame{ + {idx: 10, frame: tuiFrame{Name: "A", HeightTotal: 100}}, + {idx: 11, frame: tuiFrame{Name: "B", HeightTotal: 50}}, + {idx: 12, frame: tuiFrame{Name: "C", HeightTotal: 0}}, + } + + heights := leafFrameHeights(frames, 5) + if got, want := heights[10], 5; got != want { + t.Fatalf("A height=%d want=%d", got, want) + } + if got, want := heights[11], 3; got != want { + t.Fatalf("B height=%d want=%d", got, want) + } + if got, want := heights[12], 1; got != want { + t.Fatalf("C height=%d want=%d", got, want) + } +} + +func TestRenderLeafRowBandFiltersFramesByBand(t *testing.T) { + frames := []indexedFrame{ + {idx: 0, frame: tuiFrame{Name: "A", Col: 0, Width: 5, Path: "root" + pathSeparator + "A", Fill: color.RGBA{R: 150, G: 80, B: 80, A: 255}}}, + {idx: 1, frame: tuiFrame{Name: "B", Col: 5, Width: 5, Path: "root" + pathSeparator + "B", Fill: color.RGBA{R: 80, G: 120, B: 180, A: 255}}}, + } + heights := map[int]int{ + 0: 5, + 1: 2, + } + + topBand := renderLeafRowBand(frames, heights, 3, 10, "root"+pathSeparator+"A", nil, nil, 0, true, false, false, true) + if !strings.Contains(topBand, "A") { + t.Fatalf("expected top band to render taller frame A, got %q", topBand) + } + if strings.Contains(topBand, "B") { + t.Fatalf("expected top band to hide shorter frame B, got %q", topBand) + } + + lowerBand := renderLeafRowBand(frames, heights, 1, 10, "root"+pathSeparator+"A", nil, nil, 0, true, false, false, true) + if !strings.Contains(lowerBand, "A") || !strings.Contains(lowerBand, "B") { + t.Fatalf("expected lower band to render both frames, got %q", lowerBand) + } +} + func mustFindFrame(t *testing.T, frames []tuiFrame, path string) tuiFrame { t.Helper() for _, frame := range frames { |
