Files
MujicaUI/datetime/calendar_week_view_test.go

178 lines
5.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package datetime
import (
"fmt"
"testing"
"time"
"github.com/egoist/mygo/ui"
"git.zacharyzhang.com/ZacharyZhang-NY/MujicaUI/core"
)
type weekProbe struct {
week core.Date
events []CalendarEvent
opts CalendarWeekViewOptions
changes []CalendarChange
opened []string
disabled bool
}
func (p *weekProbe) tester() *ui.Tester {
if p.week.IsZero() {
p.week = oct(14)
}
p.opts.Location, p.opts.Today = calTokyo, calendarToday
p.opts.Now = time.Date(2026, time.October, 14, 10, 30, 0, 0, calTokyo)
return ui.NewTester(func(c *ui.Context) {
core.Use(c, core.Settings{})
o := p.opts
o.Disabled = p.disabled
r := CalendarWeekView(c, &p.week, p.events, o)
if ch, ok := r.Changed(); ok {
p.changes = append(p.changes, ch)
}
if id, ok := r.Opened(); ok {
p.opened = append(p.opened, id)
}
}, 1100, 900)
}
func calDrag(tt *ui.Tester, x0, y0, x1, y1 float32) {
tt.Press(x0, y0)
for i := 1; i <= 4; i++ {
f := float32(i) / 4
tt.Move(x0+(x1-x0)*f, y0+(y1-y0)*f)
}
tt.Release(x1, y1)
}
func calAt(t *testing.T, h, m int, day int) time.Time {
t.Helper()
return time.Date(2026, time.October, day, h, m, 0, 0, calTokyo)
}
func TestCalendarWeekViewDragCreateAndKeyboardCreate(t *testing.T) {
p := &weekProbe{}
tt := p.tester()
col, ok := tt.Find("Schedule, " + datetimeTestLabel(oct(15)))
if !ok {
t.Fatal("no column")
}
hourH := float32(72)
// Drag 9:00 to 10:30; the visible top is 8:00.
y9 := col.Y + hourH + 5
calDrag(tt, col.X+20, y9, col.X+20, y9+hourH*1.5)
if len(p.changes) != 1 || p.changes[0].Kind != CalendarCreate || !p.changes[0].Start.Equal(calAt(t, 9, 0, 15)) || !p.changes[0].End.Equal(calAt(t, 11, 0, 15)) {
t.Fatalf("drag create %+v", p.changes)
}
tt.Key(0, ui.KeyDown)
tt.Key(0, ui.KeyEnter)
if len(p.changes) != 2 || !p.changes[1].Start.Equal(calAt(t, 9, 30, 15)) || !p.changes[1].End.Equal(calAt(t, 10, 0, 15)) {
t.Fatalf("keyboard create %+v", p.changes)
}
}
func TestCalendarWeekViewMoveResizeAndOverlap(t *testing.T) {
p := &weekProbe{events: []CalendarEvent{calEvent("a", 14, 9, 0, 60), calEvent("b", 14, 9, 30, 60)}}
tt := p.tester()
a, _ := tt.Find("Event a, 09:00 – 10:00")
b, _ := tt.Find("Event b, 09:30 – 10:30")
if b.X <= a.X || b.X-a.X < a.W/2 || b.Y <= a.Y {
t.Fatalf("overlapping events should sit side by side: %v %v", a, b)
}
calDrag(tt, a.X+10, a.Y+20, a.X+10, a.Y+20+72)
if len(p.changes) != 1 || p.changes[0].Kind != CalendarMove || !p.changes[0].Start.Equal(calAt(t, 10, 0, 14)) || !p.changes[0].End.Equal(calAt(t, 11, 0, 14)) {
t.Fatalf("move %+v", p.changes)
}
h, _ := tt.Find("Resize Event b")
calDrag(tt, h.X+10, h.Y+3, h.X+10, h.Y+3+36)
if len(p.changes) != 2 || p.changes[1].Kind != CalendarResize || !p.changes[1].End.Equal(calAt(t, 11, 0, 14)) {
t.Fatalf("resize %+v", p.changes)
}
_ = tt.Click("Event a, 09:00 – 10:00")
if len(p.opened) != 1 {
t.Fatalf("click should open: %v", p.opened)
}
tt.Key(ui.Alt, ui.KeyRight)
tt.Key(ui.Alt, ui.KeyDown)
tt.Key(ui.Alt|ui.Shift, ui.KeyUp)
if len(p.changes) != 5 || !p.changes[2].Start.Equal(calAt(t, 9, 0, 15)) || !p.changes[3].Start.Equal(calAt(t, 9, 30, 14)) ||
!p.changes[4].End.Equal(calAt(t, 9, 30, 14)) {
t.Fatalf("keyboard changes %+v", p.changes[2:])
}
}
func TestCalendarWeekViewAllDayWeekStartAndNav(t *testing.T) {
ev := calEvent("h", 16, 0, 0, 24*60)
ev.AllDay, ev.Title = true, "Holiday"
p := &weekProbe{events: []CalendarEvent{ev}, opts: CalendarWeekViewOptions{WeekStart: WeekStartMonday}}
tt := p.tester()
if !tt.HasText("October 12 – October 18, 2026") || !tt.HasText("All day") || !tt.HasText("Holiday") {
t.Fatalf("texts %v", tt.Texts()[:12])
}
_ = tt.Click("Holiday, All day")
tt.Key(ui.Alt, ui.KeyRight)
if len(p.changes) != 1 || !p.changes[0].Start.Equal(calAt(t, 0, 0, 17)) || !p.changes[0].AllDay {
t.Fatalf("all-day move %+v", p.changes)
}
_ = tt.Click("Next week")
if p.week != oct(21) {
t.Fatalf("week %v", p.week)
}
}
func TestCalendarWeekViewDisabledAndInvalid(t *testing.T) {
p := &weekProbe{events: []CalendarEvent{calEvent("a", 14, 9, 0, 60)}, disabled: true}
tt := p.tester()
a, _ := tt.Find("Event a, 09:00 – 10:00")
calDrag(tt, a.X+10, a.Y+20, a.X+10, a.Y+92)
_ = tt.Click("Event a, 09:00 – 10:00")
tt.Key(ui.Alt, ui.KeyDown)
_ = tt.Click("Next week")
if len(p.changes) != 0 || len(p.opened) != 0 || p.week != oct(14) {
t.Fatal("disabled week view reacted")
}
for _, opts := range []CalendarWeekViewOptions{{SlotMinutes: 7}, {SlotMinutes: -15}} {
func() {
defer func() {
if recover() == nil {
t.Errorf("%+v: expected panic", opts)
}
}()
q := &weekProbe{opts: opts}
q.tester()
}()
}
}
func TestCalendarWeekViewLargeData(t *testing.T) {
p := &weekProbe{}
base := time.Date(2000, 1, 1, 9, 0, 0, 0, calTokyo)
for i := range 100000 {
s := base.Add(time.Duration(i) * 3 * time.Hour)
p.events = append(p.events, CalendarEvent{ID: fmt.Sprint(i), Title: "E", Start: s, End: s.Add(time.Hour)})
}
tt := p.tester()
if n := len(tt.Texts()); n > 400 {
t.Fatalf("built %d labels for one week", n)
}
}
func TestCalendarWeekViewSnapshot(t *testing.T) {
w := oct(14)
evs := []CalendarEvent{calEvent("1", 12, 9, 0, 60), calEvent("2", 14, 9, 0, 120), calEvent("3", 14, 9, 30, 60),
calEvent("4", 15, 13, 0, 90), calEvent("5", 16, 10, 0, 45)}
evs[1].Color, evs[2].Color, evs[3].Color = EventInfo, EventSuccess, EventWarning
h := calEvent("h", 13, 0, 0, 24*60)
h.AllDay, h.Title = true, "Holiday"
evs = append(evs, h)
snapshot(t, "calendar_week_view", 1000, 860, func(c *ui.Context) {
ui.Column(c).Padding(16).Children(func() {
CalendarWeekView(c, &w, evs, CalendarWeekViewOptions{Location: calTokyo, Today: calendarToday,
Now: time.Date(2026, time.October, 14, 10, 30, 0, 0, calTokyo)})
})
})
}