166 lines
4.6 KiB
Go
166 lines
4.6 KiB
Go
package mujica
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/egoist/mygo/ui"
|
|
)
|
|
|
|
var calendarToday = Date{2026, time.October, 5}
|
|
|
|
// datetimeTestLabel is the en-US spoken name of a day cell.
|
|
func datetimeTestLabel(d Date) string {
|
|
return fmt.Sprintf("%v, %v %d, %d", d.Weekday(), d.Month, d.Day, d.Year)
|
|
}
|
|
|
|
func calendarTester(value *Date, opts CalendarOptions, changes *int) *ui.Tester {
|
|
opts.Today = calendarToday
|
|
return ui.NewTester(func(c *ui.Context) {
|
|
Use(c, Settings{Mode: Light})
|
|
if Calendar(c, value, opts).Changed() {
|
|
*changes++
|
|
}
|
|
}, 400, 400)
|
|
}
|
|
|
|
func TestCalendarClickChoosesDay(t *testing.T) {
|
|
v, n := Date{}, 0
|
|
tt := calendarTester(&v, CalendarOptions{}, &n)
|
|
if !tt.HasText("October 2026") {
|
|
t.Fatalf("empty value should show today's month, got %v", tt.Texts())
|
|
}
|
|
if err := tt.Click("Monday, October 12, 2026"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if v != (Date{2026, time.October, 12}) || n != 1 {
|
|
t.Fatalf("value %v changes %d", v, n)
|
|
}
|
|
if err := tt.Click("Monday, October 12, 2026"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if n != 1 {
|
|
t.Fatalf("same day reported change again: %d", n)
|
|
}
|
|
}
|
|
|
|
func TestCalendarKeyboard(t *testing.T) {
|
|
v, n := Date{2026, time.October, 15}, 0
|
|
tt := calendarTester(&v, CalendarOptions{}, &n)
|
|
tt.Key(0, ui.KeyTab)
|
|
tt.Key(0, ui.KeyTab)
|
|
tt.Key(0, ui.KeyTab)
|
|
tt.Key(0, ui.KeyTab)
|
|
tt.Key(0, ui.KeyTab)
|
|
if !tt.Focused("Thursday, October 15, 2026") {
|
|
t.Fatal("Tab should land on the chosen day")
|
|
}
|
|
tt.Key(0, ui.KeyRight)
|
|
tt.Key(0, ui.KeyDown)
|
|
if !tt.Focused("Friday, October 23, 2026") {
|
|
t.Fatal("arrows should move the focus by day and week")
|
|
}
|
|
tt.Key(0, ui.KeyPageDown)
|
|
if !tt.HasText("November 2026") || !tt.Focused("Monday, November 23, 2026") {
|
|
t.Fatalf("PageDown should move a month: %v", tt.Texts()[:3])
|
|
}
|
|
tt.Key(ui.Shift, ui.KeyPageUp)
|
|
if !tt.HasText("November 2025") {
|
|
t.Fatal("Shift+PageUp should move a year")
|
|
}
|
|
tt.Key(0, ui.KeyEnd)
|
|
tt.Key(0, ui.KeyEnter)
|
|
if v != (Date{2025, time.November, 30}) || n != 1 {
|
|
t.Fatalf("Enter chose %v (%d changes)", v, n)
|
|
}
|
|
tt.Key(0, ui.KeyHome)
|
|
tt.Key(0, ui.KeySpace)
|
|
if v != (Date{2025, time.November, 1}) || n != 2 {
|
|
t.Fatalf("Space chose %v", v)
|
|
}
|
|
}
|
|
|
|
func TestCalendarLimits(t *testing.T) {
|
|
v, n := Date{2026, time.October, 10}, 0
|
|
opts := CalendarOptions{
|
|
Min: Date{2026, time.October, 5},
|
|
Max: Date{2026, time.October, 20},
|
|
DisableDate: func(d Date) bool { return d.Weekday() == time.Sunday },
|
|
}
|
|
tt := calendarTester(&v, opts, &n)
|
|
for _, label := range []string{"Thursday, October 1, 2026", "Sunday, October 11, 2026", "Wednesday, October 21, 2026"} {
|
|
if err := tt.Click(label); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if v != (Date{2026, time.October, 10}) || n != 0 {
|
|
t.Fatalf("disabled days changed the value to %v", v)
|
|
}
|
|
if err := tt.Click("Saturday, October 10, 2026"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
tt.Key(0, ui.KeyRight)
|
|
if !tt.Focused("Monday, October 12, 2026") {
|
|
t.Fatal("arrows should skip the disabled Sunday")
|
|
}
|
|
}
|
|
|
|
func TestCalendarWeekStart(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
ws WeekStart
|
|
loc Locale
|
|
first string
|
|
}{{WeekStartLocale, EnUS, "Sunday"}, {WeekStartLocale, ZhCN, "星期一"}, {WeekStartMonday, EnUS, "Monday"}, {WeekStartSaturday, EnUS, "Saturday"}} {
|
|
v := Date{2026, time.October, 5}
|
|
tt := ui.NewTester(func(c *ui.Context) {
|
|
Use(c, Settings{Locale: tc.loc})
|
|
Calendar(c, &v, CalendarOptions{WeekStart: tc.ws, Today: calendarToday})
|
|
}, 400, 400)
|
|
texts := tt.Texts()
|
|
var first string
|
|
for i, s := range texts {
|
|
if s == "2026年10月" || s == "October 2026" {
|
|
first = texts[i+3]
|
|
break
|
|
}
|
|
}
|
|
if first != tc.first {
|
|
t.Errorf("%v %v: first column %q, want %q", tc.ws, tc.loc, first, tc.first)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCalendarDisabled(t *testing.T) {
|
|
v, n := Date{2026, time.October, 10}, 0
|
|
tt := calendarTester(&v, CalendarOptions{Disabled: true}, &n)
|
|
_ = tt.Click("Monday, October 12, 2026")
|
|
_ = tt.Click("Next month")
|
|
if v != (Date{2026, time.October, 10}) || n != 0 || !tt.HasText("October 2026") {
|
|
t.Fatalf("disabled calendar changed: %v", v)
|
|
}
|
|
}
|
|
|
|
func TestCalendarRejectsInvalidValue(t *testing.T) {
|
|
defer func() {
|
|
if recover() == nil {
|
|
t.Fatal("expected panic for February 30")
|
|
}
|
|
}()
|
|
v := Date{2026, time.February, 30}
|
|
ui.NewTester(func(c *ui.Context) {
|
|
Use(c, Settings{})
|
|
Calendar(c, &v, CalendarOptions{})
|
|
}, 400, 400)
|
|
}
|
|
|
|
func TestCalendarSnapshot(t *testing.T) {
|
|
v := Date{2026, time.October, 14}
|
|
snapshot(t, "calendar", 320, 340, func(c *ui.Context) {
|
|
ui.Column(c).Padding(16).Children(func() {
|
|
Calendar(c, &v, CalendarOptions{Today: calendarToday, Max: Date{2026, time.October, 28},
|
|
DisableDate: func(d Date) bool { return d.Day == 20 }})
|
|
})
|
|
})
|
|
}
|