This commit is contained in:
Erik Winter 2024-12-01 11:51:43 +01:00
parent 3f0bd4e047
commit f87d979582
6 changed files with 120 additions and 14 deletions

View File

@ -52,6 +52,8 @@ func (e *EventBody) UnmarshalJSON(data []byte) error {
type Event struct {
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
}
@ -83,6 +87,8 @@ func (e Event) Item() (Item, error) {
return Item{
ID: e.ID,
Kind: KindEvent,
Recurrer: e.Recurrer,
RecurNext: e.RecurNext,
Body: string(body),
}, nil
}

View File

@ -22,6 +22,8 @@ type Item struct {
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"`
}

View File

@ -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 {

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -9,9 +9,15 @@ import (
var (
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
}