diff --git a/dist/plan b/dist/plan index a22e835..47cda3c 100755 Binary files a/dist/plan and b/dist/plan differ diff --git a/plan/command/add.go b/plan/command/add.go index c5cbac0..9ae41f3 100644 --- a/plan/command/add.go +++ b/plan/command/add.go @@ -90,7 +90,7 @@ type Add struct { Args AddArgs } -func (a *Add) Do(deps Dependencies) (CommandResult, error) { +func (a Add) Do(deps Dependencies) (CommandResult, error) { if err := deps.TaskRepo.Store(a.Args.Task); err != nil { return nil, fmt.Errorf("could not store event: %v", err) } diff --git a/plan/command/delete.go b/plan/command/delete.go index 0122609..fb73f13 100644 --- a/plan/command/delete.go +++ b/plan/command/delete.go @@ -34,7 +34,7 @@ type Delete struct { Args DeleteArgs } -func (del *Delete) Do(deps Dependencies) (CommandResult, error) { +func (del Delete) Do(deps Dependencies) (CommandResult, error) { var id string idMap, err := deps.LocalIDRepo.FindAll() if err != nil { diff --git a/plan/command/list.go b/plan/command/list.go index 3c6f8e9..2ea8810 100644 --- a/plan/command/list.go +++ b/plan/command/list.go @@ -11,14 +11,20 @@ import ( ) type ListArgs struct { - fieldTPL map[string][]string - params storage.TaskListParams + fieldTPL map[string][]string + HasRecurrer bool + From item.Date + To item.Date + Project string } func NewListArgs() ListArgs { return ListArgs{ fieldTPL: map[string][]string{ - "project": {"p", "project"}, + "project": {"p", "project"}, + "from": {"f", "from"}, + "to": {"t", "to"}, + "recurring": {"rec", "recurring"}, }, } } @@ -32,63 +38,74 @@ func (la ListArgs) Parse(main []string, fields map[string]string) (Command, erro if err != nil { return nil, err } + now := time.Now() today := item.NewDate(now.Year(), int(now.Month()), now.Day()) - tomorrow := item.NewDate(now.Year(), int(now.Month()), now.Day()+1) - var date item.Date - var includeBefore, recurrer bool - var project string switch len(main) { case 0: - date = today - includeBefore = true + fields["to"] = today.String() case 1: switch { - case slices.Contains([]string{"today", "tod"}, main[0]): - date = today - includeBefore = true - case slices.Contains([]string{"tomorrow", "tom"}, main[0]): - date = tomorrow - case main[0] == "list" || main[0] == "l": - if val, ok := fields["project"]; ok { - project = val - } + case slices.Contains([]string{"tod", "today"}, main[0]): + fields["to"] = today.String() + case slices.Contains([]string{"tom", "tomorrow"}, main[0]): + fields["from"] = today.Add(1).String() + fields["to"] = today.Add(1).String() + case main[0] == "week": + fields["from"] = today.String() + fields["to"] = today.Add(7).String() + case main[0] == "recur": + fields["recurring"] = "true" + case main[0] == "list": + fields["from"] = today.String() + fields["to"] = today.String() default: return nil, ErrWrongCommand } - case 2: - if main[0] == "list" && main[1] == "recur" { - recurrer = true - } else { - return nil, ErrWrongCommand - } - default: - return nil, ErrWrongCommand } - return &List{ - args: ListArgs{ - params: storage.TaskListParams{ - Date: date, - IncludeBefore: includeBefore, - Recurrer: recurrer, - Project: project, - }, + var fromDate, toDate item.Date + var hasRecurrer bool + var project string + if val, ok := fields["from"]; ok { + fromDate = item.NewDateFromString(val) + } + if val, ok := fields["to"]; ok { + toDate = item.NewDateFromString(val) + } + if val, ok := fields["recurrer"]; ok && val == "true" { + hasRecurrer = true + } + if val, ok := fields["project"]; ok { + project = val + } + + return List{ + Args: ListArgs{ + HasRecurrer: hasRecurrer, + From: fromDate, + To: toDate, + Project: project, }, }, nil } type List struct { - args ListArgs + Args ListArgs } -func (list *List) Do(deps Dependencies) (CommandResult, error) { +func (list List) Do(deps Dependencies) (CommandResult, error) { localIDs, err := deps.LocalIDRepo.FindAll() if err != nil { return nil, fmt.Errorf("could not get local ids: %v", err) } - all, err := deps.TaskRepo.FindMany(list.args.params) + all, err := deps.TaskRepo.FindMany(storage.TaskListParams{ + HasRecurrer: list.Args.HasRecurrer, + From: list.Args.From, + To: list.Args.To, + Project: list.Args.Project, + }) if err != nil { return nil, err } diff --git a/plan/command/list_test.go b/plan/command/list_test.go index 20d0234..23db38d 100644 --- a/plan/command/list_test.go +++ b/plan/command/list_test.go @@ -2,12 +2,82 @@ package command_test import ( "testing" + "time" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "go-mod.ewintr.nl/planner/item" "go-mod.ewintr.nl/planner/plan/command" "go-mod.ewintr.nl/planner/plan/storage/memory" ) +func TestListParse(t *testing.T) { + t.Parallel() + now := time.Now() + today := item.NewDate(now.Year(), int(now.Month()), now.Day()) + + for _, tc := range []struct { + name string + main []string + fields map[string]string + expArgs command.ListArgs + expErr bool + }{ + { + name: "empty", + main: []string{}, + fields: map[string]string{}, + expArgs: command.ListArgs{ + To: today, + }, + }, + { + name: "today", + main: []string{"tod"}, + fields: map[string]string{}, + expArgs: command.ListArgs{ + To: today, + }, + }, + { + name: "tomorrow", + main: []string{"tom"}, + fields: map[string]string{}, + expArgs: command.ListArgs{ + From: today.Add(1), + To: today.Add(1), + }, + }, + { + name: "week", + main: []string{"week"}, + fields: map[string]string{}, + expArgs: command.ListArgs{ + From: today, + To: today.Add(7), + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + nla := command.NewListArgs() + cmd, actErr := nla.Parse(tc.main, tc.fields) + if tc.expErr != (actErr != nil) { + t.Errorf("exp %v, got %v", tc.expErr, actErr != nil) + } + if tc.expErr { + return + } + listCmd, ok := cmd.(command.List) + if !ok { + t.Errorf("exp true, got false") + } + if diff := cmp.Diff(tc.expArgs, listCmd.Args, cmpopts.IgnoreTypes(map[string][]string{})); diff != "" { + t.Errorf("(+exp, -got)\n%s\n", diff) + } + }) + } +} + func TestList(t *testing.T) { t.Parallel() @@ -29,42 +99,25 @@ func TestList(t *testing.T) { for _, tc := range []struct { name string - main []string + cmd command.List expRes bool expErr bool }{ { name: "empty", - main: []string{}, - expRes: true, - }, - { - name: "list", - main: []string{"list"}, expRes: true, }, { name: "empty list", - main: []string{"list", "recur"}, - }, - { - name: "wrong", - main: []string{"delete"}, - expErr: true, + cmd: command.List{ + Args: command.ListArgs{ + HasRecurrer: true, + }, + }, }, } { t.Run(tc.name, func(t *testing.T) { - // parse - cmd, actErr := command.NewListArgs().Parse(tc.main, nil) - if tc.expErr != (actErr != nil) { - t.Errorf("exp %v, got %v", tc.expErr, actErr) - } - if tc.expErr { - return - } - - // do - res, err := cmd.Do(command.Dependencies{ + res, err := tc.cmd.Do(command.Dependencies{ TaskRepo: taskRepo, LocalIDRepo: localRepo, }) @@ -72,7 +125,6 @@ func TestList(t *testing.T) { t.Errorf("exp nil, got %v", err) } - // check listRes := res.(command.ListResult) actRes := len(listRes.Tasks) > 0 if tc.expRes != actRes { diff --git a/plan/command/show.go b/plan/command/show.go index ed7af02..23c86d0 100644 --- a/plan/command/show.go +++ b/plan/command/show.go @@ -38,7 +38,7 @@ type Show struct { args ShowArgs } -func (s *Show) Do(deps Dependencies) (CommandResult, error) { +func (s Show) Do(deps Dependencies) (CommandResult, error) { id, err := deps.LocalIDRepo.FindOne(s.args.localID) switch { case errors.Is(err, storage.ErrNotFound): diff --git a/plan/command/sync.go b/plan/command/sync.go index 1f0a0f7..742e431 100644 --- a/plan/command/sync.go +++ b/plan/command/sync.go @@ -25,7 +25,7 @@ func (sa SyncArgs) Parse(main []string, flags map[string]string) (Command, error type Sync struct{} -func (s *Sync) Do(deps Dependencies) (CommandResult, error) { +func (s Sync) Do(deps Dependencies) (CommandResult, error) { // local new and updated sendItems, err := deps.SyncRepo.FindAll() if err != nil { diff --git a/plan/command/update.go b/plan/command/update.go index 50f8e30..830b19d 100644 --- a/plan/command/update.go +++ b/plan/command/update.go @@ -90,7 +90,7 @@ type Update struct { args UpdateArgs } -func (u *Update) Do(deps Dependencies) (CommandResult, error) { +func (u Update) Do(deps Dependencies) (CommandResult, error) { id, err := deps.LocalIDRepo.FindOne(u.args.LocalID) switch { case errors.Is(err, storage.ErrNotFound): diff --git a/plan/storage/memory/task_test.go b/plan/storage/memory/task_test.go index 7fac228..5e28491 100644 --- a/plan/storage/memory/task_test.go +++ b/plan/storage/memory/task_test.go @@ -55,9 +55,9 @@ func TestTask(t *testing.T) { t.Errorf("(exp -, got +)\n%s", diff) } - t.Log("fond some") + t.Log("find some") actTasks, actErr = mem.FindMany(storage.TaskListParams{ - Date: item.NewDate(2024, 12, 29), + From: item.NewDate(2024, 12, 29), }) if actErr != nil { t.Errorf("exp nil, got %v", actErr) diff --git a/plan/storage/sqlite/task.go b/plan/storage/sqlite/task.go index b7250d3..debf2fc 100644 --- a/plan/storage/sqlite/task.go +++ b/plan/storage/sqlite/task.go @@ -69,16 +69,16 @@ func (t *SqliteTask) FindMany(params storage.TaskListParams) ([]item.Task, error args := []interface{}{} where := []string{`recurrer = ''`} - if params.Recurrer { + if params.HasRecurrer { where[0] = `recurrer != ''` } - if !params.Date.IsZero() && !params.IncludeBefore { - where = append(where, `date = ?`) - args = append(args, params.Date.String()) + if !params.From.IsZero() { + where = append(where, `date >= ?`) + args = append(args, params.From.String()) } - if !params.Date.IsZero() && params.IncludeBefore { + if !params.To.IsZero() { where = append(where, `date <= ?`) - args = append(args, params.Date.String()) + args = append(args, params.To.String()) } if params.Project != "" { where = append(where, `project = ?`) diff --git a/plan/storage/storage.go b/plan/storage/storage.go index caec98b..ff8201a 100644 --- a/plan/storage/storage.go +++ b/plan/storage/storage.go @@ -29,10 +29,11 @@ type Sync interface { } type TaskListParams struct { - Recurrer bool - Date item.Date - IncludeBefore bool - Project string + HasRecurrer bool + HasDate bool + From item.Date + To item.Date + Project string } type Task interface { @@ -43,16 +44,17 @@ type Task interface { } func Match(tsk item.Task, params TaskListParams) bool { - if params.Recurrer && tsk.Recurrer == nil { + if params.HasRecurrer && tsk.Recurrer == nil { return false } - if !params.Date.IsZero() { - if !params.IncludeBefore && !params.Date.Equal(tsk.Date) { - return false - } - if params.IncludeBefore && tsk.Date.After(params.Date) { - return false - } + if params.HasDate && tsk.Date.IsZero() { + return false + } + if !params.From.IsZero() && params.From.After(tsk.Date) { + return false + } + if !params.To.IsZero() && tsk.Date.After(params.To) { + return false } if params.Project != "" && params.Project != tsk.Project { return false diff --git a/plan/storage/storage_test.go b/plan/storage/storage_test.go index 54bf19e..7ed78ae 100644 --- a/plan/storage/storage_test.go +++ b/plan/storage/storage_test.go @@ -21,7 +21,7 @@ func TestMatch(t *testing.T) { } tskNotMatch := item.Task{ ID: "id", - Date: item.NewDate(2024, 12, 28), + Date: item.NewDate(2024, 12, 20), TaskBody: item.TaskBody{ Title: "name", Project: "p2", @@ -33,15 +33,22 @@ func TestMatch(t *testing.T) { params storage.TaskListParams }{ { - name: "date", + name: "from", params: storage.TaskListParams{ - Date: item.NewDate(2024, 12, 29), + From: item.NewDate(2024, 12, 29), + }, + }, + { + name: "to", + params: storage.TaskListParams{ + From: item.NewDate(2024, 12, 24), + To: item.NewDate(2024, 12, 29), }, }, { name: "recurrer", params: storage.TaskListParams{ - Recurrer: true, + HasRecurrer: true, }, }, {