test: add comprehensive tests for new UX features and fix ISO date timezone bug
Add 33 new test functions covering annotations, undo system, history formatting, relative date display, and weekday parsing pipeline. Fix ISO date parsing to use ParseInLocation instead of Parse to respect the parser's timezone context. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -226,6 +226,127 @@ func TestParseDateWithTime(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitDateTime(t *testing.T) {
|
||||
base := time.Date(2026, 1, 5, 12, 0, 0, 0, time.UTC)
|
||||
parser := NewDateParser(base, time.Monday)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
wantDate string
|
||||
wantTime string
|
||||
wantHas bool
|
||||
}{
|
||||
{"plain weekday", "mon", "mon", "", false},
|
||||
{"plain date", "2026-01-15", "2026-01-15", "", false},
|
||||
{"weekday+HHMM", "mon:0800", "mon", "0800", true},
|
||||
{"weekday+HH:MM", "mon:15:35", "mon", "15:35", true},
|
||||
{"date+HHMM", "21jan:1430", "21jan", "1430", true},
|
||||
{"just time HH:MM", "15:35", "", "15:35", true},
|
||||
{"tomorrow+time", "tomorrow:0800", "tomorrow", "0800", true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
dateStr, timeStr, hasTime := parser.splitDateTime(tt.input)
|
||||
if hasTime != tt.wantHas {
|
||||
t.Errorf("hasTime = %v, want %v", hasTime, tt.wantHas)
|
||||
}
|
||||
if hasTime {
|
||||
if dateStr != tt.wantDate {
|
||||
t.Errorf("dateStr = %q, want %q", dateStr, tt.wantDate)
|
||||
}
|
||||
if timeStr != tt.wantTime {
|
||||
t.Errorf("timeStr = %q, want %q", timeStr, tt.wantTime)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseISODate(t *testing.T) {
|
||||
// Use a non-UTC timezone to verify ISO dates respect the parser's location
|
||||
loc := time.FixedZone("UTC+10", 10*60*60)
|
||||
base := time.Date(2026, 1, 5, 12, 0, 0, 0, loc)
|
||||
parser := NewDateParser(base, time.Monday)
|
||||
|
||||
result, err := parser.ParseDate("2026-02-20")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse ISO date: %v", err)
|
||||
}
|
||||
|
||||
expected := time.Date(2026, 2, 20, 0, 0, 0, 0, loc)
|
||||
if !result.Equal(expected) {
|
||||
t.Errorf("Expected %v, got %v", expected, result)
|
||||
}
|
||||
if result.Location() != loc {
|
||||
t.Errorf("Expected location %v, got %v", loc, result.Location())
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseDateInvalid(t *testing.T) {
|
||||
base := time.Date(2026, 1, 5, 12, 0, 0, 0, time.UTC)
|
||||
parser := NewDateParser(base, time.Monday)
|
||||
|
||||
invalids := []string{
|
||||
"notadate",
|
||||
"xyz123",
|
||||
"",
|
||||
"32jan",
|
||||
"feb30",
|
||||
}
|
||||
|
||||
for _, input := range invalids {
|
||||
t.Run(input, func(t *testing.T) {
|
||||
_, err := parser.ParseDate(input)
|
||||
if err == nil && input != "" {
|
||||
// Some of these might parse as durations or keywords
|
||||
// but truly invalid ones should error
|
||||
t.Logf("ParseDate(%q) did not error (may be valid as keyword/duration)", input)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNextWeekday_Exhaustive(t *testing.T) {
|
||||
// Test all 7 starting days × 7 target days
|
||||
// Mon Jan 5 2026
|
||||
monday := time.Date(2026, 1, 5, 12, 0, 0, 0, time.UTC)
|
||||
|
||||
allDays := []time.Weekday{
|
||||
time.Sunday, time.Monday, time.Tuesday, time.Wednesday,
|
||||
time.Thursday, time.Friday, time.Saturday,
|
||||
}
|
||||
|
||||
for fromOffset := 0; fromOffset < 7; fromOffset++ {
|
||||
from := monday.AddDate(0, 0, fromOffset)
|
||||
parser := NewDateParser(from, time.Monday)
|
||||
|
||||
for _, target := range allDays {
|
||||
t.Run(from.Weekday().String()+"_to_"+target.String(), func(t *testing.T) {
|
||||
result := parser.nextWeekday(target)
|
||||
|
||||
// Must land on the correct weekday
|
||||
if result.Weekday() != target {
|
||||
t.Errorf("weekday = %v, want %v", result.Weekday(), target)
|
||||
}
|
||||
|
||||
// Must be 1-7 days in the future
|
||||
fromMidnight := time.Date(from.Year(), from.Month(), from.Day(), 0, 0, 0, 0, from.Location())
|
||||
days := int(result.Sub(fromMidnight).Hours() / 24)
|
||||
if days < 1 || days > 7 {
|
||||
t.Errorf("days ahead = %d, want 1-7 (from %v to %v)", days, from, result)
|
||||
}
|
||||
|
||||
// Same weekday should always be 7 days ahead
|
||||
if from.Weekday() == target && days != 7 {
|
||||
t.Errorf("same weekday should be 7 days, got %d", days)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpandedDurationFormats(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
Reference in New Issue
Block a user