every n days recurrer

This commit is contained in:
Erik Winter 2022-06-06 11:17:49 +02:00
parent bbf594f37d
commit 03252488cf
2 changed files with 104 additions and 14 deletions

View File

@ -25,20 +25,13 @@ func NewRecurrer(recurStr string) Recurrer {
terms = terms[1:]
if recur, ok := ParseDaily(start, terms); ok {
for _, parseFunc := range []func(Date, []string) (Recurrer, bool){
ParseDaily, ParseEveryNDays, ParseWeekly, ParseBiweekly,
ParseEveryNWeeks, ParseEveryNMonths,
} {
if recur, ok := parseFunc(start, terms); ok {
return recur
}
if recur, ok := ParseWeekly(start, terms); ok {
return recur
}
if recur, ok := ParseBiweekly(start, terms); ok {
return recur
}
if recur, ok := ParseEveryNWeeks(start, terms); ok {
return recur
}
if recur, ok := ParseEveryNMonths(start, terms); ok {
return recur
}
return nil
@ -48,6 +41,7 @@ type Daily struct {
Start Date
}
// yyyy-mm-dd, daily
func ParseDaily(start Date, terms []string) (Recurrer, bool) {
if len(terms) < 1 {
return nil, false
@ -70,6 +64,55 @@ func (d Daily) String() string {
return fmt.Sprintf("%s, daily", d.Start.String())
}
type EveryNDays struct {
Start Date
N int
}
// yyyy-mm-dd, every 3 days
func ParseEveryNDays(start Date, terms []string) (Recurrer, bool) {
if len(terms) != 1 {
return EveryNDays{}, false
}
terms = strings.Split(terms[0], " ")
if len(terms) != 3 || terms[0] != "every" || terms[2] != "days" {
return EveryNDays{}, false
}
n, err := strconv.Atoi(terms[1])
if err != nil {
return EveryNDays{}, false
}
return EveryNDays{
Start: start,
N: n,
}, true
}
func (nd EveryNDays) RecursOn(date Date) bool {
if nd.Start.After(date) {
return false
}
testDate := nd.Start
for {
switch {
case testDate.Equal(date):
return true
case testDate.After(date):
return false
default:
testDate = testDate.Add(nd.N)
}
}
}
func (nd EveryNDays) String() string {
return fmt.Sprintf("%s, every %d days", nd.Start.String(), nd.N)
}
type Weekly struct {
Start Date
Weekdays Weekdays

View File

@ -50,6 +50,53 @@ func TestDaily(t *testing.T) {
})
}
func TestEveryNDays(t *testing.T) {
every := task.EveryNDays{
Start: task.NewDate(2022, 6, 8),
N: 5,
}
everyStr := "2022-06-08 (wednesday), every 5 days"
t.Run("parse", func(t *testing.T) {
test.Equals(t, every, task.NewRecurrer(everyStr))
})
t.Run("string", func(t *testing.T) {
test.Equals(t, everyStr, every.String())
})
t.Run("recurs on", func(t *testing.T) {
for _, tc := range []struct {
name string
date task.Date
exp bool
}{
{
name: "before",
date: task.NewDate(2022, 1, 1),
},
{
name: "start",
date: every.Start,
exp: true,
},
{
name: "after true",
date: every.Start.Add(15),
exp: true,
},
{
name: "after false",
date: every.Start.Add(16),
},
} {
t.Run(tc.name, func(t *testing.T) {
test.Equals(t, tc.exp, every.RecursOn(tc.date))
})
}
})
}
func TestParseWeekly(t *testing.T) {
start := task.NewDate(2021, 2, 7)
for _, tc := range []struct {