diff options
Diffstat (limited to 'internal/reports/daterange_test.go')
-rw-r--r-- | internal/reports/daterange_test.go | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/internal/reports/daterange_test.go b/internal/reports/daterange_test.go new file mode 100644 index 0000000..69b0e4a --- /dev/null +++ b/internal/reports/daterange_test.go @@ -0,0 +1,246 @@ +package reports + +import ( + "fmt" + "strings" + "testing" + "time" +) + +func TestParseDateRange(t *testing.T) { + // Use a fixed time for testing + testTime := time.Date(2024, time.August, 15, 10, 30, 0, 0, time.UTC) // Thursday, August 15, 2024 + + tests := []struct { + name string + input string + wantErr bool + validate func(t *testing.T, dr DateRange) + }{ + { + name: "this week", + input: "this week", + wantErr: false, + validate: func(t *testing.T, dr DateRange) { + // Should be Monday Aug 12 to Sunday Aug 18 + expectedStart := time.Date(2024, time.August, 12, 0, 0, 0, 0, time.UTC) + expectedEnd := time.Date(2024, time.August, 18, 23, 59, 59, 999999999, time.UTC) + if !dr.Start.Equal(expectedStart) { + t.Errorf("Start = %v, want %v", dr.Start, expectedStart) + } + if !dr.End.Equal(expectedEnd) { + t.Errorf("End = %v, want %v", dr.End, expectedEnd) + } + }, + }, + { + name: "this month", + input: "this month", + wantErr: false, + validate: func(t *testing.T, dr DateRange) { + // Should be Aug 1 to Aug 31 + expectedStart := time.Date(2024, time.August, 1, 0, 0, 0, 0, time.UTC) + expectedEnd := time.Date(2024, time.August, 31, 23, 59, 59, 999999999, time.UTC) + if !dr.Start.Equal(expectedStart) { + t.Errorf("Start = %v, want %v", dr.Start, expectedStart) + } + if !dr.End.Equal(expectedEnd) { + t.Errorf("End = %v, want %v", dr.End, expectedEnd) + } + }, + }, + { + name: "month name - current month", + input: "august", + wantErr: false, + validate: func(t *testing.T, dr DateRange) { + // Should be August 2024 (current year since we're in August) + expectedStart := time.Date(2024, time.August, 1, 0, 0, 0, 0, time.UTC) + expectedEnd := time.Date(2024, time.August, 31, 23, 59, 59, 999999999, time.UTC) + if !dr.Start.Equal(expectedStart) { + t.Errorf("Start = %v, want %v", dr.Start, expectedStart) + } + if !dr.End.Equal(expectedEnd) { + t.Errorf("End = %v, want %v", dr.End, expectedEnd) + } + }, + }, + { + name: "month name - past month this year", + input: "july", + wantErr: false, + validate: func(t *testing.T, dr DateRange) { + // Should be July 2024 (current year since July already passed) + expectedStart := time.Date(2024, time.July, 1, 0, 0, 0, 0, time.UTC) + expectedEnd := time.Date(2024, time.July, 31, 23, 59, 59, 999999999, time.UTC) + if !dr.Start.Equal(expectedStart) { + t.Errorf("Start = %v, want %v", dr.Start, expectedStart) + } + if !dr.End.Equal(expectedEnd) { + t.Errorf("End = %v, want %v", dr.End, expectedEnd) + } + }, + }, + { + name: "month name - future month last year", + input: "december", + wantErr: false, + validate: func(t *testing.T, dr DateRange) { + // Should be December 2023 (last year since December hasn't come yet) + expectedStart := time.Date(2023, time.December, 1, 0, 0, 0, 0, time.UTC) + expectedEnd := time.Date(2023, time.December, 31, 23, 59, 59, 999999999, time.UTC) + if !dr.Start.Equal(expectedStart) { + t.Errorf("Start = %v, want %v", dr.Start, expectedStart) + } + if !dr.End.Equal(expectedEnd) { + t.Errorf("End = %v, want %v", dr.End, expectedEnd) + } + }, + }, + { + name: "case insensitive month name", + input: "FEBRUARY", + wantErr: false, + validate: func(t *testing.T, dr DateRange) { + // Should be February 2024 (current year since February already passed) + expectedStart := time.Date(2024, time.February, 1, 0, 0, 0, 0, time.UTC) + expectedEnd := time.Date(2024, time.February, 29, 23, 59, 59, 999999999, time.UTC) // 2024 is a leap year + if !dr.Start.Equal(expectedStart) { + t.Errorf("Start = %v, want %v", dr.Start, expectedStart) + } + if !dr.End.Equal(expectedEnd) { + t.Errorf("End = %v, want %v", dr.End, expectedEnd) + } + }, + }, + { + name: "short month name", + input: "feb", + wantErr: false, + validate: func(t *testing.T, dr DateRange) { + // Should be February 2024 + expectedStart := time.Date(2024, time.February, 1, 0, 0, 0, 0, time.UTC) + expectedEnd := time.Date(2024, time.February, 29, 23, 59, 59, 999999999, time.UTC) // 2024 is a leap year + if !dr.Start.Equal(expectedStart) { + t.Errorf("Start = %v, want %v", dr.Start, expectedStart) + } + if !dr.End.Equal(expectedEnd) { + t.Errorf("End = %v, want %v", dr.End, expectedEnd) + } + }, + }, + { + name: "month year format", + input: "july 2023", + wantErr: false, + validate: func(t *testing.T, dr DateRange) { + // Should be July 2023 + expectedStart := time.Date(2023, time.July, 1, 0, 0, 0, 0, time.UTC) + expectedEnd := time.Date(2023, time.July, 31, 23, 59, 59, 999999999, time.UTC) + if !dr.Start.Equal(expectedStart) { + t.Errorf("Start = %v, want %v", dr.Start, expectedStart) + } + if !dr.End.Equal(expectedEnd) { + t.Errorf("End = %v, want %v", dr.End, expectedEnd) + } + }, + }, + { + name: "short month year format", + input: "feb 2022", + wantErr: false, + validate: func(t *testing.T, dr DateRange) { + // Should be February 2022 + expectedStart := time.Date(2022, time.February, 1, 0, 0, 0, 0, time.UTC) + expectedEnd := time.Date(2022, time.February, 28, 23, 59, 59, 999999999, time.UTC) // 2022 is not a leap year + if !dr.Start.Equal(expectedStart) { + t.Errorf("Start = %v, want %v", dr.Start, expectedStart) + } + if !dr.End.Equal(expectedEnd) { + t.Errorf("End = %v, want %v", dr.End, expectedEnd) + } + }, + }, + { + name: "case insensitive month year", + input: "MARCH 2023", + wantErr: false, + validate: func(t *testing.T, dr DateRange) { + // Should be March 2023 + expectedStart := time.Date(2023, time.March, 1, 0, 0, 0, 0, time.UTC) + expectedEnd := time.Date(2023, time.March, 31, 23, 59, 59, 999999999, time.UTC) + if !dr.Start.Equal(expectedStart) { + t.Errorf("Start = %v, want %v", dr.Start, expectedStart) + } + if !dr.End.Equal(expectedEnd) { + t.Errorf("End = %v, want %v", dr.End, expectedEnd) + } + }, + }, + { + name: "invalid month name", + input: "invalid", + wantErr: true, + }, + { + name: "invalid month year format", + input: "july 23", + wantErr: true, + }, + { + name: "invalid year", + input: "july abcd", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a custom ParseDateRange that uses our test time + testParseFunc := func(dateStr string) (DateRange, error) { + dateStr = strings.TrimSpace(dateStr) + + // Check for predefined ranges (case-insensitive) + lowerDateStr := strings.ToLower(dateStr) + switch lowerDateStr { + case "last week": + return getLastWeek(testTime), nil + case "this week": + return getThisWeek(testTime), nil + case "last month": + return getLastMonth(testTime), nil + case "this month": + return getThisMonth(testTime), nil + } + + // Check for month name patterns (case-insensitive) + if dateRange, err := parseMonthName(dateStr, testTime); err == nil { + return dateRange, nil + } + + // Check for "month year" format + if dateRange, err := parseMonthYear(dateStr); err == nil { + return dateRange, nil + } + + // Check for custom date range format: "YYYY-MM-DD to YYYY-MM-DD" + if strings.Contains(dateStr, " to ") { + return parseCustomDateRange(dateStr) + } + + return DateRange{}, fmt.Errorf("unsupported date range: %s", dateStr) + } + + got, err := testParseFunc(tt.input) + if (err != nil) != tt.wantErr { + t.Errorf("ParseDateRange() error = %v, wantErr %v", err, tt.wantErr) + return + } + + if !tt.wantErr && tt.validate != nil { + tt.validate(t, got) + } + }) + } +} + |