Files
MujicaUI/input/combobox_test.go

165 lines
4.2 KiB
Go

package input
import (
"strings"
"testing"
"github.com/egoist/mygo/ui"
"git.zacharyzhang.com/ZacharyZhang-NY/MujicaUI/core"
)
var comboboxTestFonts = []string{"Garamond", "Georgia", "Baskerville", "Didot", "Bodoni"}
type comboboxRun struct {
value, query string
changes int
queries []string
}
func comboboxTester(r *comboboxRun, options func(query string) []string, opts ComboboxOptions) *ui.Tester {
return ui.NewTester(func(c *ui.Context) {
core.Use(c, core.Settings{})
ui.Column(c).Padding(10).Gap(10).Children(func() {
res := Combobox(c, &r.value, options(r.query), opts)
if res.Changed() {
r.changes++
}
if res.QueryChanged() {
r.queries = append(r.queries, res.Query())
}
r.query = res.Query()
Button(c, "Other", ButtonOptions{})
})
}, 400, 400)
}
func fixedFonts(string) []string { return comboboxTestFonts }
func TestComboboxFiltersAndChooses(t *testing.T) {
r := &comboboxRun{}
tt := comboboxTester(r, fixedFonts, ComboboxOptions{Label: "Font"})
tt.Key(0, ui.KeyTab)
tt.Type("bo")
if !tt.HasText("Bodoni") || tt.HasText("Garamond") {
t.Fatalf("shown %v", tt.Texts())
}
tt.Key(0, ui.KeyEnter)
if r.value != "Bodoni" || r.changes != 1 {
t.Fatalf("value %q changes %d", r.value, r.changes)
}
}
func TestComboboxArrowsAndClick(t *testing.T) {
r := &comboboxRun{}
tt := comboboxTester(r, fixedFonts, ComboboxOptions{Label: "Font"})
tt.Key(0, ui.KeyTab)
tt.Key(0, ui.KeyDown)
tt.Key(0, ui.KeyDown)
tt.Key(0, ui.KeyEnter)
if r.value != "Georgia" {
t.Fatalf("arrows chose %q", r.value)
}
tt.Key(0, ui.KeyDown)
if err := tt.Click("Didot"); err != nil {
t.Fatal(err)
}
if r.value != "Didot" || r.query != "Didot" {
t.Fatalf("click chose %q, field %q", r.value, r.query)
}
}
func TestComboboxRevertsUnknownText(t *testing.T) {
r := &comboboxRun{value: "Didot"}
tt := comboboxTester(r, fixedFonts, ComboboxOptions{})
tt.Key(0, ui.KeyTab)
tt.Type("zzz")
if !tt.HasText("No matches") {
t.Fatal("no-match state missing")
}
tt.Key(0, ui.KeyTab)
if r.value != "Didot" || r.query != "Didot" || r.changes != 0 {
t.Fatalf("value %q field %q changes %d", r.value, r.query, r.changes)
}
}
func TestComboboxCustomValue(t *testing.T) {
r := &comboboxRun{}
tt := comboboxTester(r, fixedFonts, ComboboxOptions{AllowCustom: true})
tt.Key(0, ui.KeyTab)
tt.Type("Caslon")
if !tt.HasText("Use “Caslon”") {
t.Fatalf("custom option missing: %v", tt.Texts())
}
tt.Key(0, ui.KeyEnter)
if r.value != "Caslon" {
t.Fatalf("value %q", r.value)
}
tt.Type(" Pro")
tt.Key(0, ui.KeyTab)
if r.value != "Caslon Pro" {
t.Fatalf("blur kept %q", r.value)
}
}
func TestComboboxAsyncResults(t *testing.T) {
r := &comboboxRun{}
loading := true
remote := func(q string) []string {
if loading || q == "" {
return nil
}
var out []string
for _, f := range comboboxTestFonts {
if strings.Contains(strings.ToLower(f), strings.ToLower(q)) {
out = append(out, f+" (remote)")
}
}
return out
}
opts := ComboboxOptions{ExternalFilter: true}
tt := ui.NewTester(func(c *ui.Context) {
core.Use(c, core.Settings{})
opts.Loading = loading
res := Combobox(c, &r.value, remote(r.query), opts)
if res.QueryChanged() {
r.queries = append(r.queries, res.Query())
}
r.query = res.Query()
}, 400, 400)
tt.Key(0, ui.KeyTab)
tt.Type("di")
if len(r.queries) != 1 || r.queries[0] != "di" {
t.Fatalf("queries %v", r.queries)
}
if !tt.HasText("Loading…") {
t.Fatal("loading state missing")
}
loading = false
tt.Frame()
tt.Key(0, ui.KeyEnter)
if r.value != "Didot (remote)" {
t.Fatalf("value %q", r.value)
}
}
func TestComboboxDisabled(t *testing.T) {
r := &comboboxRun{value: "Didot"}
tt := comboboxTester(r, fixedFonts, ComboboxOptions{Disabled: true})
_ = tt.Click("Didot")
tt.Type("x")
if r.value != "Didot" || r.query != "Didot" || tt.HasText("Bodoni") {
t.Fatalf("disabled edited: %q %q", r.value, r.query)
}
}
func TestComboboxSnapshot(t *testing.T) {
snapshot(t, "combobox", 460, 110, func(c *ui.Context) {
a, b := "", "Didot"
ui.Row(c).Padding(20).Gap(16).Children(func() {
Combobox(c, &a, comboboxTestFonts, ComboboxOptions{Placeholder: "Typeface"})
Combobox(c, &b, comboboxTestFonts, ComboboxOptions{Loading: true})
})
})
}