Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ jobs:
- run: gofmt -l cmd internal | tee /dev/stderr | (! read)
- run: go vet ./...
- run: go build ./...
- run: go test -race ./...
25 changes: 25 additions & 0 deletions internal/collect/git_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package collect

import "testing"

func TestAnchorMidnight(t *testing.T) {
tests := []struct {
name string
in string
want string
}{
{"bare ISO date gets midnight", "2026-05-24", "2026-05-24 00:00:00"},
{"month rollover date", "2026-02-01", "2026-02-01 00:00:00"},
{"relative string untouched", "7 days ago", "7 days ago"},
{"yesterday keyword untouched", "yesterday", "yesterday"},
{"empty untouched", "", ""},
{"date with time untouched", "2026-05-24 12:00:00", "2026-05-24 12:00:00"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := anchorMidnight(tt.in); got != tt.want {
t.Errorf("anchorMidnight(%q) = %q, want %q", tt.in, got, tt.want)
}
})
}
}
121 changes: 121 additions & 0 deletions internal/model/range_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package model

import (
"testing"
"time"
)

func TestFromDates(t *testing.T) {
tests := []struct {
name string
from, to string
wantSince string
wantUntil string
wantLabel string
wantErr bool
}{
{
name: "single day makes until exclusive next day",
from: "2026-05-24", to: "2026-05-24",
wantSince: "2026-05-24", wantUntil: "2026-05-25", wantLabel: "2026-05-24",
},
{
name: "multi-day range",
from: "2026-05-01", to: "2026-05-03",
wantSince: "2026-05-01", wantUntil: "2026-05-04", wantLabel: "2026-05-01 → 2026-05-03",
},
{
name: "until rolls over month boundary",
from: "2026-01-31", to: "2026-01-31",
wantSince: "2026-01-31", wantUntil: "2026-02-01", wantLabel: "2026-01-31",
},
{name: "bad from", from: "nope", to: "2026-05-24", wantErr: true},
{name: "bad to", from: "2026-05-24", to: "nope", wantErr: true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r, err := FromDates(tt.from, tt.to)
if tt.wantErr {
if err == nil {
t.Fatalf("expected error, got %+v", r)
}
return
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if r.Since != tt.wantSince || r.Until != tt.wantUntil || r.Label != tt.wantLabel {
t.Errorf("got {Since:%q Until:%q Label:%q}, want {Since:%q Until:%q Label:%q}",
r.Since, r.Until, r.Label, tt.wantSince, tt.wantUntil, tt.wantLabel)
}
})
}
}

func TestFromDatesEmptyToDefaultsToday(t *testing.T) {
r, err := FromDates("2026-05-01", "")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
wantUntil := time.Now().AddDate(0, 0, 1).Format(isoDate)
if r.Until != wantUntil {
t.Errorf("Until = %q, want %q (today + 1, exclusive)", r.Until, wantUntil)
}
}

func TestFromMonth(t *testing.T) {
r, err := FromMonth("2026-02")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if r.Since != "2026-02-01" || r.Until != "2026-03-01" {
t.Errorf("got {Since:%q Until:%q}, want {2026-02-01 2026-03-01}", r.Since, r.Until)
}
if r.Label != "February 2026" {
t.Errorf("Label = %q, want %q", r.Label, "February 2026")
}
if _, err := FromMonth("bad"); err == nil {
t.Error("expected error for bad month")
}
}

// TestPresetBoundaries guards the regression behind the date-skew bug: each
// preset must produce a half-open [Since, Until) window aligned to whole days,
// independent of the current time of day.
func TestPresetBoundaries(t *testing.T) {
now := time.Now()
today := now.Format(isoDate)
yesterday := now.AddDate(0, 0, -1).Format(isoDate)
tomorrow := now.AddDate(0, 0, 1).Format(isoDate)

tests := []struct {
choice string
wantSince string
wantUntil string
}{
{"Today", today, tomorrow},
{"Yesterday", yesterday, today},
{"Last 7 days", now.AddDate(0, 0, -6).Format(isoDate), tomorrow},
{"Last 30 days", now.AddDate(0, 0, -29).Format(isoDate), tomorrow},
}
for _, tt := range tests {
t.Run(tt.choice, func(t *testing.T) {
r := Preset(tt.choice)
if r.Since != tt.wantSince {
t.Errorf("Since = %q, want %q", r.Since, tt.wantSince)
}
if r.Until != tt.wantUntil {
t.Errorf("Until = %q, want %q", r.Until, tt.wantUntil)
}
})
}
}

func TestPresetUnknownFallsBackToWeek(t *testing.T) {
r := Preset("not a preset")
want := Preset("Last 7 days")
if r.Since != want.Since || r.Until != want.Until {
t.Errorf("unknown preset = {%q,%q}, want last-7-days {%q,%q}",
r.Since, r.Until, want.Since, want.Until)
}
}
Loading