diff options
Diffstat (limited to 'internal/ui/helpers_test.go')
| -rw-r--r-- | internal/ui/helpers_test.go | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/internal/ui/helpers_test.go b/internal/ui/helpers_test.go new file mode 100644 index 0000000..9ba620c --- /dev/null +++ b/internal/ui/helpers_test.go @@ -0,0 +1,363 @@ +package ui + +import ( + "testing" + "time" +) + +func TestParseTaskDate(t *testing.T) { + tests := []struct { + name string + input string + wantErr bool + }{ + { + name: "valid date", + input: "20250627T150405Z", + wantErr: false, + }, + { + name: "empty string", + input: "", + wantErr: true, + }, + { + name: "invalid format", + input: "2025-06-27", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := parseTaskDate(tt.input) + if (err != nil) != tt.wantErr { + t.Errorf("parseTaskDate() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestFormatDueText(t *testing.T) { + now := time.Now() + tests := []struct { + name string + input string + expected string + }{ + { + name: "empty", + input: "", + expected: "", + }, + { + name: "today", + input: now.UTC().Format("20060102T150405Z"), + expected: "today", + }, + { + name: "tomorrow", + input: now.Add(24 * time.Hour).UTC().Format("20060102T150405Z"), + expected: "tomorrow", + }, + { + name: "yesterday", + input: now.Add(-24 * time.Hour).UTC().Format("20060102T150405Z"), + expected: "yesterday", + }, + { + name: "future", + input: now.Add(5 * 24 * time.Hour).UTC().Format("20060102T150405Z"), + expected: "5d", + }, + { + name: "past", + input: now.Add(-3 * 24 * time.Hour).UTC().Format("20060102T150405Z"), + expected: "-3d", + }, + { + name: "invalid", + input: "invalid", + expected: "invalid", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := formatDueText(tt.input) + if got != tt.expected { + t.Errorf("formatDueText() = %v, want %v", got, tt.expected) + } + }) + } +} + +func TestValidateTagName(t *testing.T) { + tests := []struct { + name string + tag string + wantErr bool + }{ + { + name: "valid tag", + tag: "work", + wantErr: false, + }, + { + name: "valid with plus", + tag: "+work", + wantErr: false, + }, + { + name: "valid with minus", + tag: "-work", + wantErr: false, + }, + { + name: "empty tag", + tag: "", + wantErr: true, + }, + { + name: "tag with space", + tag: "my tag", + wantErr: true, + }, + { + name: "tag with tab", + tag: "my\ttag", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := validateTagName(tt.tag) + if (err != nil) != tt.wantErr { + t.Errorf("validateTagName() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestValidatePriority(t *testing.T) { + tests := []struct { + name string + priority string + wantErr bool + }{ + { + name: "high", + priority: "H", + wantErr: false, + }, + { + name: "medium", + priority: "M", + wantErr: false, + }, + { + name: "low", + priority: "L", + wantErr: false, + }, + { + name: "empty", + priority: "", + wantErr: false, + }, + { + name: "invalid", + priority: "X", + wantErr: true, + }, + { + name: "lowercase", + priority: "h", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := validatePriority(tt.priority) + if (err != nil) != tt.wantErr { + t.Errorf("validatePriority() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestValidateDescription(t *testing.T) { + tests := []struct { + name string + desc string + wantErr bool + }{ + { + name: "valid description", + desc: "Fix the bug", + wantErr: false, + }, + { + name: "empty description", + desc: "", + wantErr: true, + }, + { + name: "whitespace only", + desc: " ", + wantErr: true, + }, + { + name: "description with whitespace", + desc: " Fix the bug ", + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := validateDescription(tt.desc) + if (err != nil) != tt.wantErr { + t.Errorf("validateDescription() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestValidateDueDate(t *testing.T) { + tests := []struct { + name string + due string + wantErr bool + }{ + { + name: "empty", + due: "", + wantErr: false, + }, + { + name: "ISO date", + due: "2025-06-27", + wantErr: false, + }, + { + name: "ISO datetime", + due: "2025-06-27T15:04:05", + wantErr: false, + }, + { + name: "ISO datetime with Z", + due: "2025-06-27T15:04:05Z", + wantErr: false, + }, + { + name: "taskwarrior format", + due: "20250627T150405Z", + wantErr: false, + }, + { + name: "relative - today", + due: "today", + wantErr: false, + }, + { + name: "relative - tomorrow", + due: "tomorrow", + wantErr: false, + }, + { + name: "relative - monday", + due: "monday", + wantErr: false, + }, + { + name: "relative - eod", + due: "eod", + wantErr: false, + }, + { + name: "relative - tomorrow+2d", + due: "tomorrow+2d", + wantErr: false, + }, + { + name: "invalid format", + due: "27/06/2025", + wantErr: true, + }, + { + name: "invalid relative", + due: "someday", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := validateDueDate(tt.due) + if (err != nil) != tt.wantErr { + t.Errorf("validateDueDate() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestValidateRecurrence(t *testing.T) { + tests := []struct { + name string + recur string + wantErr bool + }{ + { + name: "empty", + recur: "", + wantErr: false, + }, + { + name: "daily", + recur: "daily", + wantErr: false, + }, + { + name: "weekly", + recur: "weekly", + wantErr: false, + }, + { + name: "3 days", + recur: "3d", + wantErr: false, + }, + { + name: "2 weeks", + recur: "2w", + wantErr: false, + }, + { + name: "1 month", + recur: "1m", + wantErr: false, + }, + { + name: "too short", + recur: "d", + wantErr: true, + }, + { + name: "single char", + recur: "x", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := validateRecurrence(tt.recur) + if (err != nil) != tt.wantErr { + t.Errorf("validateRecurrence() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +}
\ No newline at end of file |
