diff options
| author | Grant Ammons <gammons@gmail.com> | 2016-04-25 14:35:43 -0400 |
|---|---|---|
| committer | Grant Ammons <gammons@gmail.com> | 2016-04-25 14:35:43 -0400 |
| commit | a0f7203996439210b2a40663eeeeb8563ab03d68 (patch) | |
| tree | 84f7bd055f5cc581fa2b4894206868c998512d1a | |
| parent | dde4f5330c2126af0e3ec17e4098653c6f551426 (diff) | |
Get grouping working correctly
| -rw-r--r-- | todo.go | 7 | ||||
| -rw-r--r-- | todolist/app.go | 24 | ||||
| -rw-r--r-- | todolist/formatter.go | 26 | ||||
| -rw-r--r-- | todolist/grouper.go | 63 | ||||
| -rw-r--r-- | todolist/grouper_test.go | 32 | ||||
| -rw-r--r-- | todolist/todos.json | 2 |
6 files changed, 138 insertions, 16 deletions
@@ -13,19 +13,18 @@ func main() { usage() os.Exit(0) } - routeInput(os.Args[1]) + input := strings.Join(os.Args[1:], " ") + routeInput(os.Args[1], input) } func usage() { fmt.Println("usage") } -func routeInput(command string) { +func routeInput(command string, input string) { app := todolist.NewApp() - input := strings.Join(os.Args[1:], " ") switch { case command == "l" || command == "list": app.ListTodos(input) } - } diff --git a/todolist/app.go b/todolist/app.go index 3235f99..6122b6a 100644 --- a/todolist/app.go +++ b/todolist/app.go @@ -1,5 +1,7 @@ package todolist +import "regexp" + type App struct { TodoStore Store } @@ -11,6 +13,26 @@ func NewApp() *App { } func (a *App) ListTodos(input string) { - formatter := NewFormatter(a.TodoStore.Todos()) + + grouped := a.getGroups(input) + + formatter := NewFormatter(grouped) formatter.Print() } + +func (a *App) getGroups(input string) *GroupedTodos { + grouper := &Grouper{} + contextRegex, _ := regexp.Compile(`by c.*$`) + projectRegex, _ := regexp.Compile(`by p.*$`) + + var grouped *GroupedTodos + + if contextRegex.MatchString(input) { + grouped = grouper.GroupByContext(a.TodoStore.Todos()) + } else if projectRegex.MatchString(input) { + grouped = grouper.GroupByContext(a.TodoStore.Todos()) + } else { + grouped = grouper.GroupByNothing(a.TodoStore.Todos()) + } + return grouped +} diff --git a/todolist/formatter.go b/todolist/formatter.go index b2b9816..77006e0 100644 --- a/todolist/formatter.go +++ b/todolist/formatter.go @@ -12,25 +12,31 @@ import ( ) type Formatter struct { - Todos []Todo - Writer *tabwriter.Writer + GroupedTodos *GroupedTodos + Writer *tabwriter.Writer } -func NewFormatter(todos []Todo) *Formatter { +func NewFormatter(todos *GroupedTodos) *Formatter { w := new(tabwriter.Writer) w.Init(os.Stdout, 0, 8, 0, '\t', 0) - formatter := &Formatter{Todos: todos, Writer: w} + formatter := &Formatter{GroupedTodos: todos, Writer: w} return formatter } func (f *Formatter) Print() { - for _, todo := range f.Todos { - yellow := color.New(color.FgYellow).SprintFunc() + yellow := color.New(color.FgYellow).SprintFunc() + cyan := color.New(color.FgCyan).SprintFunc() + + for key, todos := range f.GroupedTodos.Groups { + fmt.Fprintf(f.Writer, "\n \t%s\n", cyan(key)) + + for _, todo := range todos { + fmt.Fprintf(f.Writer, " \t%s\t%s\t%s\t\n", + yellow(strconv.Itoa(todo.Id)), + f.formatCompleted(todo.Completed), + f.formatSubject(todo.Subject)) + } - fmt.Fprintf(f.Writer, " \t%s\t%s\t%s\t\n", - yellow(strconv.Itoa(todo.Id)), - f.formatCompleted(todo.Completed), - f.formatSubject(todo.Subject)) } f.Writer.Flush() } diff --git a/todolist/grouper.go b/todolist/grouper.go new file mode 100644 index 0000000..25547bf --- /dev/null +++ b/todolist/grouper.go @@ -0,0 +1,63 @@ +package todolist + +type Grouper struct{} + +type GroupedTodos struct { + Groups map[string][]Todo +} + +func (g *Grouper) GroupByContext(todos []Todo) *GroupedTodos { + groups := map[string][]Todo{} + + allContexts := []string{} + + for _, todo := range todos { + allContexts = addIfNotThere(allContexts, todo.Contexts) + } + + for _, todo := range todos { + for _, context := range todo.Contexts { + groups[context] = append(groups[context], todo) + } + } + + return &GroupedTodos{Groups: groups} +} + +func (g *Grouper) GroupByProject(todos []Todo) *GroupedTodos { + groups := map[string][]Todo{} + + allProjects := []string{} + + for _, todo := range todos { + allProjects = addIfNotThere(allProjects, todo.Projects) + } + + for _, todo := range todos { + for _, project := range todo.Projects { + groups[project] = append(groups[project], todo) + } + } + return &GroupedTodos{Groups: groups} +} + +func (g *Grouper) GroupByNothing(todos []Todo) *GroupedTodos { + groups := map[string][]Todo{} + groups["all"] = todos + return &GroupedTodos{Groups: groups} +} + +func addIfNotThere(arr []string, items []string) []string { + for _, item := range items { + there := false + for _, arrItem := range arr { + if item == arrItem { + there = true + } + } + if !there { + arr = append(arr, item) + } + } + return arr +} diff --git a/todolist/grouper_test.go b/todolist/grouper_test.go new file mode 100644 index 0000000..0b610f0 --- /dev/null +++ b/todolist/grouper_test.go @@ -0,0 +1,32 @@ +package todolist + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGroupByContext(t *testing.T) { + assert := assert.New(t) + + store := &FileStore{FileLocation: "todos.json"} + store.Load() + + grouper := &Grouper{} + grouped := grouper.GroupByContext(store.Todos()) + + assert.Equal(2, len(grouped.Groups["root"]), "") + assert.Equal(1, len(grouped.Groups["more"]), "") +} + +func TestGroupByProject(t *testing.T) { + assert := assert.New(t) + + store := &FileStore{FileLocation: "todos.json"} + store.Load() + + grouper := &Grouper{} + grouped := grouper.GroupByProject(store.Todos()) + + assert.Equal(2, len(grouped.Groups["test1"]), "") +} diff --git a/todolist/todos.json b/todolist/todos.json index dac8b93..8dc268d 100644 --- a/todolist/todos.json +++ b/todolist/todos.json @@ -1 +1 @@ -[{"subject":"this is the first subject","projects":[],"contexts":["root"],"due":"2016-04-04","completed":true,"id":1,"archived":true},{"subject":" audit userify for 2FA","projects":[],"contexts":[],"due":null,"completed":null,"id":2,"archived":false}] +[{"subject":"this is the first subject","projects":["test1"],"contexts":["root"],"due":"2016-04-04","completed":true,"id":1,"archived":true},{"subject":" audit userify for 2FA","projects":["test1"],"contexts":["root","more"],"due":null,"completed":null,"id":2,"archived":false}] |
