1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
package grid
import (
"testing"
"time"
"ticktock/internal/store"
)
func at(h, m int) time.Time {
return time.Date(2026, 7, 7, h, m, 0, 0, time.Local)
}
func TestParseHM(t *testing.T) {
m, err := parseHM("07:30")
if err != nil || m != 450 {
t.Fatalf("got %d err %v, want 450", m, err)
}
if _, err := parseHM("nope"); err == nil {
t.Fatal("want error")
}
}
func TestBuildGridAlignsAndCountsRows(t *testing.T) {
// window 07:00..09:00, slot 30 → rows at 07:00,07:30,08:00,08:30 = 4
g := BuildGrid(30, 7*60, 9*60, nil)
if g.FirstMin != 420 || g.Rows != 4 {
t.Fatalf("got FirstMin=%d Rows=%d, want 420,4", g.FirstMin, g.Rows)
}
}
func TestBuildGridExpandsToCoverEntries(t *testing.T) {
// entry 06:10..09:40 must expand window 07:00..08:00 outward, slot 30:
// first floors 06:10 → 06:00 (360); last ceils 09:40 → 10:00 (600)
es := []store.Entry{{Start: at(6, 10), End: at(9, 40)}}
g := BuildGrid(30, 7*60, 8*60, es)
if g.FirstMin != 360 {
t.Errorf("FirstMin=%d, want 360", g.FirstMin)
}
last := g.SlotMinute(g.Rows) // one past the last row = window end
if last != 600 {
t.Errorf("window end=%d, want 600", last)
}
}
func TestRowOfRoundTripAndClamp(t *testing.T) {
g := BuildGrid(30, 7*60, 9*60, nil) // FirstMin 420, Rows 4
if g.RowOf(420) != 0 || g.RowOf(449) != 0 || g.RowOf(450) != 1 {
t.Errorf("RowOf boundaries wrong")
}
if g.RowOf(0) != 0 {
t.Errorf("below window should clamp to 0")
}
if g.RowOf(100000) != g.Rows-1 {
t.Errorf("above window should clamp to last row")
}
if g.SlotMinute(2) != 420+60 {
t.Errorf("SlotMinute wrong")
}
}
func TestBuildGridRunningEntryUsesStartOnly(t *testing.T) {
es := []store.Entry{{Start: at(20, 10)}} // End zero → running
g := BuildGrid(30, 7*60, 21*60, es)
// running start 20:10 is inside default window; end stays 21:00
if g.SlotMinute(g.Rows) != 21*60 {
t.Errorf("running entry must not expand end past window")
}
}
|