Files
MujicaUI/date_picker_test.go
T

153 lines
4.7 KiB
Go

package mujica
import (
"testing"
"time"
"github.com/egoist/mygo/ui"
)
func datePickerTester(value *Date, opts DatePickerOptions, changes *int) *ui.Tester {
opts.Today = calendarToday
return ui.NewTester(func(c *ui.Context) {
Use(c, Settings{Mode: Light})
ui.Column(c).Padding(16).Gap(8).Children(func() {
if DatePicker(c, value, opts).Changed() {
*changes++
}
Button(c, "Elsewhere", ButtonOptions{})
})
}, 420, 460)
}
func datePickerType(tt *ui.Tester, label, text string) {
_ = tt.Click(label)
tt.Command("selectAll")
tt.Type(text)
}
func TestDatePickerTyping(t *testing.T) {
v, n := Date{2026, time.October, 5}, 0
tt := datePickerTester(&v, DatePickerOptions{Label: "Due"}, &n)
datePickerType(tt, "Due", "2026-11-03")
tt.Key(0, ui.KeyEnter)
if v != (Date{2026, time.November, 3}) || n != 1 {
t.Fatalf("Enter committed %v (%d)", v, n)
}
datePickerType(tt, "Due", "2026-12-24")
if err := tt.Click("Elsewhere"); err != nil {
t.Fatal(err)
}
if v != (Date{2026, time.December, 24}) || n != 2 {
t.Fatalf("blur committed %v (%d)", v, n)
}
}
func TestDatePickerInvalidInputKept(t *testing.T) {
v, n := Date{2026, time.October, 5}, 0
tt := datePickerTester(&v, DatePickerOptions{Label: "Due", Max: Date{2026, time.December, 31}}, &n)
datePickerType(tt, "Due", "2026-02-30")
tt.Key(0, ui.KeyEnter)
if v != (Date{2026, time.October, 5}) || n != 0 {
t.Fatalf("invalid day was corrected into %v", v)
}
if !tt.HasText("Enter a date like 2026-10-05.") {
t.Fatalf("expected an error: %v", tt.Texts())
}
// The typed text stays: fixing its day makes it valid.
tt.Key(0, ui.KeyBackspace)
tt.Key(0, ui.KeyBackspace)
tt.Type("28")
tt.Key(0, ui.KeyEnter)
if v != (Date{2026, time.February, 28}) || n != 1 || tt.HasText("Enter a date like") {
t.Fatalf("edited text committed %v (%d)", v, n)
}
datePickerType(tt, "Due", "2027-01-02")
tt.Key(0, ui.KeyEnter)
if v != (Date{2026, time.February, 28}) || !tt.HasText("Choose 2026-12-31 or earlier.") {
t.Fatalf("out of range accepted: %v %v", v, tt.Texts())
}
datePickerType(tt, "Due", "")
tt.Key(0, ui.KeyEnter)
if v.IsZero() {
t.Fatal("empty text cleared a non-clearable picker")
}
}
func TestDatePickerCalendarPopup(t *testing.T) {
v, n := Date{2026, time.October, 5}, 0
tt := datePickerTester(&v, DatePickerOptions{Label: "Due"}, &n)
if err := tt.Click("Open calendar"); err != nil {
t.Fatal(err)
}
if !tt.Focused("Monday, October 5, 2026") {
t.Fatal("the popup should focus the chosen day")
}
tt.Key(0, ui.KeyRight)
tt.Key(0, ui.KeyEnter)
if v != (Date{2026, time.October, 6}) || n != 1 || tt.HasText("October 2026") {
t.Fatalf("keyboard pick %v, popup open %v", v, tt.HasText("October 2026"))
}
_ = tt.Click("Due")
tt.Key(0, ui.KeyDown)
if !tt.HasText("October 2026") {
t.Fatal("Down should open the calendar")
}
tt.Key(0, ui.KeyEscape)
if tt.HasText("October 2026") || v != (Date{2026, time.October, 6}) {
t.Fatal("Escape should close without change")
}
_ = tt.Click("Open calendar")
if err := tt.Click("Thursday, October 22, 2026"); err != nil {
t.Fatal(err)
}
if v != (Date{2026, time.October, 22}) || n != 2 {
t.Fatalf("click pick %v", v)
}
}
func TestDatePickerClearAndLayout(t *testing.T) {
v, n := Date{2026, time.October, 5}, 0
tt := datePickerTester(&v, DatePickerOptions{Label: "Due", Clearable: true, Layout: "02/01/2006"}, &n)
_ = tt.Click("Due")
tt.Key(0, ui.KeyEnter)
if v != (Date{2026, time.October, 5}) || n != 0 || tt.HasText("Enter a date like") {
t.Fatalf("shown text did not parse back with the layout: %v", tt.Texts())
}
if err := tt.Click("Clear"); err != nil {
t.Fatal(err)
}
if !v.IsZero() || n != 1 {
t.Fatalf("clear left %v", v)
}
datePickerType(tt, "Due", "31/12/2026")
tt.Key(0, ui.KeyEnter)
if v != (Date{2026, time.December, 31}) {
t.Fatalf("custom layout parsed %v", v)
}
}
func TestDatePickerDisabled(t *testing.T) {
v, n := Date{2026, time.October, 5}, 0
tt := datePickerTester(&v, DatePickerOptions{Label: "Due", Disabled: true}, &n)
_ = tt.Click("Open calendar")
if tt.HasText("October 2026") {
t.Fatal("disabled picker opened")
}
}
func TestDatePickerSnapshot(t *testing.T) {
a, b, e := Date{2026, time.October, 14}, Date{}, Date{2026, time.October, 5}
snapshot(t, "date_picker", 640, 130, func(c *ui.Context) {
ui.Row(c).Padding(16).Gap(16).AlignItems(ui.Start).Children(func() {
ui.Column(c).Gap(12).Width(260).Children(func() {
DatePicker(c, &b, DatePickerOptions{Today: calendarToday})
DatePicker(c, &e, DatePickerOptions{Today: calendarToday, Disabled: true})
})
ui.Column(c).Width(300).Children(func() {
DatePicker(c, &a, DatePickerOptions{Today: calendarToday, Clearable: true, Label: "Due"})
})
})
})
}