diff options
| author | Paul Buetow <paul@buetow.org> | 2026-02-26 23:33:55 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-02-26 23:33:55 +0200 |
| commit | 4ca34f040203c8e31603bbb39fd38632b68067d8 (patch) | |
| tree | eed81b39e169eb6d0cd7d2eca6b338c7c0914ba4 /internal/tui/eventstream/model_test.go | |
| parent | e5cb5db2292ae84680935767d455a777125e0fe9 (diff) | |
tui: add paused stream CSV export and foreground editor open
Diffstat (limited to 'internal/tui/eventstream/model_test.go')
| -rw-r--r-- | internal/tui/eventstream/model_test.go | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/internal/tui/eventstream/model_test.go b/internal/tui/eventstream/model_test.go index d55da61..74bccb6 100644 --- a/internal/tui/eventstream/model_test.go +++ b/internal/tui/eventstream/model_test.go @@ -1,6 +1,8 @@ package eventstream import ( + "encoding/csv" + "os" "strings" "testing" ) @@ -583,3 +585,112 @@ func TestPausedEnterCanFilterByFDColumn(t *testing.T) { t.Fatalf("expected 3 rows with fd=3, got %d", len(m.filtered)) } } + +func TestPausedQuickExportWritesFilteredRows(t *testing.T) { + rb := NewRingBuffer() + rb.Push(StreamEvent{Seq: 1, Comm: "firefox", PID: 10, TID: 100, Syscall: "read", FileName: "/a"}) + rb.Push(StreamEvent{Seq: 2, Comm: "bash", PID: 11, TID: 200, Syscall: "write", FileName: "/b"}) + rb.Push(StreamEvent{Seq: 3, Comm: "firefox", PID: 12, TID: 300, Syscall: "open", FileName: "/c"}) + + m := NewModel(rb) + m.height = 20 + m.setExportDirForTest(t.TempDir()) + m.Refresh() + if !m.HandleKey("space") { + t.Fatalf("space should pause") + } + + m.selectedIdx = 0 + m.selectedCol = streamColComm + if !m.HandleKey("enter") { + t.Fatalf("enter should apply comm filter") + } + if len(m.filtered) != 2 { + t.Fatalf("expected 2 filtered rows before export, got %d", len(m.filtered)) + } + + if !m.HandleKey("x") { + t.Fatalf("x should quick-export while paused") + } + if m.lastExportPath == "" { + t.Fatalf("expected last export path to be set") + } + records := readCSVRecords(t, m.lastExportPath) + if len(records) != 3 { + t.Fatalf("expected header + 2 rows in export, got %d records", len(records)) + } + if records[1][4] != "firefox" || records[2][4] != "firefox" { + t.Fatalf("expected only firefox rows exported, got %q and %q", records[1][4], records[2][4]) + } +} + +func TestPausedExportAsModalSavesWithProvidedFilename(t *testing.T) { + rb := NewRingBuffer() + rb.Push(StreamEvent{Seq: 1, Comm: "proc", PID: 1, TID: 1, Syscall: "read"}) + m := NewModel(rb) + m.height = 20 + m.setExportDirForTest(t.TempDir()) + m.Refresh() + _ = m.HandleKey("space") + + if !m.HandleKey("X") { + t.Fatalf("X should open export modal while paused") + } + if !m.exportModal.Visible() { + t.Fatalf("expected export modal visible") + } + // Replace default value fully and submit. + m.exportModal = m.exportModal.Open("custom-name") + if !m.HandleKey("enter") { + t.Fatalf("enter should submit export modal") + } + if m.exportModal.Visible() { + t.Fatalf("expected export modal closed after submit") + } + if !strings.HasSuffix(m.lastExportPath, "custom-name.csv") { + t.Fatalf("expected custom-name.csv export path, got %q", m.lastExportPath) + } + if _, err := os.Stat(m.lastExportPath); err != nil { + t.Fatalf("expected exported file to exist: %v", err) + } +} + +func TestPausedOpenLastExportQueuesRequest(t *testing.T) { + rb := NewRingBuffer() + rb.Push(StreamEvent{Seq: 1, Comm: "proc", PID: 1, TID: 1, Syscall: "read"}) + m := NewModel(rb) + m.height = 20 + m.setExportDirForTest(t.TempDir()) + m.Refresh() + _ = m.HandleKey("space") + _ = m.HandleKey("x") + + if !m.HandleKey("E") { + t.Fatalf("E should queue opening last export while paused") + } + path, ok := m.ConsumeOpenEditorRequest() + if !ok { + t.Fatalf("expected queued open-editor request") + } + if path != m.lastExportPath { + t.Fatalf("expected opened path %q, got %q", m.lastExportPath, path) + } + if _, ok := m.ConsumeOpenEditorRequest(); ok { + t.Fatalf("expected request to be consumed once") + } +} + +func readCSVRecords(t *testing.T, path string) [][]string { + t.Helper() + f, err := os.Open(path) + if err != nil { + t.Fatalf("open csv: %v", err) + } + defer f.Close() + r := csv.NewReader(f) + records, err := r.ReadAll() + if err != nil { + t.Fatalf("read csv: %v", err) + } + return records +} |
