diff --git a/CHANGELOG.md b/CHANGELOG.md index a6e9b1b5e..9265553c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Take server state into account in server completions. For example, do not offer started servers as completions for `server start` command. - Allow using UUID prefix as an argument. For example, if there is only one network available that has an UUID starting with `0316`, details of that network can be listed with `upctl network show 0316` command. +- Match title and name arguments case-insensitively if the given parameter does not resolve with an exact match. ## [3.11.1] - 2024-08-12 diff --git a/internal/resolver/matchers.go b/internal/resolver/matchers.go index 4fe4dd836..51a295633 100644 --- a/internal/resolver/matchers.go +++ b/internal/resolver/matchers.go @@ -11,6 +11,9 @@ func MatchArgWithWhitespace(arg, value string) MatchType { if completion.RemoveWordBreaks(value) == arg || value == arg { return MatchTypeExact } + if strings.EqualFold(completion.RemoveWordBreaks(value), arg) || strings.EqualFold(value, arg) { + return MatchTypeCaseInsensitive + } return MatchTypeNone } diff --git a/internal/resolver/matchers_test.go b/internal/resolver/matchers_test.go new file mode 100644 index 000000000..3b8eb4dc8 --- /dev/null +++ b/internal/resolver/matchers_test.go @@ -0,0 +1,45 @@ +package resolver + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestMatchers(t *testing.T) { + cases := []struct { + name string + execFn func(string, string) MatchType + arg string + value string + expected MatchType + }{ + { + name: "Exact match", + execFn: MatchArgWithWhitespace, + arg: "McDuck", + value: "McDuck", + expected: MatchTypeExact, + }, + { + name: "Case-insensitive match", + execFn: MatchArgWithWhitespace, + arg: "mcduck", + value: "McDuck", + expected: MatchTypeCaseInsensitive, + }, + { + name: "No match", + execFn: MatchArgWithWhitespace, + arg: "scrooge", + value: "McDuck", + expected: MatchTypeNone, + }, + } + + for _, tt := range cases { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.expected, tt.execFn(tt.arg, tt.value)) + }) + } +}