summaryrefslogtreecommitdiff
path: root/internal/models/recurrence_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/models/recurrence_test.go')
-rw-r--r--internal/models/recurrence_test.go51
1 files changed, 51 insertions, 0 deletions
diff --git a/internal/models/recurrence_test.go b/internal/models/recurrence_test.go
new file mode 100644
index 0000000..8d18996
--- /dev/null
+++ b/internal/models/recurrence_test.go
@@ -0,0 +1,51 @@
+package models
+
+import (
+ "testing"
+ "time"
+)
+
+func TestComputeNextOccurrence(t *testing.T) {
+ mustParse := func(t *testing.T, s string) time.Time {
+ t.Helper()
+ d, err := time.Parse("2006-01-02", s)
+ if err != nil {
+ t.Fatalf("bad fixture date %q: %v", s, err)
+ }
+ return d
+ }
+
+ tests := []struct {
+ name string
+ due string
+ freq string
+ interval int
+ weekdays []int
+ want string
+ }{
+ {"daily interval 1", "2026-07-13", "daily", 1, nil, "2026-07-14"},
+ {"daily interval 3", "2026-07-13", "daily", 3, nil, "2026-07-16"},
+ {"weekly no weekdays interval 1", "2026-07-13", "weekly", 1, nil, "2026-07-20"},
+ {"weekly no weekdays interval 2", "2026-07-13", "weekly", 2, nil, "2026-07-27"},
+ // 2026-07-13 is a Monday (weekday=1).
+ {"weekly with weekdays same week", "2026-07-13", "weekly", 1, []int{1, 3, 5}, "2026-07-15"},
+ {"weekly with weekdays wraps to next week", "2026-07-17", "weekly", 1, []int{1, 3, 5}, "2026-07-20"}, // due=Fri(5), wraps to Mon
+ {"weekly with weekdays interval 2 wraps", "2026-07-13", "weekly", 2, []int{1}, "2026-07-27"}, // due=Mon, only Mon active, skip a week
+ {"monthly interval 1", "2026-06-13", "monthly", 1, nil, "2026-07-13"},
+ {"monthly rollover", "2026-01-31", "monthly", 1, nil, "2026-03-03"},
+ {"monthly rollover locks in on the drifted day", "2026-03-03", "monthly", 1, nil, "2026-04-03"},
+ {"yearly interval 1", "2026-07-13", "yearly", 1, nil, "2027-07-13"},
+ {"unknown freq returns due unchanged", "2026-07-13", "bogus", 1, nil, "2026-07-13"},
+ {"interval below 1 is treated as 1", "2026-07-13", "daily", 0, nil, "2026-07-14"},
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ got := ComputeNextOccurrence(mustParse(t, tc.due), tc.freq, tc.interval, tc.weekdays)
+ want := mustParse(t, tc.want)
+ if !got.Equal(want) {
+ t.Errorf("ComputeNextOccurrence(%s, %s, %d, %v) = %s, want %s", tc.due, tc.freq, tc.interval, tc.weekdays, got.Format("2006-01-02"), tc.want)
+ }
+ })
+ }
+}