diff options
Diffstat (limited to 'todolist')
| -rw-r--r-- | todolist/app.go | 32 | ||||
| -rw-r--r-- | todolist/filter.go | 4 | ||||
| -rw-r--r-- | todolist/formatter.go | 8 | ||||
| -rw-r--r-- | todolist/parser.go | 71 | ||||
| -rw-r--r-- | todolist/parser_test.go | 90 | ||||
| -rw-r--r-- | todolist/todo_item.go | 1 | ||||
| -rw-r--r-- | todolist/todos.json | 2 |
7 files changed, 203 insertions, 5 deletions
diff --git a/todolist/app.go b/todolist/app.go index f63c41b..92ee64d 100644 --- a/todolist/app.go +++ b/todolist/app.go @@ -137,6 +137,35 @@ func (a *App) ExpandTodo(input string) { fmt.Println("Todo expanded.") } +func (a *App) HandleNotes(input string) { + a.Load() + id := a.getId(input) + if id == -1 { + return + } + todo := a.TodoList.FindById(id) + if todo == nil { + fmt.Println("No such id.") + return + } + parser := &Parser{} + + if parser.ParseAddNote(todo, input) { + fmt.Println("Note added.") + } else if parser.ParseDeleteNote(todo, input) { + fmt.Println("Note deleted.") + } else if parser.ParseEditNote(todo, input) { + fmt.Println("Note edited.") + } else if parser.ParseShowNote(todo, input) { + groups := map[string][]*Todo{} + groups[""] = append(groups[""], todo) + formatter := NewFormatter(&GroupedTodos{Groups: groups}) + formatter.Print(true) + return + } + a.Save() +} + func (a *App) ArchiveCompleted() { a.Load() for _, todo := range a.TodoList.Todos() { @@ -154,7 +183,8 @@ func (a *App) ListTodos(input string) { grouped := a.getGroups(input, filtered) formatter := NewFormatter(grouped) - formatter.Print() + re, _ := regexp.Compile(`^ln`) + formatter.Print(re.MatchString(input)) } func (a *App) PrioritizeTodo(input string) { diff --git a/todolist/filter.go b/todolist/filter.go index dd61d11..88b28a7 100644 --- a/todolist/filter.go +++ b/todolist/filter.go @@ -38,7 +38,7 @@ func (f *TodoFilter) filterArchived(input string) []*Todo { return f.Todos } - r, _ := regexp.Compile(`l archived$`) + r, _ := regexp.Compile(`ln? archived$`) if r.MatchString(input) { return f.getArchived() } else { @@ -47,7 +47,7 @@ func (f *TodoFilter) filterArchived(input string) []*Todo { } func (f *TodoFilter) filterPrioritized(input string) []*Todo { - r, _ := regexp.Compile(`l p`) + r, _ := regexp.Compile(`ln? p`) if r.MatchString(input) { return f.getPrioritized() } else { diff --git a/todolist/formatter.go b/todolist/formatter.go index c0f3313..e7863db 100644 --- a/todolist/formatter.go +++ b/todolist/formatter.go @@ -25,7 +25,7 @@ func NewFormatter(todos *GroupedTodos) *Formatter { return formatter } -func (f *Formatter) Print() { +func (f *Formatter) Print(printNotes bool) { cyan := color.New(color.FgCyan).SprintFunc() var keys []string @@ -38,6 +38,12 @@ func (f *Formatter) Print() { fmt.Fprintf(f.Writer, "\n %s\n", cyan(key)) for _, todo := range f.GroupedTodos.Groups[key] { f.printTodo(todo) + if printNotes { + for nid, note := range todo.Notes { + fmt.Fprintf(f.Writer, " %s\t%s\t\n", + cyan(strconv.Itoa(nid)), note) + } + } } } f.Writer.Flush() diff --git a/todolist/parser.go b/todolist/parser.go index d62c77d..3f700af 100644 --- a/todolist/parser.go +++ b/todolist/parser.go @@ -83,6 +83,77 @@ func (p *Parser) Contexts(input string) []string { return p.matchWords(input, r) } +func (p *Parser) ParseAddNote(todo *Todo, input string) bool { + r, _ := regexp.Compile(`^an\s+\d+\s+(.*)`) + matches := r.FindStringSubmatch(input) + if len(matches) != 2 { + return false + } + + todo.Notes = append(todo.Notes, matches[1]) + return true +} + +func (p *Parser) ParseDeleteNote(todo *Todo, input string) bool { + r, _ := regexp.Compile(`^dn\s+\d+\s+(\d+)`) + matches := r.FindStringSubmatch(input) + if len(matches) != 2 { + return false + } + + rmid, err := p.getNoteID(matches[1]) + if err != nil { + return false + } + + for id, _ := range todo.Notes { + if id == rmid { + todo.Notes = append(todo.Notes[:rmid], todo.Notes[rmid+1:]...) + return true + } + } + return false +} + +func (p *Parser) ParseEditNote(todo *Todo, input string) bool { + r, _ := regexp.Compile(`^en\s+\d+\s+(\d+)\s+(.*)`) + matches := r.FindStringSubmatch(input) + if len(matches) != 3 { + return false + } + + edid, err := p.getNoteID(matches[1]) + if err != nil { + return false + } + + for id, _ := range todo.Notes { + if id == edid { + todo.Notes[id] = matches[2] + return true + } + } + return false +} + +func (p *Parser) ParseShowNote(todo *Todo, input string) bool { + r, _ := regexp.Compile(`^n\s+\d+`) + matches := r.FindStringSubmatch(input) + if len(matches) != 1 { + return false + } + return true +} + +func (p *Parser) getNoteID(input string) (int, error) { + ret, err := strconv.Atoi(input) + if err != nil { + fmt.Println("wrong note id") + return -1, err + } + return ret, nil +} + func (p *Parser) hasDue(input string) bool { r1, _ := regexp.Compile(`due \w+$`) r2, _ := regexp.Compile(`due \w+ \d+$`) diff --git a/todolist/parser_test.go b/todolist/parser_test.go index 476edaa..313ad9f 100644 --- a/todolist/parser_test.go +++ b/todolist/parser_test.go @@ -74,6 +74,96 @@ func TestParseContexts(t *testing.T) { } } +func TestParseAddNote(t *testing.T) { + parser := &Parser{} + todo := parser.ParseNewTodo("add write the test functions") + + b1 := parser.ParseAddNote(todo, "an 1 TestPasrseAddNote") + b2 := parser.ParseAddNote(todo, "an 1 TestPasrseDeleteNote") + b3 := parser.ParseAddNote(todo, "an 1 TestPasrseEditNote") + + if !b1 || !b2 || !b3 { + t.Error("Fail adding notes, expected 3 notes but", len(todo.Notes)) + } +} + +func TestParseDeleteNote(t *testing.T) { + parser := &Parser{} + todo := parser.ParseNewTodo("add buy notebook") + + todo.Notes = append(todo.Notes, "ASUStek") + todo.Notes = append(todo.Notes, "Apple") + todo.Notes = append(todo.Notes, "Dell") + todo.Notes = append(todo.Notes, "Acer") + + b1 := parser.ParseDeleteNote(todo, "dn 1 1") + b2 := parser.ParseDeleteNote(todo, "dn 1 1") + + if !b1 || !b2 { + t.Error("Fail deleting notes, expected 2 notes left but", len(todo.Notes)) + } + + if todo.Notes[0] != "ASUStek" || todo.Notes[1] != "Acer" { + t.Error("Fail deleting notes,", todo.Notes[0], "and", todo.Notes[1], "are left") + } +} + +func TestParseEditNote(t *testing.T) { + parser := &Parser{} + todo := parser.ParseNewTodo("add record the weather") + + todo.Notes = append(todo.Notes, "Aug 29 Wed") + todo.Notes = append(todo.Notes, "Cloudy") + todo.Notes = append(todo.Notes, "40°C") + todo.Notes = append(todo.Notes, "Tokyo") + + parser.ParseEditNote(todo, "en 1 0 Aug 29 Tue") + if todo.Notes[0] != "Aug 29 Tue" { + t.Error("Fail editing notes, note 0 should be \"Aug 29 Tue\" but got", todo.Notes[0]) + } + + parser.ParseEditNote(todo, "en 1 1 Sunny") + if todo.Notes[1] != "Sunny" { + t.Error("Fail editing notes, note 1 should be \"Sunny\" but got", todo.Notes[1]) + } + + parser.ParseEditNote(todo, "en 1 2 22°C") + if todo.Notes[2] != "22°C" { + t.Error("Fail editing notes, note 2 should be \"22°C\" but got", todo.Notes[2]) + } + + parser.ParseEditNote(todo, "en 1 3 Seoul") + if todo.Notes[3] != "Seoul" { + t.Error("Fail editing notes, note 3 should be \"Seoul\" but got", todo.Notes[3]) + } +} + +func TestHandleNotes(t *testing.T) { + parser := &Parser{} + todo := parser.ParseNewTodo("add search engine survey") + + if !parser.ParseAddNote(todo, "an 1 www.google.com") { + t.Error("Expected Notes to be added") + } + if todo.Notes[0] != "www.google.com" { + t.Error("Expected note 1 to be 'www.google.com' but got", todo.Notes[0]) + } + + if !parser.ParseEditNote(todo, "en 1 0 www.duckduckgo.com") { + t.Error("Expected Notes to be editted") + } + if todo.Notes[0] != "www.duckduckgo.com" { + t.Error("Expected note 1 to be 'www.duckduckgo.com' but got", todo.Notes[0]) + } + + if !parser.ParseDeleteNote(todo, "dn 1 0") { + t.Error("Expected Notes to be deleted") + } + if len(todo.Notes) != 0 { + t.Error("Expected no note") + } +} + func TestDueToday(t *testing.T) { assert := assert.New(t) parser := &Parser{} diff --git a/todolist/todo_item.go b/todolist/todo_item.go index 0c30707..5b9bcbc 100644 --- a/todolist/todo_item.go +++ b/todolist/todo_item.go @@ -15,6 +15,7 @@ type Todo struct { CompletedDate string `json:"completedDate"` Archived bool `json:"archived"` IsPriority bool `json:"isPriority"` + Notes []string `json:"notes"` } func NewTodo() *Todo { diff --git a/todolist/todos.json b/todolist/todos.json index 7f511ed..39593be 100644 --- a/todolist/todos.json +++ b/todolist/todos.json @@ -1 +1 @@ -[{"id":1,"subject":"this is the first subject","projects":["test1"],"contexts":["root"],"due":"2016-04-04","completed":false,"completedDate":"","archived":true,"isPriority":false},{"id":2,"subject":" audit userify for 2FA","projects":["test1"],"contexts":["root","more"],"due":"","completed":true,"completedDate":"","archived":false,"isPriority":false}]
\ No newline at end of file +[{"id":1,"subject":"this is the first subject","projects":["test1"],"contexts":["root"],"due":"2016-04-04","completed":false,"completedDate":"","archived":true,"isPriority":false,"notes":null},{"id":2,"subject":" audit userify for 2FA","projects":["test1"],"contexts":["root","more"],"due":"","completed":true,"completedDate":"","archived":false,"isPriority":false,"notes":null}]
\ No newline at end of file |
