Files
MujicaUI/prompt_library_test.go
T
2026-10-05 14:24:42 -04:00

106 lines
3.5 KiB
Go

package mujica
import (
"slices"
"testing"
"github.com/egoist/mygo/ui"
)
func promptTemplates() []PromptTemplate {
return []PromptTemplate{
{ID: "t1", Category: "Letters", Title: "Invitation", Body: "Write an invitation to {{guest}} for the {{event}}."},
{ID: "t2", Category: "Music", Title: "Recital program", Body: "List pieces for a {{ instrument }} recital, then thank {{guest}}."},
{ID: "t3", Category: "Letters", Title: "Thank-you note", Body: "Thank the hosts."},
}
}
func TestPromptLibraryVariables(t *testing.T) {
if got := PromptLibraryVariables("{{a}} and {{ b }} and {{a}}"); !slices.Equal(got, []string{"a", "b"}) {
t.Fatalf("variables %q", got)
}
if got := PromptLibraryFill("Hi {{ name }}, {{x}}!", map[string]string{"name": "Ann"}); got != "Hi Ann, !" {
t.Fatalf("fill %q", got)
}
}
func TestPromptLibraryBrowseFillInsert(t *testing.T) {
var s PromptLibraryState
templates := promptTemplates()
inserted := ""
tt := chatTester(940, 520, func(c *ui.Context) {
if v := PromptLibrary(c, &s, templates, PromptLibraryOptions{Label: "Prompts"}); v.Inserted != "" {
inserted = v.Inserted
}
})
_ = tt.Click("Music")
if tt.HasText("Invitation") || !tt.HasText("Recital program") {
t.Fatalf("category filter: %q", tt.Texts())
}
_ = tt.Click("All")
_ = tt.Click("Search prompts")
tt.Type("thank")
if tt.HasText("Invitation") || !tt.HasText("Thank-you note") || !tt.HasText("Recital program") {
t.Fatalf("search covers titles and bodies: %q", tt.Texts())
}
_ = tt.Click("Recital program")
if !tt.HasText("[instrument]") {
t.Fatal("placeholder not previewed")
}
_ = tt.Click("Insert")
if inserted != "" {
t.Fatal("inserted with empty variables")
}
// Each variable's field sits under its label.
for _, f := range [][2]string{{"instrument", "harp"}, {"guest", "the duke"}} {
r, _ := tt.Find(f[0])
tt.ClickAt(r.X+20, r.Y+r.H+18)
tt.Type(f[1])
}
_ = tt.Click("Insert")
if inserted != "List pieces for a harp recital, then thank the duke." {
t.Fatalf("inserted %q", inserted)
}
}
func TestPromptLibraryKeyboardAndDisabled(t *testing.T) {
var s PromptLibraryState
tt := chatTester(940, 520, func(c *ui.Context) { PromptLibrary(c, &s, promptTemplates(), PromptLibraryOptions{}) })
tt.Key(0, ui.KeyTab)
tt.Key(0, ui.KeyDown)
tt.Key(0, ui.KeyEnter)
if s.Category != "Letters" {
t.Fatalf("keys chose category %q", s.Category)
}
var d PromptLibraryState
tt = chatTester(940, 520, func(c *ui.Context) { PromptLibrary(c, &d, promptTemplates(), PromptLibraryOptions{Disabled: true}) })
_ = tt.Click("Invitation")
_ = tt.Click("Music")
if d.Selected != "" || d.Category != "" {
t.Fatalf("disabled library chose %q %q", d.Selected, d.Category)
}
}
func TestPromptLibraryFiltersOnlyOnChange(t *testing.T) {
var s PromptLibraryState
templates := promptTemplates()
tt := chatTester(940, 520, func(c *ui.Context) { PromptLibrary(c, &s, templates, PromptLibraryOptions{}) })
s.shown.cats = append(s.shown.cats, "Marker")
tt.Frame()
if !slices.Contains(s.shown.cats, "Marker") {
t.Fatal("refiltered without a change")
}
s.Query = "invit"
tt.Frame()
if !slices.Equal(s.shown.ids, []int{0}) {
t.Fatalf("ids %v", s.shown.ids)
}
}
func TestPromptLibrarySnapshot(t *testing.T) {
snapshot(t, "prompt_library", 900, 360, func(c *ui.Context) {
s := &PromptLibraryState{Selected: "t1", Values: map[string]string{"guest": "Lady Ann"}}
ui.Column(c).Padding(16).Children(func() { PromptLibrary(c, s, promptTemplates(), PromptLibraryOptions{}) })
})
}