diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-06 14:44:34 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-06 14:44:34 +0200 |
| commit | 479f399aae8d3b28d9714214ea624d4a8cc0e886 (patch) | |
| tree | 0609eee6378d170b3e6a4601560f58e98bf09cc8 /internal/tui/flamegraph/model_test.go | |
| parent | 3e08a3d199fdf603b7c0a4002ca9822b6ecf2575 (diff) | |
flamegraph: keep non-matches visible in filter and add pgup/pgdn selection jumps
Diffstat (limited to 'internal/tui/flamegraph/model_test.go')
| -rw-r--r-- | internal/tui/flamegraph/model_test.go | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/internal/tui/flamegraph/model_test.go b/internal/tui/flamegraph/model_test.go index e253c76..093bf34 100644 --- a/internal/tui/flamegraph/model_test.go +++ b/internal/tui/flamegraph/model_test.go @@ -193,6 +193,37 @@ func TestHorizontalTraversalFallbackFromRoot(t *testing.T) { } } +func TestPageUpJumpsSelectionToTopMostDepth(t *testing.T) { + m := NewModel(nil) + m.frames = []tuiFrame{ + {Name: "root", Depth: 0, Col: 0, Path: "root"}, + {Name: "A", Depth: 1, Col: 0, Path: "root" + pathSeparator + "A"}, + {Name: "B", Depth: 1, Col: 40, Path: "root" + pathSeparator + "B"}, + {Name: "A1", Depth: 2, Col: 0, Path: "root" + pathSeparator + "A" + pathSeparator + "A1"}, + {Name: "B1", Depth: 2, Col: 40, Path: "root" + pathSeparator + "B" + pathSeparator + "B1"}, + {Name: "A2", Depth: 3, Col: 0, Path: "root" + pathSeparator + "A" + pathSeparator + "A1" + pathSeparator + "A2"}, + {Name: "B2", Depth: 3, Col: 40, Path: "root" + pathSeparator + "B" + pathSeparator + "B1" + pathSeparator + "B2"}, + } + m.selectedIdx = mustFrameIndex(t, m.frames, "root"+pathSeparator+"B"+pathSeparator+"B1") + + m = pressFlameKey(t, m, tea.KeyPressMsg{Code: tea.KeyPgUp}) + if got, want := m.frames[m.selectedIdx].Path, "root"+pathSeparator+"B"+pathSeparator+"B1"+pathSeparator+"B2"; got != want { + t.Fatalf("expected pgup to jump to deepest top frame %q, got %q", want, got) + } +} + +func TestPageDownJumpsSelectionToCurrentViewRoot(t *testing.T) { + m := newZoomModel() + m.selectedIdx = mustFrameIndex(t, m.frames, "root"+pathSeparator+"A") + m = pressFlameKey(t, m, tea.KeyPressMsg{Code: tea.KeyEnter}) + m.selectedIdx = mustFrameIndex(t, m.frames, "root"+pathSeparator+"A"+pathSeparator+"A1") + + m = pressFlameKey(t, m, tea.KeyPressMsg{Code: tea.KeyPgDown}) + if got, want := m.frames[m.selectedIdx].Path, "root"+pathSeparator+"A"; got != want { + t.Fatalf("expected pgdn to jump to current zoom root %q, got %q", want, got) + } +} + func TestPausedStateStillAllowsNavigation(t *testing.T) { m := NewModel(nil) m.frames = []tuiFrame{ @@ -635,6 +666,45 @@ func TestViewIncludesSelectionStatusBar(t *testing.T) { } } +func TestViewFilterSelectionStatusUsesFilteredTotalAndKeepsContextVisible(t *testing.T) { + snapshot := &snapshotNode{ + Name: "root", + Total: 100, + Children: []*snapshotNode{ + { + Name: "keep", + Total: 60, + Children: []*snapshotNode{ + {Name: "needle", Total: 60}, + }, + }, + { + Name: "drop", + Total: 40, + Children: []*snapshotNode{ + {Name: "noise", Total: 40}, + }, + }, + }, + } + m := NewModel(nil) + m.width = 220 + m.height = 12 + m.frames = BuildTerminalLayout(snapshot, m.width, m.height) + m.globalTotal = 100 + m.selectedIdx = mustFrameIndex(t, m.frames, "root"+pathSeparator+"keep"+pathSeparator+"needle") + m.searchQuery = "needle" + m.recomputeFilterState() + + view := m.View().Content + if !strings.Contains(view, "100.00% filter") { + t.Fatalf("expected filtered selection share in status line, got %q", view) + } + if !strings.Contains(view, "drop") || !strings.Contains(view, "noise") { + t.Fatalf("expected non-matching branches to remain visible while filtering, got %q", view) + } +} + func TestControlCycleFieldOrderReconfiguresLiveTrie(t *testing.T) { liveTrie := coreflamegraph.NewLiveTrie([]string{"comm", "path", "tracepoint"}, "count") m := NewModel(liveTrie) |
