176 lines
5.6 KiB
Go
176 lines
5.6 KiB
Go
package mujica
|
||
|
||
import (
|
||
"fmt"
|
||
"testing"
|
||
"time"
|
||
|
||
"github.com/egoist/mygo/ui"
|
||
)
|
||
|
||
type weekProbe struct {
|
||
week 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) {
|
||
Use(c, 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)})
|
||
})
|
||
})
|
||
}
|