From 041db5abe904e9ab6091e362776d6146a3e01bdb Mon Sep 17 00:00:00 2001 From: Erik Winter Date: Mon, 23 Dec 2024 10:06:59 +0100 Subject: [PATCH] service test --- item/recur.go | 12 ++--- plan/storage/storage.go | 100 +++++++++++++++++++----------------- sync/service/memory.go | 41 ++++----------- sync/service/memory_test.go | 33 +++--------- sync/service/recur_test.go | 17 +++--- 5 files changed, 81 insertions(+), 122 deletions(-) diff --git a/item/recur.go b/item/recur.go index a8e4735..a20d89f 100644 --- a/item/recur.go +++ b/item/recur.go @@ -43,10 +43,10 @@ func NewRecurrer(recurStr string) Recurrer { func FirstRecurAfter(r Recurrer, d Date) Date { lim := NewDate(2050, 1, 1) for { + d = d.Add(1) if r.RecursOn(d) || d.Equal(lim) { return d } - d = d.Add(1) } } @@ -73,7 +73,7 @@ func (d Daily) RecursOn(date Date) bool { return date.Equal(d.Start) || date.After(d.Start) } -func (d Daily) First() Date { return FirstRecurAfter(d, d.Start) } +func (d Daily) First() Date { return FirstRecurAfter(d, d.Start.Add(-1)) } func (d Daily) String() string { return fmt.Sprintf("%s, daily", d.Start.String()) @@ -124,7 +124,7 @@ func (nd EveryNDays) RecursOn(date Date) bool { } } -func (nd EveryNDays) First() Date { return FirstRecurAfter(nd, nd.Start) } +func (nd EveryNDays) First() Date { return FirstRecurAfter(nd, nd.Start.Add(-1)) } func (nd EveryNDays) String() string { return fmt.Sprintf("%s, every %d days", nd.Start.String(), nd.N) @@ -177,7 +177,7 @@ func (w Weekly) RecursOn(date Date) bool { return false } -func (w Weekly) First() Date { return FirstRecurAfter(w, w.Start) } +func (w Weekly) First() Date { return FirstRecurAfter(w, w.Start.Add(-1)) } func (w Weekly) String() string { weekdayStrs := []string{} @@ -227,7 +227,7 @@ func (enw EveryNWeeks) RecursOn(date Date) bool { return enw.Start.DaysBetween(date)%intervalDays == 0 } -func (enw EveryNWeeks) First() Date { return FirstRecurAfter(enw, enw.Start) } +func (enw EveryNWeeks) First() Date { return FirstRecurAfter(enw, enw.Start.Add(-1)) } func (enw EveryNWeeks) String() string { return fmt.Sprintf("%s, every %d weeks", enw.Start.String(), enw.N) @@ -277,7 +277,7 @@ func (enm EveryNMonths) RecursOn(date Date) bool { } -func (enm EveryNMonths) First() Date { return FirstRecurAfter(enm, enm.Start) } +func (enm EveryNMonths) First() Date { return FirstRecurAfter(enm, enm.Start.Add(-1)) } func (enm EveryNMonths) String() string { return fmt.Sprintf("%s, every %d months", enm.Start.String(), enm.N) diff --git a/plan/storage/storage.go b/plan/storage/storage.go index 080ba89..9dc2794 100644 --- a/plan/storage/storage.go +++ b/plan/storage/storage.go @@ -2,66 +2,70 @@ package storage import ( "errors" + "sort" + "time" + + "go-mod.ewintr.nl/planner/item" ) var ( ErrNotFound = errors.New("not found") ) -// type LocalID interface { -// FindAll() (map[string]int, error) -// FindOrNext(id string) (int, error) -// Next() (int, error) -// Store(id string, localID int) error -// Delete(id string) error -// } +type LocalID interface { + FindAll() (map[string]int, error) + FindOrNext(id string) (int, error) + Next() (int, error) + Store(id string, localID int) error + Delete(id string) error +} -// type Sync interface { -// FindAll() ([]item.Item, error) -// Store(i item.Item) error -// DeleteAll() error -// LastUpdate() (time.Time, error) -// } +type Sync interface { + FindAll() ([]item.Item, error) + Store(i item.Item) error + DeleteAll() error + LastUpdate() (time.Time, error) +} -// type Event interface { -// Store(event item.Event) error -// Find(id string) (item.Event, error) -// FindAll() ([]item.Event, error) -// Delete(id string) error -// } +type Event interface { + Store(event item.Event) error + Find(id string) (item.Event, error) + FindAll() ([]item.Event, error) + Delete(id string) error +} -// func NextLocalID(used []int) int { -// if len(used) == 0 { -// return 1 -// } +func NextLocalID(used []int) int { + if len(used) == 0 { + return 1 + } -// sort.Ints(used) -// usedMax := 1 -// for _, u := range used { -// if u > usedMax { -// usedMax = u -// } -// } + sort.Ints(used) + usedMax := 1 + for _, u := range used { + if u > usedMax { + usedMax = u + } + } -// var limit int -// for limit = 1; limit <= len(used) || limit < usedMax; limit *= 10 { -// } + var limit int + for limit = 1; limit <= len(used) || limit < usedMax; limit *= 10 { + } -// newId := used[len(used)-1] + 1 -// if newId < limit { -// return newId -// } + newId := used[len(used)-1] + 1 + if newId < limit { + return newId + } -// usedMap := map[int]bool{} -// for _, u := range used { -// usedMap[u] = true -// } + usedMap := map[int]bool{} + for _, u := range used { + usedMap[u] = true + } -// for i := 1; i < limit; i++ { -// if _, ok := usedMap[i]; !ok { -// return i -// } -// } + for i := 1; i < limit; i++ { + if _, ok := usedMap[i]; !ok { + return i + } + } -// return limit -// } + return limit +} diff --git a/sync/service/memory.go b/sync/service/memory.go index 84f3a88..e079ced 100644 --- a/sync/service/memory.go +++ b/sync/service/memory.go @@ -46,34 +46,15 @@ func (m *Memory) Updated(kinds []item.Kind, timestamp time.Time) ([]item.Item, e return result, nil } -func (m *Memory) RecursBefore(date time.Time) ([]item.Item, error) { - // res := make([]item.Item, 0) - // for _, i := range m.items { - // if i.Recurrer == nil { - // continue - // } - // if i.RecurNext.Before(date) { - // res = append(res, i) - // } - // } - // return res, nil - return nil, nil -} - -func (m *Memory) RecursNext(id string, date time.Time, ts time.Time) error { - // i, ok := m.items[id] - // if !ok { - // return ErrNotFound - // } - // if i.Recurrer == nil { - // return ErrNotARecurrer - // } - // if !i.Recurrer.On(date) { - // return fmt.Errorf("item does not recur on %v", date) - // } - // i.RecurNext = date - // i.Updated = ts - // m.items[id] = i - - return nil +func (m *Memory) ShouldRecur(date item.Date) ([]item.Item, error) { + res := make([]item.Item, 0) + for _, i := range m.items { + if i.Recurrer == nil { + continue + } + if date.Equal(i.RecurNext) || date.After(i.RecurNext) { + res = append(res, i) + } + } + return res, nil } diff --git a/sync/service/memory_test.go b/sync/service/memory_test.go index a512348..b9009da 100644 --- a/sync/service/memory_test.go +++ b/sync/service/memory_test.go @@ -113,19 +113,14 @@ func TestMemoryRecur(t *testing.T) { mem := NewMemory() now := time.Now() earlier := now.Add(-5 * time.Minute) - today := time.Date(2024, 12, 1, 0, 0, 0, 0, time.UTC) - yesterday := time.Date(2024, 11, 30, 0, 0, 0, 0, time.UTC) - tomorrow := time.Date(2024, 12, 2, 0, 0, 0, 0, time.UTC) + today := item.NewDate(2024, 12, 1) + yesterday := item.NewDate(2024, 11, 30) t.Log("start") i1 := item.Item{ - ID: "a", - Updated: earlier, - Recurrer: &item.Recur{ - Start: yesterday, - Period: item.PeriodDay, - Count: 1, - }, + ID: "a", + Updated: earlier, + Recurrer: item.NewRecurrer("2024-11-30, daily"), RecurNext: yesterday, } i2 := item.Item{ @@ -140,7 +135,7 @@ func TestMemoryRecur(t *testing.T) { } t.Log("get recurrers") - rs, err := mem.RecursBefore(today) + rs, err := mem.ShouldRecur(today) if err != nil { t.Errorf("exp nil, gt %v", err) } @@ -148,20 +143,4 @@ func TestMemoryRecur(t *testing.T) { t.Errorf("(exp +, got -)\n%s", diff) } - t.Log("set next") - if err := mem.RecursNext(i1.ID, tomorrow, time.Now()); err != nil { - t.Errorf("exp nil, got %v", err) - } - - t.Log("check result") - us, err := mem.Updated([]item.Kind{}, now) - if err != nil { - t.Errorf("exp nil, got %v", err) - } - if len(us) != 1 { - t.Errorf("exp 1, got %v", len(us)) - } - if us[0].ID != i1.ID { - t.Errorf("exp %v, got %v", i1.ID, us[0].ID) - } } diff --git a/sync/service/recur_test.go b/sync/service/recur_test.go index 5148237..2aabe14 100644 --- a/sync/service/recur_test.go +++ b/sync/service/recur_test.go @@ -12,23 +12,18 @@ import ( func TestRecur(t *testing.T) { t.Parallel() - now := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC) + now := time.Now() + today := item.NewDate(2024, 1, 1) mem := NewMemory() rec := NewRecur(mem, mem, slog.New(slog.NewTextHandler(io.Discard, nil))) - // Create a recurring item - recur := &item.Recur{ - Start: now, - Period: item.PeriodDay, - Count: 1, - } testItem := item.Item{ ID: "test-1", Kind: item.KindEvent, Updated: now, Deleted: false, - Recurrer: recur, - RecurNext: now, + Recurrer: item.NewRecurrer("2024-01-01, daily"), + RecurNext: today, Body: `{"title":"Test Event","start":"2024-01-01T10:00:00Z","duration":"30m"}`, } @@ -53,14 +48,14 @@ func TestRecur(t *testing.T) { } // Check that RecurNext was updated - recurItems, err := mem.RecursBefore(now.Add(48 * time.Hour)) + recurItems, err := mem.ShouldRecur(today.Add(1)) if err != nil { t.Fatal(err) } if len(recurItems) != 1 { t.Errorf("expected 1 recur item, got %d", len(recurItems)) } - if !recurItems[0].RecurNext.After(now) { + if !recurItems[0].RecurNext.After(today) { t.Errorf("RecurNext was not updated, still %v", recurItems[0].RecurNext) } }