diff --git a/eisenhower.go b/eisenhower.go index 6603ca1fdc22c9394e0f9bad3466371db84582e9..d2838d44ab3751ac76cab5eeda7bfca10c4678a0 100644 --- a/eisenhower.go +++ b/eisenhower.go @@ -4,7 +4,11 @@ package lunatask -import "fmt" +import ( + "errors" + "fmt" + "strings" +) // Eisenhower represents a quadrant in the Eisenhower priority matrix, which // categorizes tasks by whether they are urgent (time-sensitive) and/or @@ -77,3 +81,29 @@ func (e Eisenhower) IsUrgent() bool { func (e Eisenhower) IsImportant() bool { return e == EisenhowerDoNow || e == EisenhowerDoLater } + +// Errors returned by Eisenhower operations. +var ( + // ErrInvalidEisenhower is returned when parsing an unknown Eisenhower quadrant string. + ErrInvalidEisenhower = errors.New("invalid eisenhower quadrant") +) + +// ParseEisenhower parses a string to an Eisenhower quadrant value (case-insensitive). +// Valid values: "uncategorized", "do-now", "delegate", "do-later", "eliminate", +// as well as numeric strings "0" through "4". +func ParseEisenhower(str string) (Eisenhower, error) { + switch strings.ToLower(str) { + case "uncategorized", "0": + return EisenhowerUncategorized, nil + case "do-now", "donow", "1": + return EisenhowerDoNow, nil + case "delegate", "2": + return EisenhowerDelegate, nil + case "do-later", "dolater", "3": + return EisenhowerDoLater, nil + case "eliminate", "4": + return EisenhowerEliminate, nil + default: + return 0, fmt.Errorf("%w: %q", ErrInvalidEisenhower, str) + } +} diff --git a/eisenhower_test.go b/eisenhower_test.go index 008b571f0c890aded15be9d2d7143dd0343c83ac..59f8d291a5ed83f897d91a381195d2ecdb0cfc89 100644 --- a/eisenhower_test.go +++ b/eisenhower_test.go @@ -5,6 +5,7 @@ package lunatask_test import ( + "errors" "testing" lunatask "git.secluded.site/go-lunatask" @@ -378,3 +379,71 @@ func TestTaskUpdateBuilder_WithEisenhowerTyped(t *testing.T) { assertBodyFieldFloat(t, capture.Body, "eisenhower", 2) } + +// --- ParseEisenhower --- + +func TestParseEisenhower(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + input string + want lunatask.Eisenhower + wantErr bool + }{ + // Text values + {"uncategorized_lower", "uncategorized", lunatask.EisenhowerUncategorized, false}, + {"uncategorized_upper", "UNCATEGORIZED", lunatask.EisenhowerUncategorized, false}, + {"do_now_lower", "do-now", lunatask.EisenhowerDoNow, false}, + {"do_now_upper", "DO-NOW", lunatask.EisenhowerDoNow, false}, + {"donow_lower", "donow", lunatask.EisenhowerDoNow, false}, + {"donow_upper", "DONOW", lunatask.EisenhowerDoNow, false}, + {"delegate_lower", "delegate", lunatask.EisenhowerDelegate, false}, + {"delegate_upper", "DELEGATE", lunatask.EisenhowerDelegate, false}, + {"do_later_lower", "do-later", lunatask.EisenhowerDoLater, false}, + {"do_later_upper", "DO-LATER", lunatask.EisenhowerDoLater, false}, + {"dolater_lower", "dolater", lunatask.EisenhowerDoLater, false}, + {"dolater_upper", "DOLATER", lunatask.EisenhowerDoLater, false}, + {"eliminate_lower", "eliminate", lunatask.EisenhowerEliminate, false}, + {"eliminate_upper", "ELIMINATE", lunatask.EisenhowerEliminate, false}, + + // Numeric values + {"zero", "0", lunatask.EisenhowerUncategorized, false}, + {"one", "1", lunatask.EisenhowerDoNow, false}, + {"two", "2", lunatask.EisenhowerDelegate, false}, + {"three", "3", lunatask.EisenhowerDoLater, false}, + {"four", "4", lunatask.EisenhowerEliminate, false}, + + // Invalid values + {"invalid", "invalid", 0, true}, + {"empty", "", 0, true}, + {"five", "5", 0, true}, + {"negative", "-1", 0, true}, + {"typo", "elimate", 0, true}, + } + + for _, testCase := range tests { + t.Run(testCase.name, func(t *testing.T) { + t.Parallel() + + got, err := lunatask.ParseEisenhower(testCase.input) + if (err != nil) != testCase.wantErr { + t.Errorf("ParseEisenhower(%q) error = %v, wantErr %v", testCase.input, err, testCase.wantErr) + + return + } + + if testCase.wantErr { + if !errors.Is(err, lunatask.ErrInvalidEisenhower) { + t.Errorf("ParseEisenhower(%q) error = %v, want ErrInvalidEisenhower", testCase.input, err) + } + + return + } + + if got != testCase.want { + t.Errorf("ParseEisenhower(%q) = %v, want %v", testCase.input, got, testCase.want) + } + }) + } +}