summaryrefslogtreecommitdiff
path: root/internal/tui/dashboard
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-06 13:36:51 +0200
committerPaul Buetow <paul@buetow.org>2026-03-06 13:36:51 +0200
commitef12ce837176bd21deb455eb50a6c839af02b510 (patch)
treec262ceeda0b419236a4b0b1826df8eb5e418b852 /internal/tui/dashboard
parent10c5d48413afaef88626419d8c4bf9fbf6f1c902 (diff)
Add live flamegraph test modes and dynamic synthetic live feed
Diffstat (limited to 'internal/tui/dashboard')
-rw-r--r--internal/tui/dashboard/model.go4
-rw-r--r--internal/tui/dashboard/model_test.go37
2 files changed, 33 insertions, 8 deletions
diff --git a/internal/tui/dashboard/model.go b/internal/tui/dashboard/model.go
index 7ec1362..b1d23bb 100644
--- a/internal/tui/dashboard/model.go
+++ b/internal/tui/dashboard/model.go
@@ -134,8 +134,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, nil
}
var animCmd tea.Cmd
- if m.liveTrie != nil && !m.flamegraphModel.Paused() && (!m.flamegraphModel.HasSnapshot() || m.liveTrie.Version() != m.flamegraphModel.LastVersion()) {
- m.flamegraphModel.RefreshFromLiveTrie()
+ if m.liveTrie != nil && m.flamegraphModel.RefreshFromLiveTrie() {
animCmd = m.flamegraphModel.AnimationCmd()
}
if animCmd != nil {
@@ -368,6 +367,7 @@ func (m *Model) SetLiveTrie(liveTrie *coreflamegraph.LiveTrie) {
if m.width > 0 && m.height > 0 {
m.flamegraphModel.SetViewport(m.width, m.height)
}
+ m.flamegraphModel.RefreshFromLiveTrie()
}
// SetDarkMode updates dashboard child models for the active theme.
diff --git a/internal/tui/dashboard/model_test.go b/internal/tui/dashboard/model_test.go
index 1dc1cc1..8904a2f 100644
--- a/internal/tui/dashboard/model_test.go
+++ b/internal/tui/dashboard/model_test.go
@@ -198,20 +198,45 @@ func TestFlameTickRefreshesFlamegraphModel(t *testing.T) {
}
}
-func TestFlameTickLoadsInitialSnapshotWithoutVersionChange(t *testing.T) {
+func TestSetLiveTriePreloadsInitialSnapshotWithoutVersionChange(t *testing.T) {
liveTrie := coreflamegraph.NewLiveTrie([]string{"comm", "path"}, "count")
m := NewModelWithConfig(nil, nil, 250, common.DefaultKeyMap())
m.SetLiveTrie(liveTrie)
m.activeTab = TabFlame
- if m.flamegraphModel.HasSnapshot() {
- t.Fatalf("expected fresh flame model to start without snapshot")
+ if !m.flamegraphModel.HasSnapshot() {
+ t.Fatalf("expected SetLiveTrie to preload a baseline snapshot")
}
next, _ := m.Update(flameTickMsg{})
model := next.(Model)
if !model.flamegraphModel.HasSnapshot() {
- t.Fatalf("expected flame tick to load initial snapshot even when trie version is unchanged")
+ t.Fatalf("expected flame tick to retain initial snapshot even when trie version is unchanged")
+ }
+}
+
+func TestFlameTickPausedContinuesBootstrapRefresh(t *testing.T) {
+ liveTrie := coreflamegraph.NewLiveTrie([]string{"comm", "path"}, "count")
+ m := NewModelWithConfig(nil, nil, 250, common.DefaultKeyMap())
+ m.SetLiveTrie(liveTrie)
+ m.activeTab = TabFlame
+
+ next, _ := m.Update(tea.KeyPressMsg{Code: tea.KeySpace, Text: " "})
+ model := next.(Model)
+
+ next, _ = model.Update(flameTickMsg{})
+ model = next.(Model)
+ initialVersion := model.flamegraphModel.LastVersion()
+
+ liveTrie.Reset()
+ if liveTrie.Version() == initialVersion {
+ t.Fatalf("expected reset to advance trie version")
+ }
+
+ next, _ = model.Update(flameTickMsg{})
+ model = next.(Model)
+ if got, want := model.flamegraphModel.LastVersion(), liveTrie.Version(); got != want {
+ t.Fatalf("expected paused flame tick bootstrap to refresh version, got %d want %d", got, want)
}
}
@@ -359,10 +384,10 @@ func TestFlameTabReceivesResetAndPauseKeys(t *testing.T) {
m.width = 120
m.height = 30
- next, _ := m.Update(tea.KeyPressMsg{Code: []rune{'p'}[0], Text: string([]rune{'p'})})
+ next, _ := m.Update(tea.KeyPressMsg{Code: tea.KeySpace, Text: " "})
model := next.(Model)
if !strings.Contains(model.View().Content, "[PAUSED]") {
- t.Fatalf("expected flame pause key to toggle paused state")
+ t.Fatalf("expected flame space key to toggle paused state")
}
next, cmd := model.Update(tea.KeyPressMsg{Code: []rune{'r'}[0], Text: string([]rune{'r'})})