summaryrefslogtreecommitdiff
path: root/internal/tui/tui_test.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-08 22:03:01 +0200
committerPaul Buetow <paul@buetow.org>2026-03-08 22:03:01 +0200
commit0d1492291a3e20665d8a3a6b16d2eb4e13938cee (patch)
treeec09f7d660403478d23841cf541bdfa7f33aa70f /internal/tui/tui_test.go
parentd84902555621cc10b16a9641274b088e495f3714 (diff)
tui: restore global filter stack and anchored matches
Diffstat (limited to 'internal/tui/tui_test.go')
-rw-r--r--internal/tui/tui_test.go179
1 files changed, 179 insertions, 0 deletions
diff --git a/internal/tui/tui_test.go b/internal/tui/tui_test.go
index 513de4c..ab8b5db 100644
--- a/internal/tui/tui_test.go
+++ b/internal/tui/tui_test.go
@@ -1184,6 +1184,185 @@ func TestGlobalFilterCloseWithoutChangesDoesNotRestartTrace(t *testing.T) {
}
}
+func TestPausedStreamEnterAppliesSelectedCellAsGlobalFilter(t *testing.T) {
+ m := NewModel(-1, func(context.Context) error { return nil })
+ m.screen = ScreenDashboard
+ m.attaching = false
+ m.width = 120
+ m.height = 30
+
+ stopped := false
+ m.traceStop = func() { stopped = true }
+
+ rb := eventstream.NewRingBuffer()
+ rb.Push(eventstream.StreamEvent{
+ Seq: 1,
+ Syscall: "write",
+ Comm: "systemd",
+ PID: 3655,
+ TID: 4862,
+ FileName: "/var/lib/clickhouse/data",
+ DurationNs: 1234,
+ GapNs: 44,
+ FD: 20,
+ })
+ m.dashboard.SetStreamSource(rb)
+
+ 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'})})
+ m = next.(Model)
+ next, _ = m.Update(tea.KeyPressMsg{Code: tea.KeySpace, Text: " "})
+ m = next.(Model)
+ next, _ = m.Update(tea.KeyPressMsg{Code: tea.KeyRight})
+ m = next.(Model)
+ next, _ = m.Update(tea.KeyPressMsg{Code: tea.KeyRight})
+ m = next.(Model)
+
+ next, cmd := m.Update(tea.KeyPressMsg{Code: tea.KeyEnter})
+ m = next.(Model)
+ if cmd == nil {
+ t.Fatalf("expected enter on paused stream selection to emit a global filter request")
+ }
+
+ next, cmd = m.Update(cmd())
+ m = next.(Model)
+ if cmd == nil {
+ t.Fatalf("expected applying selected-cell global filter to restart tracing")
+ }
+ if m.globalFilter.Comm == nil || m.globalFilter.Comm.Pattern != "systemd" {
+ t.Fatalf("expected selected comm applied globally, got %+v", m.globalFilter.Comm)
+ }
+ if !stopped {
+ t.Fatalf("expected selected-cell global filter to stop the active trace")
+ }
+ if !m.attaching {
+ t.Fatalf("expected selected-cell global filter to restart tracing")
+ }
+ if len(m.filterStack) != 1 || m.filterStack[0] != "comm~systemd" {
+ t.Fatalf("expected selected-cell action pushed to filter stack, got %+v", m.filterStack)
+ }
+}
+
+func TestGlobalFilterUndoKeyPopsLatestStackEntry(t *testing.T) {
+ m := NewModel(-1, func(context.Context) error { return nil })
+ m.screen = ScreenDashboard
+ m.attaching = false
+
+ next, _ := m.Update(tea.KeyPressMsg{Code: []rune{'f'}[0], Text: string([]rune{'f'})})
+ m = next.(Model)
+ next, _ = m.Update(tea.KeyPressMsg{Code: tea.KeyEnter})
+ m = next.(Model)
+ next, _ = m.Update(tea.KeyPressMsg{Code: []rune("read")[0], Text: string([]rune("read"))})
+ m = next.(Model)
+ next, _ = m.Update(tea.KeyPressMsg{Code: tea.KeyEsc})
+ m = next.(Model)
+
+ m.attaching = false
+ stopped := false
+ m.traceStop = func() { stopped = true }
+
+ next, cmd := m.Update(tea.KeyPressMsg{Code: []rune{'F'}[0], Text: string([]rune{'F'})})
+ m = next.(Model)
+ if cmd == nil {
+ t.Fatalf("expected F to trigger global filter undo")
+ }
+ if m.globalFilter.IsActive() {
+ t.Fatalf("expected undo to restore the previous all-filter state, got %+v", m.globalFilter)
+ }
+ if len(m.filterStack) != 0 || len(m.filterHistory) != 0 {
+ t.Fatalf("expected filter stack/history cleared after undo, got stack=%+v history=%d", m.filterStack, len(m.filterHistory))
+ }
+ if !stopped {
+ t.Fatalf("expected undo to stop the active trace")
+ }
+ if !m.attaching {
+ t.Fatalf("expected undo to restart tracing")
+ }
+}
+
+func TestPausedStreamEscUndoesLatestGlobalFilter(t *testing.T) {
+ m := NewModel(-1, func(context.Context) error { return nil })
+ m.screen = ScreenDashboard
+ m.attaching = false
+ m.width = 120
+ m.height = 30
+
+ next, _ := m.Update(tea.KeyPressMsg{Code: []rune{'f'}[0], Text: string([]rune{'f'})})
+ m = next.(Model)
+ next, _ = m.Update(tea.KeyPressMsg{Code: tea.KeyEnter})
+ m = next.(Model)
+ next, _ = m.Update(tea.KeyPressMsg{Code: []rune("read")[0], Text: string([]rune("read"))})
+ m = next.(Model)
+ next, _ = m.Update(tea.KeyPressMsg{Code: tea.KeyEsc})
+ m = next.(Model)
+
+ rb := eventstream.NewRingBuffer()
+ rb.Push(eventstream.StreamEvent{Seq: 1, Syscall: "read", Comm: "systemd", PID: 1, TID: 2})
+ m.dashboard.SetStreamSource(rb)
+ m.attaching = false
+ stopped := false
+ m.traceStop = func() { stopped = true }
+
+ 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'})})
+ m = next.(Model)
+ next, _ = m.Update(tea.KeyPressMsg{Code: tea.KeySpace, Text: " "})
+ m = next.(Model)
+
+ next, cmd := m.Update(tea.KeyPressMsg{Code: tea.KeyEsc})
+ m = next.(Model)
+ if cmd == nil {
+ t.Fatalf("expected esc in paused stream to undo one global filter layer")
+ }
+ next, cmd = m.Update(cmd())
+ m = next.(Model)
+ if cmd == nil {
+ t.Fatalf("expected esc undo to restart tracing")
+ }
+ if m.globalFilter.IsActive() {
+ t.Fatalf("expected esc undo to restore all-filter state, got %+v", m.globalFilter)
+ }
+ if len(m.filterStack) != 0 {
+ t.Fatalf("expected filter stack cleared after esc undo, got %+v", m.filterStack)
+ }
+ if !stopped {
+ t.Fatalf("expected esc undo to stop the active trace")
+ }
+ if !m.attaching {
+ t.Fatalf("expected esc undo to restart tracing")
+ }
+}
+
+func TestDashboardFooterShowsGlobalFilterStack(t *testing.T) {
+ m := NewModel(-1, func(context.Context) error { return nil })
+ m.screen = ScreenDashboard
+ m.attaching = false
+ m.width = 140
+ m.height = 35
+
+ next, _ := m.Update(tea.KeyPressMsg{Code: []rune{'f'}[0], Text: string([]rune{'f'})})
+ m = next.(Model)
+ next, _ = m.Update(tea.KeyPressMsg{Code: tea.KeyEnter})
+ m = next.(Model)
+ next, _ = m.Update(tea.KeyPressMsg{Code: []rune("read")[0], Text: string([]rune("read"))})
+ m = next.(Model)
+ next, _ = m.Update(tea.KeyPressMsg{Code: tea.KeyEsc})
+ m = next.(Model)
+
+ m.attaching = false
+ next, _ = m.Update(tea.KeyPressMsg{Code: []rune{'4'}[0], Text: string([]rune{'4'})})
+ m = next.(Model)
+
+ view := m.View().Content
+ for _, want := range []string{"filter: syscall~read", "stack: syscall~read"} {
+ if !strings.Contains(view, want) {
+ t.Fatalf("expected dashboard footer to show %q\n%s", want, view)
+ }
+ }
+}
+
func TestGlobalFilterApplyPreservesActiveDashboardTab(t *testing.T) {
m := NewModel(-1, func(context.Context) error { return nil })
m.screen = ScreenDashboard