fancy theme

This commit is contained in:
2026-11-04 17:18:09 +01:00
parent e6ca4aef8f
commit d0860c26ad
11 changed files with 351 additions and 44 deletions
+81
View File
@@ -0,0 +1,81 @@
package main
import (
"os"
"path/filepath"
"strings"
"testing"
"github.com/charmbracelet/lipgloss"
"todoapp/internal/todos"
)
func assertFits(t *testing.T, view string, width, height int) {
t.Helper()
lines := strings.Split(strings.TrimSuffix(view, "\n"), "\n")
if len(lines) > height {
t.Fatalf("view is %d lines in %d-row terminal:\n%s", len(lines), height, view)
}
for _, line := range lines {
if lipgloss.Width(line) > width {
t.Fatalf("line is %d cells in %d-column terminal: %q", lipgloss.Width(line), width, line)
}
}
}
func TestStyledScreensFitTerminals(t *testing.T) {
for _, size := range [][2]int{{80, 24}, {50, 14}, {32, 10}} {
width, height := size[0], size[1]
app := model{width: width, height: height, project: "/tmp/project", todosDir: "/tmp/project/.pi/todos", items: []todos.Todo{
{ID: "deadbeef", Title: "A long title for a narrow terminal", Status: "open", Tags: []string{"qa"}, Body: "# Long heading\n\nBody text."},
{ID: "cafebabe", Title: "Another todo", Status: "in_progress_with_long_status", Tags: []string{"a very long tag that must be clipped"}, Body: "Second body"},
}}
assertFits(t, app.View(), width, height)
if !strings.Contains(app.View(), "› ") || !strings.Contains(app.View(), "Search:") {
t.Fatal("selection or search missing from styled list")
}
app = testKey(app, runeKey('/'))
app = testKey(app, runeKey('z'))
if !strings.Contains(app.View(), "No matching todos") {
t.Fatal("search empty state missing")
}
assertFits(t, app.View(), width, height)
app.search, app.query = false, ""
app.detail = true
assertFits(t, app.View(), width, height)
app.detail = false
// Render an editor without touching the filesystem.
app.editor = &editor{creating: true, fields: [3]string{"A title that goes well beyond the width of this small window", "qa, pi", "Line one\nLine two"}}
app.editor.selectField(0)
if !strings.Contains(app.View(), "▏") {
t.Fatalf("title cursor hidden at width %d: %s", width, app.View())
}
assertFits(t, app.View(), width, height)
app.editor.selectField(2)
assertFits(t, app.View(), width, height)
app.confirm = "close"
assertFits(t, app.View(), width, height)
}
}
func TestNoColorAndMalformedWarning(t *testing.T) {
t.Setenv("NO_COLOR", "1")
project := t.TempDir()
dir := todos.Dir(project)
if err := os.MkdirAll(dir, 0700); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(dir, "deadbeef.md"), []byte("invalid"), 0600); err != nil {
t.Fatal(err)
}
app, err := newModel(project)
if err != nil {
t.Fatal(err)
}
view := app.View()
if !strings.Contains(view, "Warning") || !strings.Contains(view, "No todos yet") || strings.Contains(view, "\x1b[") {
t.Fatalf("no-color warning/empty state is unclear: %s", view)
}
assertFits(t, view, 80, 24)
}