From c384926308d12e3013db23bd3e6e546efc495dd5 Mon Sep 17 00:00:00 2001 From: Tom Fleet Date: Thu, 1 Aug 2024 09:36:54 +0100 Subject: [PATCH] Add more flag parse tests (#55) * More tests for flag parsing * Add more flag parse tests --- internal/flag/flag.go | 3 + internal/flag/set.go | 1 + internal/flag/set_test.go | 124 +++++++++++++++++++++++++++++++++++++- 3 files changed, 126 insertions(+), 2 deletions(-) diff --git a/internal/flag/flag.go b/internal/flag/flag.go index 702581e..a465c28 100644 --- a/internal/flag/flag.go +++ b/internal/flag/flag.go @@ -439,6 +439,9 @@ func validateFlagShort(short rune) error { // errParse is a helper to quickly return a consistent error in the face of flag // value parsing errors. +// +// TODO: A proper error type and use errors.Is/As during testing rather +// than comparing string contents. func errParse[T any](name, str string, typ *T, err error) error { return fmt.Errorf( "flag %q received invalid value %q (expected %T), detail: %w", diff --git a/internal/flag/set.go b/internal/flag/set.go index b009238..bc07539 100644 --- a/internal/flag/set.go +++ b/internal/flag/set.go @@ -160,6 +160,7 @@ func (s *Set) parseLongFlag(long string, rest []string) (remaining []string, err return rest[1:], nil default: // --flag (value was required) + // Do we ever hit this? Idk when a flag would be required return nil, fmt.Errorf("flag --%s requires an argument", name) } } diff --git a/internal/flag/set_test.go b/internal/flag/set_test.go index a594498..ece28f3 100644 --- a/internal/flag/set_test.go +++ b/internal/flag/set_test.go @@ -236,6 +236,30 @@ func TestParse(t *testing.T) { args: []string{"--delete"}, wantErr: false, }, + { + name: "valid long with args", + newSet: func(t *testing.T) *flag.Set { + t.Helper() + set := flag.NewSet() + f, err := flag.New(new(bool), "delete", 'd', false, "Delete something") + test.Ok(t, err) + + err = flag.AddToSet(set, f) + test.Ok(t, err) + + return set + }, + test: func(t *testing.T, set *flag.Set) { + t.Helper() + value, exists := set.Get("delete") + test.True(t, exists) + + test.Equal(t, value.Type(), "bool") + test.Equal(t, value.String(), "true") + }, + args: []string{"some", "subcommand", "--delete"}, + wantErr: false, + }, { name: "valid short", newSet: func(t *testing.T) *flag.Set { @@ -260,6 +284,30 @@ func TestParse(t *testing.T) { args: []string{"-d"}, wantErr: false, }, + { + name: "valid short with args", + newSet: func(t *testing.T) *flag.Set { + t.Helper() + set := flag.NewSet() + f, err := flag.New(new(bool), "delete", 'd', false, "Delete something") + test.Ok(t, err) + + err = flag.AddToSet(set, f) + test.Ok(t, err) + + return set + }, + test: func(t *testing.T, set *flag.Set) { + t.Helper() + value, exists := set.Get("delete") + test.True(t, exists) + + test.Equal(t, value.Type(), "bool") + test.Equal(t, value.String(), "true") + }, + args: []string{"some", "arg", "-d"}, + wantErr: false, + }, { name: "valid long value", newSet: func(t *testing.T) *flag.Set { @@ -284,6 +332,30 @@ func TestParse(t *testing.T) { args: []string{"--count", "1"}, wantErr: false, }, + { + name: "valid long value with args", + newSet: func(t *testing.T) *flag.Set { + t.Helper() + set := flag.NewSet() + f, err := flag.New(new(int), "count", 'c', 0, "Count something") + test.Ok(t, err) + + err = flag.AddToSet(set, f) + test.Ok(t, err) + + return set + }, + test: func(t *testing.T, set *flag.Set) { + t.Helper() + value, exists := set.Get("count") + test.True(t, exists) + + test.Equal(t, value.Type(), "int") + test.Equal(t, value.String(), "1") + }, + args: []string{"some", "arg", "--count", "1", "more", "args"}, + wantErr: false, + }, { name: "invalid long value", newSet: func(t *testing.T) *flag.Set { @@ -333,6 +405,30 @@ func TestParse(t *testing.T) { args: []string{"-c", "1"}, wantErr: false, }, + { + name: "valid short value with args", + newSet: func(t *testing.T) *flag.Set { + t.Helper() + set := flag.NewSet() + f, err := flag.New(new(int), "count", 'c', 0, "Count something") + test.Ok(t, err) + + err = flag.AddToSet(set, f) + test.Ok(t, err) + + return set + }, + test: func(t *testing.T, set *flag.Set) { + t.Helper() + value, exists := set.Get("count") + test.True(t, exists) + + test.Equal(t, value.Type(), "int") + test.Equal(t, value.String(), "1") + }, + args: []string{"args", "-c", "1", "more", "args"}, + wantErr: false, + }, { name: "invalid short value", newSet: func(t *testing.T) *flag.Set { @@ -382,6 +478,30 @@ func TestParse(t *testing.T) { args: []string{"--count=1"}, wantErr: false, }, + { + name: "valid long equals value with args", + newSet: func(t *testing.T) *flag.Set { + t.Helper() + set := flag.NewSet() + f, err := flag.New(new(int), "count", 'c', 0, "Count something") + test.Ok(t, err) + + err = flag.AddToSet(set, f) + test.Ok(t, err) + + return set + }, + test: func(t *testing.T, set *flag.Set) { + t.Helper() + value, exists := set.Get("count") + test.True(t, exists) + + test.Equal(t, value.Type(), "int") + test.Equal(t, value.String(), "1") + }, + args: []string{"args", "--count=1", "more", "args"}, + wantErr: false, + }, { name: "invalid long equals value", newSet: func(t *testing.T) *flag.Set { @@ -432,7 +552,7 @@ func TestParse(t *testing.T) { wantErr: false, }, { - name: "valid short equals value", + name: "valid short equals value with args", newSet: func(t *testing.T) *flag.Set { t.Helper() set := flag.NewSet() @@ -452,7 +572,7 @@ func TestParse(t *testing.T) { test.Equal(t, value.Type(), "int") test.Equal(t, value.String(), "1") }, - args: []string{"-c=1"}, + args: []string{"args", "-c=1", "more", "args"}, wantErr: false, }, }