diff --git a/motivation.go b/motivation.go new file mode 100644 index 0000000000000000000000000000000000000000..e30e7a4278f64bceed1d49c0b9ae3ca6a6a0b258 --- /dev/null +++ b/motivation.go @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: Amolith +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +package lunatask + +import ( + "errors" + "fmt" + "strings" +) + +// Errors returned by Motivation operations. +var ( + // ErrInvalidMotivation is returned when parsing an unknown motivation string. + ErrInvalidMotivation = errors.New("invalid motivation") +) + +// ParseMotivation parses a string to a Motivation value (case-insensitive). +// Valid values: "unknown", "must", "should", "want". +func ParseMotivation(str string) (Motivation, error) { + switch strings.ToLower(str) { + case "unknown": + return MotivationUnknown, nil + case "must": + return MotivationMust, nil + case "should": + return MotivationShould, nil + case "want": + return MotivationWant, nil + default: + return "", fmt.Errorf("%w: %q", ErrInvalidMotivation, str) + } +} diff --git a/motivation_test.go b/motivation_test.go new file mode 100644 index 0000000000000000000000000000000000000000..27dc86df9b62e66d068941e04f453fb63a4aabe2 --- /dev/null +++ b/motivation_test.go @@ -0,0 +1,54 @@ +// SPDX-FileCopyrightText: Amolith +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +package lunatask_test + +import ( + "testing" + + lunatask "git.secluded.site/go-lunatask" +) + +func TestParseMotivation(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + input string + want lunatask.Motivation + wantErr bool + }{ + {"unknown_lower", "unknown", lunatask.MotivationUnknown, false}, + {"unknown_upper", "UNKNOWN", lunatask.MotivationUnknown, false}, + {"unknown_mixed", "UnKnOwN", lunatask.MotivationUnknown, false}, + {"must_lower", "must", lunatask.MotivationMust, false}, + {"must_upper", "MUST", lunatask.MotivationMust, false}, + {"should_lower", "should", lunatask.MotivationShould, false}, + {"should_upper", "SHOULD", lunatask.MotivationShould, false}, + {"want_lower", "want", lunatask.MotivationWant, false}, + {"want_upper", "WANT", lunatask.MotivationWant, false}, + {"want_mixed", "WaNt", lunatask.MotivationWant, false}, + {"invalid", "invalid", "", true}, + {"empty", "", "", true}, + {"numeric", "1", "", true}, + {"typo", "muust", "", true}, + } + + for _, testCase := range tests { + t.Run(testCase.name, func(t *testing.T) { + t.Parallel() + + got, err := lunatask.ParseMotivation(testCase.input) + if (err != nil) != testCase.wantErr { + t.Errorf("ParseMotivation(%q) error = %v, wantErr %v", testCase.input, err, testCase.wantErr) + + return + } + + if !testCase.wantErr && got != testCase.want { + t.Errorf("ParseMotivation(%q) = %q, want %q", testCase.input, got, testCase.want) + } + }) + } +}