diff options
Diffstat (limited to 'internal/tmuxedit/history_test.go')
| -rw-r--r-- | internal/tmuxedit/history_test.go | 326 |
1 files changed, 0 insertions, 326 deletions
diff --git a/internal/tmuxedit/history_test.go b/internal/tmuxedit/history_test.go deleted file mode 100644 index f6d6d7d..0000000 --- a/internal/tmuxedit/history_test.go +++ /dev/null @@ -1,326 +0,0 @@ -package tmuxedit - -import ( - "fmt" - "os" - "path/filepath" - "testing" - "time" - - "codeberg.org/snonux/hexai/internal/textutil" -) - -func TestAppendHistory(t *testing.T) { - // Create temp directory for test - tmpDir := t.TempDir() - t.Setenv("XDG_STATE_HOME", tmpDir) - - text := "test prompt text" - agent := "claude" - cwd := "/tmp/test" - - // Append first entry - if err := AppendHistory(text, agent, cwd); err != nil { - t.Fatalf("AppendHistory failed: %v", err) - } - - // Verify file was created - historyPath := filepath.Join(tmpDir, "state", "tmux-edit-history.jsonl") - if _, err := os.Stat(historyPath); err != nil { - t.Fatalf("history file not created: %v", err) - } - - // Read and verify content - data, err := os.ReadFile(historyPath) - if err != nil { - t.Fatalf("cannot read history file: %v", err) - } - - content := string(data) - if content == "" { - t.Fatal("history file is empty") - } - - // Verify it contains expected fields - if !containsString(content, "test prompt text") { - t.Error("history doesn't contain text") - } - if !containsString(content, "claude") { - t.Error("history doesn't contain agent") - } - if !containsString(content, "/tmp/test") { - t.Error("history doesn't contain cwd") - } -} - -func TestGetHistory(t *testing.T) { - tmpDir := t.TempDir() - t.Setenv("XDG_STATE_HOME", tmpDir) - - // Append multiple entries - entries := []struct { - text string - agent string - cwd string - }{ - {"first prompt", "claude", "/home/user"}, - {"second prompt", "aider", "/tmp/project"}, - {"third prompt", "claude", "/var/tmp"}, - } - - for _, e := range entries { - if err := AppendHistory(e.text, e.agent, e.cwd); err != nil { - t.Fatalf("AppendHistory failed: %v", err) - } - time.Sleep(10 * time.Millisecond) // Ensure different timestamps - } - - // Get all history - history, err := GetHistory(0) - if err != nil { - t.Fatalf("GetHistory failed: %v", err) - } - - if len(history) != 3 { - t.Fatalf("expected 3 entries, got %d", len(history)) - } - - // Verify first entry - if history[0].Text != "first prompt" { - t.Errorf("first entry text: got %q, want %q", history[0].Text, "first prompt") - } - if history[0].Agent != "claude" { - t.Errorf("first entry agent: got %q, want %q", history[0].Agent, "claude") - } - - // Test limit - limited, err := GetHistory(2) - if err != nil { - t.Fatalf("GetHistory with limit failed: %v", err) - } - if len(limited) != 2 { - t.Fatalf("expected 2 entries with limit, got %d", len(limited)) - } - - // Should get the most recent 2 - if limited[0].Text != "second prompt" { - t.Errorf("limited[0] should be second entry") - } - if limited[1].Text != "third prompt" { - t.Errorf("limited[1] should be third entry") - } -} - -func TestGetHistory_EmptyFile(t *testing.T) { - tmpDir := t.TempDir() - t.Setenv("XDG_STATE_HOME", tmpDir) - - // Get history when file doesn't exist - history, err := GetHistory(0) - if err != nil { - t.Fatalf("GetHistory should not error on missing file: %v", err) - } - - if len(history) != 0 { - t.Errorf("expected empty history, got %d entries", len(history)) - } -} - -func TestSplitLines(t *testing.T) { - tests := []struct { - name string - input string - want []string - }{ - { - name: "unix newlines", - input: "line1\nline2\nline3", - want: []string{"line1", "line2", "line3"}, - }, - { - name: "windows newlines", - input: "line1\r\nline2\r\nline3", - want: []string{"line1", "line2", "line3"}, - }, - { - name: "mixed newlines", - input: "line1\nline2\r\nline3", - want: []string{"line1", "line2", "line3"}, - }, - { - name: "trailing newline", - input: "line1\nline2\n", - want: []string{"line1", "line2"}, - }, - { - name: "empty string", - input: "", - want: []string{}, - }, - { - name: "single line no newline", - input: "single", - want: []string{"single"}, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := textutil.SplitLinesBytes([]byte(tt.input)) - gotStr := make([]string, len(got)) - for i, b := range got { - gotStr[i] = string(b) - } - - if len(gotStr) != len(tt.want) { - t.Fatalf("got %d lines, want %d", len(gotStr), len(tt.want)) - } - - for i := range gotStr { - if gotStr[i] != tt.want[i] { - t.Errorf("line %d: got %q, want %q", i, gotStr[i], tt.want[i]) - } - } - }) - } -} - -func TestGetHistory_MalformedEntries(t *testing.T) { - tmpDir := t.TempDir() - t.Setenv("XDG_STATE_HOME", tmpDir) - - // Create state directory and write a file with some valid and invalid lines - stateDir := filepath.Join(tmpDir, "state") - if err := os.MkdirAll(stateDir, 0o755); err != nil { - t.Fatalf("cannot create state dir: %v", err) - } - historyPath := filepath.Join(stateDir, "tmux-edit-history.jsonl") - content := `{"timestamp":"2025-01-01T00:00:00Z","agent":"claude","cwd":"/tmp","text":"valid"} -not json at all -{"timestamp":"2025-01-02T00:00:00Z","agent":"aider","cwd":"/home","text":"also valid"} -` - if err := os.WriteFile(historyPath, []byte(content), 0o644); err != nil { - t.Fatalf("cannot write history file: %v", err) - } - - entries, err := GetHistory(0) - if err != nil { - t.Fatalf("GetHistory failed: %v", err) - } - // Should skip the malformed line and return the 2 valid entries - if len(entries) != 2 { - t.Fatalf("expected 2 entries, got %d", len(entries)) - } - if entries[0].Text != "valid" { - t.Errorf("entries[0].Text = %q, want 'valid'", entries[0].Text) - } - if entries[1].Text != "also valid" { - t.Errorf("entries[1].Text = %q, want 'also valid'", entries[1].Text) - } -} - -func TestGetHistory_EmptyLines(t *testing.T) { - tmpDir := t.TempDir() - t.Setenv("XDG_STATE_HOME", tmpDir) - - stateDir := filepath.Join(tmpDir, "state") - if err := os.MkdirAll(stateDir, 0o755); err != nil { - t.Fatalf("cannot create state dir: %v", err) - } - historyPath := filepath.Join(stateDir, "tmux-edit-history.jsonl") - // File with empty lines interspersed - content := "\n" + - `{"timestamp":"2025-01-01T00:00:00Z","agent":"claude","cwd":"/tmp","text":"entry1"}` + "\n" + - "\n\n" + - `{"timestamp":"2025-01-02T00:00:00Z","agent":"aider","cwd":"/home","text":"entry2"}` + "\n" - if err := os.WriteFile(historyPath, []byte(content), 0o644); err != nil { - t.Fatalf("cannot write history file: %v", err) - } - - entries, err := GetHistory(0) - if err != nil { - t.Fatalf("GetHistory failed: %v", err) - } - if len(entries) != 2 { - t.Fatalf("expected 2 entries (skipping empty lines), got %d", len(entries)) - } -} - -func TestGetHistory_LimitZeroReturnsAll(t *testing.T) { - tmpDir := t.TempDir() - t.Setenv("XDG_STATE_HOME", tmpDir) - - for i := 0; i < 5; i++ { - if err := AppendHistory(fmt.Sprintf("entry%d", i), "claude", "/tmp"); err != nil { - t.Fatalf("AppendHistory failed: %v", err) - } - } - - entries, err := GetHistory(0) - if err != nil { - t.Fatalf("GetHistory failed: %v", err) - } - if len(entries) != 5 { - t.Errorf("expected 5 entries with limit=0, got %d", len(entries)) - } -} - -func TestGetHistory_LimitLargerThanEntries(t *testing.T) { - tmpDir := t.TempDir() - t.Setenv("XDG_STATE_HOME", tmpDir) - - if err := AppendHistory("only one", "claude", "/tmp"); err != nil { - t.Fatalf("AppendHistory failed: %v", err) - } - - entries, err := GetHistory(100) - if err != nil { - t.Fatalf("GetHistory failed: %v", err) - } - if len(entries) != 1 { - t.Errorf("expected 1 entry with large limit, got %d", len(entries)) - } -} - -func TestAppendHistory_InvalidStateDir(t *testing.T) { - // Point XDG_STATE_HOME to a path that can't be created (file, not dir) - tmpDir := t.TempDir() - blockingFile := filepath.Join(tmpDir, "blocker") - if err := os.WriteFile(blockingFile, []byte("x"), 0o644); err != nil { - t.Fatalf("cannot create blocking file: %v", err) - } - // Set state home to a path under the file (impossible to mkdir) - t.Setenv("XDG_STATE_HOME", filepath.Join(blockingFile, "sub")) - - err := AppendHistory("text", "agent", "/cwd") - if err == nil { - t.Fatal("expected error when state directory cannot be created") - } -} - -func TestGetHistory_InvalidStateDir(t *testing.T) { - tmpDir := t.TempDir() - blockingFile := filepath.Join(tmpDir, "blocker") - if err := os.WriteFile(blockingFile, []byte("x"), 0o644); err != nil { - t.Fatalf("cannot create blocking file: %v", err) - } - t.Setenv("XDG_STATE_HOME", filepath.Join(blockingFile, "sub")) - - _, err := GetHistory(0) - if err == nil { - t.Fatal("expected error when state directory cannot be created") - } -} - -func containsString(s, substr string) bool { - return len(s) >= len(substr) && (s == substr || len(s) > len(substr) && findSubstring(s, substr)) -} - -func findSubstring(s, substr string) bool { - for i := 0; i <= len(s)-len(substr); i++ { - if s[i:i+len(substr)] == substr { - return true - } - } - return false -} |
