diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-05 22:18:08 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-05 22:18:08 +0200 |
| commit | 043bbbb884560a0f91f5e12d0b7851ad60121d5a (patch) | |
| tree | b3345068b594945c777991a03876e2826175c089 /internal | |
| parent | 98e46348ca59de2033451b844a4f592f1f9e5433 (diff) | |
task 350: add TabFlame tab infrastructure
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/tui/common/keys.go | 5 | ||||
| -rw-r--r-- | internal/tui/common/keys_test.go | 24 | ||||
| -rw-r--r-- | internal/tui/dashboard/model.go | 4 | ||||
| -rw-r--r-- | internal/tui/dashboard/model_test.go | 4 | ||||
| -rw-r--r-- | internal/tui/dashboard/tabs.go | 7 | ||||
| -rw-r--r-- | internal/tui/dashboard/tabs_test.go | 15 | ||||
| -rw-r--r-- | internal/tui/tui_test.go | 4 |
7 files changed, 50 insertions, 13 deletions
diff --git a/internal/tui/common/keys.go b/internal/tui/common/keys.go index 31fdf64..6b0ae27 100644 --- a/internal/tui/common/keys.go +++ b/internal/tui/common/keys.go @@ -44,7 +44,7 @@ func DefaultKeyMap() KeyMap { Four: key.NewBinding(key.WithKeys("4"), key.WithHelp("4", "processes")), Five: key.NewBinding(key.WithKeys("5"), key.WithHelp("5", "lat+gaps")), Six: key.NewBinding(key.WithKeys("6"), key.WithHelp("6", "stream")), - Seven: key.NewBinding(key.WithKeys("7"), key.WithHelp("7", "stream")), + Seven: key.NewBinding(key.WithKeys("7"), key.WithHelp("7", "flame")), DirGroup: key.NewBinding(key.WithKeys("d"), key.WithHelp("d", "dir group")), SelectPID: key.NewBinding(key.WithKeys("p"), key.WithHelp("p", "select pid")), SelectTID: key.NewBinding(key.WithKeys("t"), key.WithHelp("t", "select tid")), @@ -83,6 +83,7 @@ func (k KeyMap) DashboardStatusHelpSections() []HelpSection { k.Four, k.Five, k.Six, + k.Seven, k.SelectPID, k.SelectTID, k.Probes, @@ -126,7 +127,7 @@ func (k KeyMap) DashboardFullHelp() [][]key.Binding { controls = append(controls, k.DirGroup, k.SelectPID, k.SelectTID, k.Probes, k.Refresh, k.Quit) return [][]key.Binding{ - {k.One, k.Two, k.Three, k.Four, k.Five, k.Six}, + {k.One, k.Two, k.Three, k.Four, k.Five, k.Six, k.Seven}, controls, { helpTextBinding("space", "stream pause"), diff --git a/internal/tui/common/keys_test.go b/internal/tui/common/keys_test.go index 42e47ab..e043f9e 100644 --- a/internal/tui/common/keys_test.go +++ b/internal/tui/common/keys_test.go @@ -23,6 +23,11 @@ func TestDefaultKeyMapIncludesDirGroupBinding(t *testing.T) { if selectTIDHelp.Key != "t" || selectTIDHelp.Desc != "select tid" { t.Fatalf("unexpected select tid binding help: key=%q desc=%q", selectTIDHelp.Key, selectTIDHelp.Desc) } + + flameHelp := keys.Seven.Help() + if flameHelp.Key != "7" || flameHelp.Desc != "flame" { + t.Fatalf("unexpected flame binding help: key=%q desc=%q", flameHelp.Key, flameHelp.Desc) + } } func TestDashboardFullHelpIncludesDirGroupBinding(t *testing.T) { @@ -33,6 +38,7 @@ func TestDashboardFullHelpIncludesDirGroupBinding(t *testing.T) { } found := false + foundSeven := false for _, binding := range groups[1] { help := binding.Help() if help.Key == "d" && help.Desc == "dir group" { @@ -44,6 +50,17 @@ func TestDashboardFullHelpIncludesDirGroupBinding(t *testing.T) { t.Fatalf("expected dir group binding in dashboard full help controls") } + for _, binding := range groups[0] { + help := binding.Help() + if help.Key == "7" && help.Desc == "flame" { + foundSeven = true + break + } + } + if !foundSeven { + t.Fatalf("expected flame tab binding in dashboard full help tabs") + } + found = false for _, binding := range groups[1] { help := binding.Help() @@ -86,6 +103,7 @@ func TestDashboardStatusHelpIncludesProbesBinding(t *testing.T) { short := keys.DashboardStatusHelp() found := false foundSelectTID := false + foundSeven := false for _, binding := range short { help := binding.Help() if help.Key == "o" && help.Desc == "probes" { @@ -94,6 +112,9 @@ func TestDashboardStatusHelpIncludesProbesBinding(t *testing.T) { if help.Key == "t" && help.Desc == "select tid" { foundSelectTID = true } + if help.Key == "7" && help.Desc == "flame" { + foundSeven = true + } } if !found { t.Fatalf("expected probes binding in dashboard short help") @@ -101,4 +122,7 @@ func TestDashboardStatusHelpIncludesProbesBinding(t *testing.T) { if !foundSelectTID { t.Fatalf("expected select tid binding in dashboard short help") } + if !foundSeven { + t.Fatalf("expected flame tab binding in dashboard short help") + } } diff --git a/internal/tui/dashboard/model.go b/internal/tui/dashboard/model.go index f097da7..0a9915b 100644 --- a/internal/tui/dashboard/model.go +++ b/internal/tui/dashboard/model.go @@ -166,7 +166,7 @@ func (m Model) handleKey(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) { m.activeTab = TabStream handled = true case key.Matches(msg, m.keys.Seven): - m.activeTab = TabStream + m.activeTab = TabFlame handled = true case key.Matches(msg, m.keys.Refresh): snap := m.snapshot() @@ -378,6 +378,8 @@ func renderActiveTab(tab Tab, snap *statsengine.Snapshot, streamModel *eventstre return renderProcessesWithOffset(snap, width, height, processesOffset, pidFilter) case TabLatency: return renderLatencyGapsTab(snap, width, height) + case TabFlame: + return common.PanelStyle.Render("Flame: waiting for model...") default: return common.PanelStyle.Render("Unknown tab") } diff --git a/internal/tui/dashboard/model_test.go b/internal/tui/dashboard/model_test.go index 642c702..c9a1cb9 100644 --- a/internal/tui/dashboard/model_test.go +++ b/internal/tui/dashboard/model_test.go @@ -48,8 +48,8 @@ func TestKeySwitchingChangesActiveTab(t *testing.T) { next, _ = model.Update(tea.KeyPressMsg{Code: []rune{'7'}[0], Text: string([]rune{'7'})}) model = next.(Model) - if model.activeTab != TabStream { - t.Fatalf("expected stream tab on key 7, got %v", model.activeTab) + if model.activeTab != TabFlame { + t.Fatalf("expected flame tab on key 7, got %v", model.activeTab) } next, _ = model.Update(tea.KeyPressMsg{Code: []rune{'6'}[0], Text: string([]rune{'6'})}) diff --git a/internal/tui/dashboard/tabs.go b/internal/tui/dashboard/tabs.go index 62c7762..731e21f 100644 --- a/internal/tui/dashboard/tabs.go +++ b/internal/tui/dashboard/tabs.go @@ -25,6 +25,8 @@ const ( TabLatency // TabStream is the live event stream tab. TabStream + // TabFlame is the live flamegraph tab. + TabFlame ) var allTabs = []Tab{ @@ -34,6 +36,7 @@ var allTabs = []Tab{ TabProcesses, TabLatency, TabStream, + TabFlame, } func (t Tab) String() string { @@ -50,6 +53,8 @@ func (t Tab) String() string { return "Latency+Gaps" case TabStream: return "Stream" + case TabFlame: + return "Flame" default: return "Unknown" } @@ -192,6 +197,8 @@ func tabLabel(tab Tab, short bool) string { return "Lat" case TabStream: return "Str" + case TabFlame: + return "Flm" default: return "Unk" } diff --git a/internal/tui/dashboard/tabs_test.go b/internal/tui/dashboard/tabs_test.go index 1148103..16f8b76 100644 --- a/internal/tui/dashboard/tabs_test.go +++ b/internal/tui/dashboard/tabs_test.go @@ -11,17 +11,20 @@ func TestTabNavigationWraps(t *testing.T) { if got := nextTab(TabLatency); got != TabStream { t.Fatalf("expected next after latency+gaps to be stream, got %v", got) } - if got := nextTab(TabStream); got != TabOverview { - t.Fatalf("expected wrap to overview from stream, got %v", got) + if got := nextTab(TabStream); got != TabFlame { + t.Fatalf("expected next after stream to be flame, got %v", got) } - if got := prevTab(TabOverview); got != TabStream { - t.Fatalf("expected wrap to stream, got %v", got) + if got := nextTab(TabFlame); got != TabOverview { + t.Fatalf("expected wrap to overview from flame, got %v", got) + } + if got := prevTab(TabOverview); got != TabFlame { + t.Fatalf("expected wrap to flame, got %v", got) } } func TestRenderTabBarContainsLabels(t *testing.T) { out := renderTabBar(TabOverview, 100) - for _, label := range []string{"Overview", "Syscalls", "Files", "Processes", "Latency+Gaps", "Stream"} { + for _, label := range []string{"Overview", "Syscalls", "Files", "Processes", "Latency+Gaps", "Stream", "Flame"} { if !strings.Contains(out, label) { t.Fatalf("expected tab label %q in tab bar", label) } @@ -34,7 +37,7 @@ func TestRenderTabBarSmallWidthUsesSingleLine(t *testing.T) { if len(lines) != 1 { t.Fatalf("expected single-line tab bar at width 70, got %d lines", len(lines)) } - if strings.Contains(out, "6:Strea") { + if strings.Contains(out, "7:Flam") { t.Fatalf("tab label should not be wrapped/split in small width output") } } diff --git a/internal/tui/tui_test.go b/internal/tui/tui_test.go index 68bfca0..610461d 100644 --- a/internal/tui/tui_test.go +++ b/internal/tui/tui_test.go @@ -255,7 +255,7 @@ func TestTracingStartedRebindsEventStreamSource(t *testing.T) { next, _ = m.Update(tea.WindowSizeMsg{Width: 120, Height: 30}) m = next.(Model) - next, _ = m.Update(tea.KeyPressMsg{Code: []rune{'7'}[0], Text: string([]rune{'7'})}) + next, _ = m.Update(tea.KeyPressMsg{Code: []rune{'6'}[0], Text: string([]rune{'6'})}) m = next.(Model) next, _ = m.Update(messages.StatsTickMsg{}) m = next.(Model) @@ -429,7 +429,7 @@ func TestStreamFilterModalConsumesEKeyInsteadOfOpeningExport(t *testing.T) { m.width = 120 m.height = 30 - next, _ := m.Update(tea.KeyPressMsg{Code: []rune{'7'}[0], Text: string([]rune{'7'})}) + next, _ := m.Update(tea.KeyPressMsg{Code: []rune{'6'}[0], Text: string([]rune{'6'})}) m = next.(Model) next, _ = m.Update(tea.KeyPressMsg{Code: []rune{'f'}[0], Text: string([]rune{'f'})}) m = next.(Model) |
