|
|
@ -1,6 +1,7 @@ |
|
|
package arg |
|
|
package arg |
|
|
|
|
|
|
|
|
import ( |
|
|
import ( |
|
|
|
|
|
"os" |
|
|
"strings" |
|
|
"strings" |
|
|
"testing" |
|
|
"testing" |
|
|
|
|
|
|
|
|
@ -69,6 +70,28 @@ func TestShortFlag(t *testing.T) { |
|
|
assert.Equal(t, "xyz", args.Foo) |
|
|
assert.Equal(t, "xyz", args.Foo) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestInvalidShortFlag(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo string `arg:"-foo"` |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("", &args) |
|
|
|
|
|
assert.Error(t, err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestLongFlag(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo string `arg:"--abc"` |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
err := parse("-abc xyz", &args) |
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
assert.Equal(t, "xyz", args.Foo) |
|
|
|
|
|
|
|
|
|
|
|
err = parse("--abc xyz", &args) |
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
assert.Equal(t, "xyz", args.Foo) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
func TestCaseSensitive(t *testing.T) { |
|
|
func TestCaseSensitive(t *testing.T) { |
|
|
var args struct { |
|
|
var args struct { |
|
|
Lower bool `arg:"-v"` |
|
|
Lower bool `arg:"-v"` |
|
|
@ -104,6 +127,19 @@ func TestPositional(t *testing.T) { |
|
|
assert.Equal(t, "", args.Output) |
|
|
assert.Equal(t, "", args.Output) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestPositionalPointer(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Input string `arg:"positional"` |
|
|
|
|
|
Output []*string `arg:"positional"` |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("foo bar baz", &args) |
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
assert.Equal(t, "foo", args.Input) |
|
|
|
|
|
bar := "bar" |
|
|
|
|
|
baz := "baz" |
|
|
|
|
|
assert.Equal(t, []*string{&bar, &baz}, args.Output) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
func TestRequiredPositional(t *testing.T) { |
|
|
func TestRequiredPositional(t *testing.T) { |
|
|
var args struct { |
|
|
var args struct { |
|
|
Input string `arg:"positional"` |
|
|
Input string `arg:"positional"` |
|
|
@ -132,3 +168,191 @@ func TestMultiple(t *testing.T) { |
|
|
assert.Equal(t, []int{1, 2, 3}, args.Foo) |
|
|
assert.Equal(t, []int{1, 2, 3}, args.Foo) |
|
|
assert.Equal(t, []string{"x", "y", "z"}, args.Bar) |
|
|
assert.Equal(t, []string{"x", "y", "z"}, args.Bar) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestMultipleWithEq(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo []int |
|
|
|
|
|
Bar []string |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("--foo 1 2 3 --bar=x", &args) |
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
assert.Equal(t, []int{1, 2, 3}, args.Foo) |
|
|
|
|
|
assert.Equal(t, []string{"x"}, args.Bar) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestExemptField(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo string |
|
|
|
|
|
Bar interface{} `arg:"-"` |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("--foo xyz", &args) |
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
assert.Equal(t, "xyz", args.Foo) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestUnknownField(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo string |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("--bar xyz", &args) |
|
|
|
|
|
assert.Error(t, err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestMissingRequired(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo string `arg:"required"` |
|
|
|
|
|
X []string `arg:"positional"` |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("x", &args) |
|
|
|
|
|
assert.Error(t, err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestMissingValue(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo string |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("--foo", &args) |
|
|
|
|
|
assert.Error(t, err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestInvalidInt(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo int |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("--foo=xyz", &args) |
|
|
|
|
|
assert.Error(t, err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestInvalidUint(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo uint |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("--foo=xyz", &args) |
|
|
|
|
|
assert.Error(t, err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestInvalidFloat(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo float64 |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("--foo xyz", &args) |
|
|
|
|
|
require.Error(t, err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestInvalidBool(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo bool |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("--foo=xyz", &args) |
|
|
|
|
|
require.Error(t, err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestInvalidIntSlice(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo []int |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("--foo 1 2 xyz", &args) |
|
|
|
|
|
require.Error(t, err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestInvalidPositional(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo int `arg:"positional"` |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("xyz", &args) |
|
|
|
|
|
require.Error(t, err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestInvalidPositionalSlice(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo []int `arg:"positional"` |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("1 2 xyz", &args) |
|
|
|
|
|
require.Error(t, err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestNoMoreOptions(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo string |
|
|
|
|
|
Bar []string `arg:"positional"` |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("abc -- --foo xyz", &args) |
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
assert.Equal(t, "", args.Foo) |
|
|
|
|
|
assert.Equal(t, []string{"abc", "--foo", "xyz"}, args.Bar) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestHelpFlag(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo string |
|
|
|
|
|
Bar interface{} `arg:"-"` |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("--help", &args) |
|
|
|
|
|
assert.Equal(t, ErrHelp, err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestPanicOnNonPointer(t *testing.T) { |
|
|
|
|
|
var args struct{} |
|
|
|
|
|
assert.Panics(t, func() { |
|
|
|
|
|
parse("", args) |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestPanicOnNonStruct(t *testing.T) { |
|
|
|
|
|
var args string |
|
|
|
|
|
assert.Panics(t, func() { |
|
|
|
|
|
parse("", &args) |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestUnsupportedType(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo interface{} |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("--foo", &args) |
|
|
|
|
|
assert.Error(t, err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestUnsupportedSliceElement(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo []interface{} |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("--foo", &args) |
|
|
|
|
|
assert.Error(t, err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestUnknownTag(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo string `arg:"this_is_not_valid"` |
|
|
|
|
|
} |
|
|
|
|
|
err := parse("--foo xyz", &args) |
|
|
|
|
|
assert.Error(t, err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestParse(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo string |
|
|
|
|
|
} |
|
|
|
|
|
os.Args = []string{"example", "--foo", "bar"} |
|
|
|
|
|
err := Parse(&args) |
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
assert.Equal(t, "bar", args.Foo) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestParseError(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo string `arg:"this_is_not_valid"` |
|
|
|
|
|
} |
|
|
|
|
|
os.Args = []string{"example", "--bar"} |
|
|
|
|
|
err := Parse(&args) |
|
|
|
|
|
assert.Error(t, err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestMustParse(t *testing.T) { |
|
|
|
|
|
var args struct { |
|
|
|
|
|
Foo string |
|
|
|
|
|
} |
|
|
|
|
|
os.Args = []string{"example", "--foo", "bar"} |
|
|
|
|
|
MustParse(&args) |
|
|
|
|
|
assert.Equal(t, "bar", args.Foo) |
|
|
|
|
|
} |