From f87d979582e351299f808037f59532fb4f681e62 Mon Sep 17 00:00:00 2001 From: Erik Winter Date: Sun, 1 Dec 2024 11:51:43 +0100 Subject: [PATCH] mem test --- item/event.go | 14 ++++++--- item/item.go | 12 ++++--- item/recur.go | 6 ++-- sync/service/memory.go | 32 +++++++++++++++++++ sync/service/memory_test.go | 62 ++++++++++++++++++++++++++++++++++++- sync/service/storage.go | 8 ++++- 6 files changed, 120 insertions(+), 14 deletions(-) diff --git a/item/event.go b/item/event.go index 5a7fbfc..5faafa1 100644 --- a/item/event.go +++ b/item/event.go @@ -51,7 +51,9 @@ func (e *EventBody) UnmarshalJSON(data []byte) error { } type Event struct { - ID string `json:"id"` + ID string `json:"id"` + Recurrer *Recur `json:"recurrer"` + RecurNext time.Time `json:"recurNext"` EventBody } @@ -66,6 +68,8 @@ func NewEvent(i Item) (Event, error) { } e.ID = i.ID + e.Recurrer = i.Recurrer + e.RecurNext = i.RecurNext return e, nil } @@ -81,9 +85,11 @@ func (e Event) Item() (Item, error) { } return Item{ - ID: e.ID, - Kind: KindEvent, - Body: string(body), + ID: e.ID, + Kind: KindEvent, + Recurrer: e.Recurrer, + RecurNext: e.RecurNext, + Body: string(body), }, nil } diff --git a/item/item.go b/item/item.go index 8d5d5ca..93ea4c5 100644 --- a/item/item.go +++ b/item/item.go @@ -18,11 +18,13 @@ var ( ) type Item struct { - ID string `json:"id"` - Kind Kind `json:"kind"` - Updated time.Time `json:"updated"` - Deleted bool `json:"deleted"` - Body string `json:"body"` + ID string `json:"id"` + Kind Kind `json:"kind"` + Updated time.Time `json:"updated"` + Deleted bool `json:"deleted"` + Recurrer *Recur `json:"recurrer"` + RecurNext time.Time `json:"recurNext"` + Body string `json:"body"` } func NewItem(k Kind, body string) Item { diff --git a/item/recur.go b/item/recur.go index 48d37be..0df33de 100644 --- a/item/recur.go +++ b/item/recur.go @@ -10,9 +10,9 @@ const ( ) type Recur struct { - Start time.Time - Period RecurPeriod - Count int + Start time.Time `json:"start"` + Period RecurPeriod `json:"period"` + Count int `json:"count"` } func (r *Recur) On(date time.Time) bool { diff --git a/sync/service/memory.go b/sync/service/memory.go index cbcaf8b..97439a6 100644 --- a/sync/service/memory.go +++ b/sync/service/memory.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "slices" "sync" "time" @@ -44,3 +45,34 @@ 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 +} + +func (m *Memory) RecursNext(id string, date 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 = time.Now() + m.items[id] = i + + return nil +} diff --git a/sync/service/memory_test.go b/sync/service/memory_test.go index d2f38d3..9d7c134 100644 --- a/sync/service/memory_test.go +++ b/sync/service/memory_test.go @@ -5,10 +5,11 @@ import ( "testing" "time" + "github.com/google/go-cmp/cmp" "go-mod.ewintr.nl/planner/item" ) -func TestMemoryItem(t *testing.T) { +func TestMemoryUpdate(t *testing.T) { t.Parallel() mem := NewMemory() @@ -109,3 +110,62 @@ func TestMemoryItem(t *testing.T) { t.Errorf("exp %v, got %v", t1.ID, actItems[0].ID) } } + +func TestMemoryRecur(t *testing.T) { + t.Parallel() + + 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) + + t.Log("start") + i1 := item.Item{ + ID: "a", + Updated: earlier, + Recurrer: &item.Recur{ + Start: yesterday, + Period: item.PeriodDay, + Count: 1, + }, + RecurNext: yesterday, + } + i2 := item.Item{ + ID: "b", + Updated: earlier, + } + + for _, i := range []item.Item{i1, i2} { + if err := mem.Update(i); err != nil { + t.Errorf("exp nil, ot %v", err) + } + } + + t.Log("get recurrers") + rs, err := mem.RecursBefore(today) + if err != nil { + t.Errorf("exp nil, gt %v", err) + } + if diff := cmp.Diff([]item.Item{i1}, rs); diff != "" { + t.Errorf("(exp +, got -)\n%s", diff) + } + + t.Log("set next") + if err := mem.RecursNext(i1.ID, tomorrow); 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/storage.go b/sync/service/storage.go index ba14634..4ea186f 100644 --- a/sync/service/storage.go +++ b/sync/service/storage.go @@ -8,10 +8,16 @@ import ( ) var ( - ErrNotFound = errors.New("not found") + ErrNotFound = errors.New("not found") + ErrNotARecurrer = errors.New("not a recurrer") ) type Syncer interface { Update(item item.Item) error Updated(kind []item.Kind, t time.Time) ([]item.Item, error) } + +type Recurrer interface { + RecursBefore(date time.Time) ([]item.Item, error) + RecursNext(id string, date time.Time) error +}