From a716a04c831e4fb23cdd558756d8f393e4ef8d73 Mon Sep 17 00:00:00 2001 From: Quey-Liang Kao Date: Tue, 29 Aug 2017 17:00:18 +0800 Subject: Refactor previous commits Rewrite the `ManipulateNotes` function into `HandleNotes`, which routes the note sub-commands to calls of newly-written `Parse*Note` functions. On successful parse, these functions return true, and false otherwise. Related tests are also refined. --- todo.go | 2 +- todolist/app.go | 26 +++++++++----- todolist/parser.go | 95 +++++++++++++++++++++++++++---------------------- todolist/parser_test.go | 72 ++++++++++++++++++++++++++++++++++--- 4 files changed, 139 insertions(+), 56 deletions(-) diff --git a/todo.go b/todo.go index d2bc7ab..645a880 100644 --- a/todo.go +++ b/todo.go @@ -166,7 +166,7 @@ func routeInput(command string, input string) { case "ex", "expand": app.ExpandTodo(input) case "an", "n", "dn", "en": - app.ManipulateNotes(input) + app.HandleNotes(input) case "gc": app.GarbageCollect() case "p", "prioritize": diff --git a/todolist/app.go b/todolist/app.go index 79e3aad..92ee64d 100644 --- a/todolist/app.go +++ b/todolist/app.go @@ -137,23 +137,33 @@ func (a *App) ExpandTodo(input string) { fmt.Println("Todo expanded.") } -func (a *App) ManipulateNotes(input string) { +func (a *App) HandleNotes(input string) { a.Load() id := a.getId(input) - parser := &Parser{} + if id == -1 { + return + } todo := a.TodoList.FindById(id) if todo == nil { fmt.Println("No such id.") return } + parser := &Parser{} - retStr := parser.ParseNotes(todo, input) - if retStr != "" { - a.Save() - if retStr != "list" { - fmt.Println("Notes " + retStr + "ed.") - } + 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() { diff --git a/todolist/parser.go b/todolist/parser.go index 8f5e180..6ad8007 100644 --- a/todolist/parser.go +++ b/todolist/parser.go @@ -83,57 +83,66 @@ func (p *Parser) Contexts(input string) []string { return p.matchWords(input, r) } -func (p *Parser) ParseNotes(todo *Todo, input string) string { - r, _ := regexp.Compile(`(\w+) \d+\s*(.*)?`) +func (p *Parser) ParseAddNote(todo *Todo, input string) bool { + r, _ := regexp.Compile(`^an\s+\d+\s+(.*)`) matches := r.FindStringSubmatch(input) - switch matches[1] { - case "an": - todo.Notes = append(todo.Notes, matches[2]) - return "add" - - case "n": - groups := map[string][]*Todo{} - groups[""] = append(groups[""], todo) - formatter := NewFormatter(&GroupedTodos{Groups: groups}) - formatter.Print(true) - return "list" - - case "dn": - rmid, err := p.getNoteID(matches[2]) - if err != nil { - return "" - } + if len(matches) != 2 { + return false + } - for id, _ := range todo.Notes { - if id == rmid { - todo.Notes = append(todo.Notes[:rmid], todo.Notes[rmid+1:]...) - return "delete" - } - } - fmt.Println("Could not found note id") - return "" + todo.Notes = append(todo.Notes, matches[1]) + return true +} - case "en": - r1, _ := regexp.Compile(`(\d)+\s+(.*)?`) - tail := r1.FindStringSubmatch(matches[2]) - edid, err := p.getNoteID(tail[1]) - if err != nil { - return "" - } +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 == edid { - todo.Notes[id] = tail[2] - return "edit" - } + for id, _ := range todo.Notes { + if id == rmid { + todo.Notes = append(todo.Notes[:rmid], todo.Notes[rmid+1:]...) + return true } + } + return false +} - fmt.Println("Could not found note id") - return "" +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 } - fmt.Println("Could not match command or id") - return "" + 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) { diff --git a/todolist/parser_test.go b/todolist/parser_test.go index 2c4fd25..313ad9f 100644 --- a/todolist/parser_test.go +++ b/todolist/parser_test.go @@ -74,25 +74,89 @@ func TestParseContexts(t *testing.T) { } } -func TestParseNotes(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.ParseNotes(todo, "an 1 www.google.com") != "add" { + 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.ParseNotes(todo, "en 1 0 www.duckduckgo.com") != "edit" { + 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.ParseNotes(todo, "dn 1 0") != "delete" { + if !parser.ParseDeleteNote(todo, "dn 1 0") { t.Error("Expected Notes to be deleted") } if len(todo.Notes) != 0 { -- cgit v1.3