diff options
| author | Grant Ammons <gammons@gmail.com> | 2016-04-30 08:45:49 -0400 |
|---|---|---|
| committer | Grant Ammons <gammons@gmail.com> | 2016-04-30 08:45:49 -0400 |
| commit | ef9427646b9464d1f8c376f75741e737117a1a83 (patch) | |
| tree | ba3912135e071cd2c7b77e746126cc5eae67ccfb | |
| parent | 695c60e3f58d831e4b05aa35114adff7e1c46d23 (diff) | |
Handle parsing dates, and printing them
| -rw-r--r-- | todolist/formatter.go | 61 | ||||
| -rw-r--r-- | todolist/parser.go | 73 | ||||
| -rw-r--r-- | todolist/parser_test.go | 58 | ||||
| -rw-r--r-- | todolist/todo_item.go | 17 |
4 files changed, 166 insertions, 43 deletions
diff --git a/todolist/formatter.go b/todolist/formatter.go index 77006e0..60517f1 100644 --- a/todolist/formatter.go +++ b/todolist/formatter.go @@ -7,6 +7,7 @@ import ( "strconv" "strings" "text/tabwriter" + "time" "github.com/fatih/color" ) @@ -24,23 +25,71 @@ func NewFormatter(todos *GroupedTodos) *Formatter { } func (f *Formatter) Print() { - 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)) + f.printTodo(todo) } } f.Writer.Flush() } +func (f *Formatter) printTodo(todo Todo) { + yellow := color.New(color.FgYellow).SprintFunc() + fmt.Fprintf(f.Writer, " \t%s\t%s\t%s\t%s\t\n", + yellow(strconv.Itoa(todo.Id)), + f.formatCompleted(todo.Completed), + f.formatDue(todo.Due), + f.formatSubject(todo.Subject)) +} + +func (f *Formatter) formatDue(due string) string { + if due == "" { + return "" + } + dueTime, err := time.Parse("2006-01-02", due) + + if err != nil { + panic(err) + } + + blue := color.New(color.FgBlue).SprintFunc() + red := color.New(color.FgRed).SprintFunc() + + if isToday(dueTime) { + return blue("today") + } else if isTomorrow(dueTime) { + return blue("tomorrow") + } else if isPastDue(dueTime) { + return red(dueTime.Format("Mon Jan 2")) + } else { + return blue(dueTime.Format("Mon Jan 2")) + } +} + +func isToday(t time.Time) bool { + nowYear, nowMonth, nowDay := time.Now().Date() + timeYear, timeMonth, timeDay := t.Date() + return nowYear == timeYear && + nowMonth == timeMonth && + nowDay == timeDay +} + +func isTomorrow(t time.Time) bool { + nowYear, nowMonth, nowDay := time.Now().AddDate(0, 0, 1).Date() + timeYear, timeMonth, timeDay := t.Date() + return nowYear == timeYear && + nowMonth == timeMonth && + nowDay == timeDay +} + +func isPastDue(t time.Time) bool { + return time.Now().After(t) +} + func (f *Formatter) formatSubject(subject string) string { red := color.New(color.FgRed).SprintFunc() magenta := color.New(color.FgMagenta).SprintFunc() diff --git a/todolist/parser.go b/todolist/parser.go index 1e98d33..a857f16 100644 --- a/todolist/parser.go +++ b/todolist/parser.go @@ -17,7 +17,7 @@ func (p *Parser) ParseNewTodo(input string) *Todo { todo.Projects = p.Projects(input) todo.Contexts = p.Contexts(input) if p.hasDue(input) { - todo.FormattedDue = p.Due(input) + todo.Due = p.Due(input, time.Now()) } return todo } @@ -49,31 +49,78 @@ func (p *Parser) hasDue(input string) bool { return r.MatchString(input) } -func (p *Parser) Due(input string) time.Time { +func (p *Parser) Due(input string, day time.Time) string { r, _ := regexp.Compile(`due .*$`) res := r.FindString(input) res = res[4:len(res)] switch { case res == "today": - return now.BeginningOfDay() + return now.BeginningOfDay().Format("2006-01-02") case res == "tomorrow" || res == "tom": - return now.BeginningOfDay().AddDate(0, 0, 1) + return now.BeginningOfDay().AddDate(0, 0, 1).Format("2006-01-02") case res == "monday" || res == "mon": - n := now.BeginningOfDay() - return now.New(n).Monday().AddDate(0, 0, 7) + return p.monday(day) case res == "tuesday" || res == "tue": - n := now.BeginningOfDay() - return now.New(n).Monday().AddDate(0, 0, 1) + return p.tuesday(day) case res == "wednesday" || res == "wed": - n := now.BeginningOfDay() - return now.New(n).Monday().AddDate(0, 0, 2) + return p.wednesday(day) + case res == "thursday" || res == "thu": + return p.thursday(day) + case res == "friday" || res == "fri": + return p.friday(day) + case res == "saturday" || res == "sat": + return p.saturday(day) + case res == "sunday" || res == "sun": + return p.sunday(day) case res == "next week": n := now.BeginningOfDay() - return now.New(n).Monday().AddDate(0, 0, 7) + return now.New(n).Monday().AddDate(0, 0, 7).Format("2006-01-02") + } + return time.Now().Format("2006-01-02") +} + +func (p *Parser) monday(day time.Time) string { + mon := now.New(day).Monday() + return p.thisOrNextWeek(mon, day) +} + +func (p *Parser) tuesday(day time.Time) string { + tue := now.New(day).Monday().AddDate(0, 0, 1) + return p.thisOrNextWeek(tue, day) +} + +func (p *Parser) wednesday(day time.Time) string { + tue := now.New(day).Monday().AddDate(0, 0, 2) + return p.thisOrNextWeek(tue, day) +} + +func (p *Parser) thursday(day time.Time) string { + tue := now.New(day).Monday().AddDate(0, 0, 3) + return p.thisOrNextWeek(tue, day) +} + +func (p *Parser) friday(day time.Time) string { + tue := now.New(day).Monday().AddDate(0, 0, 4) + return p.thisOrNextWeek(tue, day) +} + +func (p *Parser) saturday(day time.Time) string { + tue := now.New(day).Monday().AddDate(0, 0, 5) + return p.thisOrNextWeek(tue, day) +} + +func (p *Parser) sunday(day time.Time) string { + tue := now.New(day).Monday().AddDate(0, 0, 6) + return p.thisOrNextWeek(tue, day) +} + +func (p *Parser) thisOrNextWeek(day time.Time, pivotDay time.Time) string { + if day.Before(pivotDay) { + return day.AddDate(0, 0, 7).Format("2006-01-02") + } else { + return day.Format("2006-01-02") } - //return now.Parse(input) - return time.Now() } func (p *Parser) matchWords(input string, r *regexp.Regexp) []string { diff --git a/todolist/parser_test.go b/todolist/parser_test.go index 1ab2826..9a2732c 100644 --- a/todolist/parser_test.go +++ b/todolist/parser_test.go @@ -6,11 +6,12 @@ import ( "time" "github.com/jinzhu/now" + "github.com/stretchr/testify/assert" ) func TestParseSubject(t *testing.T) { parser := &Parser{} - todo := parser.Parse("do this thing") + todo := parser.ParseNewTodo("do this thing") if todo.Subject != "do this thing" { t.Error("Expected todo.Subject to equal 'do this thing'") } @@ -18,7 +19,7 @@ func TestParseSubject(t *testing.T) { func TestParseSubjectWithDue(t *testing.T) { parser := &Parser{} - todo := parser.Parse("do this thing due tomorrow") + todo := parser.ParseNewTodo("do this thing due tomorrow") if todo.Subject != "do this thing" { t.Error("Expected todo.Subject to equal 'do this thing', got ", todo.Subject) } @@ -26,7 +27,7 @@ func TestParseSubjectWithDue(t *testing.T) { func TestParseProjects(t *testing.T) { parser := &Parser{} - todo := parser.Parse("do this thing +proj1 +proj2 due tomorrow") + todo := parser.ParseNewTodo("do this thing +proj1 +proj2 due tomorrow") if len(todo.Projects) != 2 { t.Error("Expected Projects length to be 2") } @@ -40,7 +41,7 @@ func TestParseProjects(t *testing.T) { func TestParseContexts(t *testing.T) { parser := &Parser{} - todo := parser.Parse("do this thing with @bob and @mary due tomorrow") + todo := parser.ParseNewTodo("do this thing with @bob and @mary due tomorrow") if len(todo.Contexts) != 2 { t.Error("Expected Projects length to be 2") } @@ -54,20 +55,55 @@ func TestParseContexts(t *testing.T) { func TestDueToday(t *testing.T) { parser := &Parser{} - todo := parser.Parse("do this thing with @bob and @mary due today") - if todo.FormattedDue != now.BeginningOfDay() { + todo := parser.ParseNewTodo("do this thing with @bob and @mary due today") + if todo.Due != now.BeginningOfDay().Format("2006-01-02") { fmt.Println("Date is different", todo.Due, time.Now()) } } func TestDueTomorrow(t *testing.T) { parser := &Parser{} - todo := parser.Parse("do this thing with @bob and @mary due tomorrow") - if todo.FormattedDue != now.BeginningOfDay().AddDate(0, 0, 1) { + todo := parser.ParseNewTodo("do this thing with @bob and @mary due tomorrow") + if todo.Due != now.BeginningOfDay().AddDate(0, 0, 1).Format("2006-01-02") { fmt.Println("Date is different", todo.Due, time.Now()) } } +func TestMondayOnSunday(t *testing.T) { + assert := assert.New(t) + parser := &Parser{} + now, _ := time.Parse("2006-01-02", "2016-04-24") + assert.Equal("2016-04-25", parser.monday(now)) +} + +func TestMondayOnMonday(t *testing.T) { + assert := assert.New(t) + parser := &Parser{} + now, _ := time.Parse("2006-01-02", "2016-04-25") + assert.Equal("2016-04-25", parser.monday(now)) +} + +func TestMondayOnTuesday(t *testing.T) { + assert := assert.New(t) + parser := &Parser{} + now, _ := time.Parse("2006-01-02", "2016-04-26") + assert.Equal("2016-05-02", parser.monday(now)) +} + +func TestTuesdayOnMonday(t *testing.T) { + assert := assert.New(t) + parser := &Parser{} + now, _ := time.Parse("2006-01-02", "2016-04-25") + assert.Equal("2016-04-26", parser.tuesday(now)) +} + +func TestTuesdayOnWednesday(t *testing.T) { + assert := assert.New(t) + parser := &Parser{} + now, _ := time.Parse("2006-01-02", "2016-04-27") + assert.Equal("2016-05-03", parser.tuesday(now)) +} + //func TestDueNextWeek(t *testing.T) { // parser := &Parser{} // @@ -75,9 +111,3 @@ func TestDueTomorrow(t *testing.T) { // todo := parser.Parse("do this thing with @bob and @mary due next week") // fmt.Println(todo.Due) //} - -func TestDueMonday(t *testing.T) { - parser := &Parser{} - todo := parser.Parse("do this thing with @bob and @mary due mon") - fmt.Println(todo.Due) -} diff --git a/todolist/todo_item.go b/todolist/todo_item.go index 0b6eeac..cc06615 100644 --- a/todolist/todo_item.go +++ b/todolist/todo_item.go @@ -1,16 +1,13 @@ package todolist -import "time" - type Todo struct { - Id int `json:"id"` - Subject string `json:"subject"` - Projects []string `json:"projects"` - Contexts []string `json:"contexts"` - Due string `json:"due"` - FormattedDue time.Time `json:"-"` - Completed bool `json:"completed"` - Archived bool `json:"archived"` + Id int `json:"id"` + Subject string `json:"subject"` + Projects []string `json:"projects"` + Contexts []string `json:"contexts"` + Due string `json:"due"` + Completed bool `json:"completed"` + Archived bool `json:"archived"` } func NewTodo() *Todo { |
