package app import ( "os" "path/filepath" "strings" "testing" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" "glint/internal/editor" ) func statusApp() *App { a := newApp() a.width = 120 a.height = 24 return a } func TestStatusBarShowsLnCol(t *testing.T) { a := statusApp() a.editor.SetContent([]byte("hello\nworld")) a.editor.Cursor = editor.Position{Row: 1, Col: 2} if got := a.statusBar(); !strings.Contains(got, "Ln 2:3") { t.Fatalf("status bar missing Ln 2:3:\n%s", got) } } func TestStatusBarShowsWordCount(t *testing.T) { a := statusApp() a.editor.SetContent([]byte("one two three")) if got := a.statusBar(); !strings.Contains(got, "3 words") { t.Fatalf("status bar missing word count:\n%s", got) } } func TestStatusBarShowsThemeName(t *testing.T) { a := statusApp() if got := a.statusBar(); !strings.Contains(got, a.theme.Name) { t.Fatalf("status bar missing theme %q:\n%s", a.theme.Name, got) } } func TestStatusBarShowsHelpIndicator(t *testing.T) { a := statusApp() if got := a.statusBar(); !strings.Contains(got, "?") { t.Fatalf("status bar missing help indicator:\n%s", got) } } func TestStatusBarShowsSelectionStats(t *testing.T) { a := statusApp() a.editor.SetContent([]byte("one two three")) for i := 0; i < 7; i++ { // select "one two" via Shift+Right a.editor.HandleKey(tea.KeyMsg{Type: tea.KeyShiftRight}) } got := a.statusBar() if !strings.Contains(got, "7 chars") || !strings.Contains(got, "2 words selected") { t.Fatalf("status bar missing selection stats:\n%s", got) } } func TestRepoOrParentReturnsRepoName(t *testing.T) { root := t.TempDir() repo := filepath.Join(root, "myrepo") sub := filepath.Join(repo, "notes") if err := os.MkdirAll(filepath.Join(repo, ".git"), 0o755); err != nil { t.Fatal(err) } if err := os.MkdirAll(sub, 0o755); err != nil { t.Fatal(err) } got := repoOrParent(filepath.Join(sub, "n.md")) if got != "myrepo" { t.Fatalf("repoOrParent = %q, want %q", got, "myrepo") } } func TestRepoOrParentFallsBackToParent(t *testing.T) { root := t.TempDir() dir := filepath.Join(root, "plainfolder") if err := os.MkdirAll(dir, 0o755); err != nil { t.Fatal(err) } got := repoOrParent(filepath.Join(dir, "n.md")) if got != "plainfolder" { t.Fatalf("repoOrParent = %q, want %q", got, "plainfolder") } } func TestStatusBarNarrowNoOverflow(t *testing.T) { a := statusApp() a.width = 20 a.editor.SetContent([]byte("one two three four five")) a.editor.Cursor = editor.Position{Row: 0, Col: 3} for _, line := range strings.Split(a.statusBar(), "\n") { if w := lipgloss.Width(line); w > 20 { t.Fatalf("status line width %d > 20: %q", w, line) } } } func TestEscClearsSelection(t *testing.T) { a := statusApp() a.editor.SetContent([]byte("hello world")) for i := 0; i < 5; i++ { // select "hello" with Shift+Right a.editor.HandleKey(tea.KeyMsg{Type: tea.KeyShiftRight}) } if !a.editor.HasSelection() { t.Fatal("setup: expected a selection") } a.handleKey(tea.KeyMsg{Type: tea.KeyEsc}) if a.editor.HasSelection() { t.Fatal("Esc should clear the selection") } if a.mode != ModeEditor { t.Fatalf("mode = %v, want ModeEditor", a.mode) } }