diff options
Diffstat (limited to 'v2/opts_test.go')
-rw-r--r-- | v2/opts_test.go | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/v2/opts_test.go b/v2/opts_test.go new file mode 100644 index 0000000..1e35910 --- /dev/null +++ b/v2/opts_test.go @@ -0,0 +1,366 @@ +package opts + +import ( + "fmt" + "testing" +) + +func die(t *testing.T, name string, want, got any) { + t.Fatalf("Expected %s to be ‘%s’ but got ‘%s’", name, want, got) +} + +// SHORT OPTS + +func assertGet(t *testing.T, args []string, fw, rw int, ew error) []Flag { + flags, rest, err := Get(args, "abλc:dßĦ::") + if err != ew { + die(t, "err", ew, err) + } + if len(rest) != rw { + die(t, "rest", rw, rest) + } + if len(flags) != fw { + die(t, "flags", fw, flags) + } + return flags +} + +func TestNoArg(t *testing.T) { + args := []string{} + assertGet(t, args, 0, 0, nil) +} + +func TestNoFlag(t *testing.T) { + args := []string{"foo"} + assertGet(t, args, 0, 0, nil) +} + +func TestCNoArg(t *testing.T) { + args := []string{"foo", "-c"} + assertGet(t, args, 0, 0, NoArgumentError{r: 'c'}) +} + +func TestCWithArg(t *testing.T) { + args := []string{"foo", "-c", "bar"} + flags := assertGet(t, args, 1, 0, nil) + if flags[0].Key != 'c' { + die(t, "flags[0].Key", 'c', flags[0].Key) + } + if flags[0].Value != "bar" { + die(t, "flags[0].Value", "bar", flags[0].Value) + } +} + +func TestCWithArgNoSpace(t *testing.T) { + args := []string{"foo", "-cbar"} + flags := assertGet(t, args, 1, 0, nil) + if flags[0].Key != 'c' { + die(t, "flags[0].Key", 'c', flags[0].Key) + } + if flags[0].Value != "bar" { + die(t, "flags[0].Value", "bar", flags[0].Value) + } +} + +func TestANoArg(t *testing.T) { + args := []string{"foo", "-a"} + flags := assertGet(t, args, 1, 0, nil) + if flags[0].Key != 'a' { + die(t, "flags[0].Key", 'a', flags[0].Key) + } + if flags[0].Value != "" { + die(t, "flags[0].Value", "", flags[0].Value) + } +} + +func TestAWithArg(t *testing.T) { + args := []string{"foo", "-a", "bar"} + flags := assertGet(t, args, 1, 1, nil) + if flags[0].Key != 'a' { + die(t, "flags[0].Key", 'a', flags[0].Key) + } + if flags[0].Value != "" { + die(t, "flags[0].Value", "", flags[0].Value) + } +} + +func TestAAndCWithArg(t *testing.T) { + args := []string{"foo", "-a", "-c", "bar"} + flags := assertGet(t, args, 2, 0, nil) + if flags[0].Key != 'a' { + die(t, "flags[0].Key", 'a', flags[0].Key) + } + if flags[0].Value != "" { + die(t, "flags[0].Value", "", flags[0].Value) + } + if flags[1].Key != 'c' { + die(t, "flags[0].Key", 'c', flags[1].Key) + } + if flags[1].Value != "bar" { + die(t, "flags[0].Value", "bar", flags[1].Value) + } +} + +func TestACWithArg(t *testing.T) { + args := []string{"foo", "-ac", "bar"} + flags := assertGet(t, args, 2, 0, nil) + if flags[0].Key != 'a' { + die(t, "flags[0].Key", 'a', flags[0].Key) + } + if flags[0].Value != "" { + die(t, "flags[0].Value", "", flags[0].Value) + } + if flags[1].Key != 'c' { + die(t, "flags[0].Key", 'c', flags[1].Key) + } + if flags[1].Value != "bar" { + die(t, "flags[0].Value", "bar", flags[1].Value) + } +} + +func TestCAWithArg(t *testing.T) { + args := []string{"foo", "-ca", "bar"} + flags := assertGet(t, args, 1, 1, nil) + if flags[0].Key != 'c' { + die(t, "flags[0].Key", 'c', flags[0].Key) + } + if flags[0].Value != "a" { + die(t, "flags[0].Value", "a", flags[0].Value) + } +} + +func TestBAfterDashDash(t *testing.T) { + args := []string{"foo", "--", "-b"} + assertGet(t, args, 0, 1, nil) +} + +func TestCWithArgAfterDashDash(t *testing.T) { + args := []string{"foo", "--", "-c", "bar", "baz"} + assertGet(t, args, 0, 3, nil) +} + +func TestCWithArgThenDAfterDashDash(t *testing.T) { + args := []string{"foo", "-c", "bar", "baz", "--", "-d"} + flags := assertGet(t, args, 1, 3, nil) + if flags[0].Key != 'c' { + die(t, "flags[0].Key", 'c', flags[0].Key) + } + if flags[0].Value != "bar" { + die(t, "flags[0].Value", "bar", flags[0].Value) + } +} + +func TestCWithArgThenDAfterEmpty(t *testing.T) { + args := []string{"foo", "-c", "bar", "baz", "", "-d"} + flags := assertGet(t, args, 1, 3, nil) + if flags[0].Key != 'c' { + die(t, "flags[0].Key", 'c', flags[0].Key) + } + if flags[0].Value != "bar" { + die(t, "flags[0].Value", "bar", flags[0].Value) + } +} + +func TestBChainedThrice(t *testing.T) { + args := []string{"foo", "-bbb"} + flags := assertGet(t, args, 3, 0, nil) + for i := 0; i < 3; i++ { + s := fmt.Sprintf("flags[%d].", i) + if flags[i].Key != 'b' { + die(t, s+"Key", 'b', flags[i].Key) + } + if flags[i].Value != "" { + die(t, s+"Value", "", flags[i].Value) + } + } +} + +func TestẞChainedTwice(t *testing.T) { + args := []string{"foo", "-ßß"} + flags := assertGet(t, args, 2, 0, nil) + for i := 0; i < 2; i++ { + s := fmt.Sprintf("flags[%d].", i) + if flags[i].Key != 'ß' { + die(t, s+"Key", 'ß', flags[i].Key) + } + if flags[i].Value != "" { + die(t, s+"Value", "", flags[i].Value) + } + } +} + +func TestΛAsArgToC(t *testing.T) { + args := []string{"foo", "-c", "-λ"} + flags := assertGet(t, args, 1, 0, nil) + if flags[0].Key != 'c' { + die(t, "flags[0].Key", 'c', flags[0].Key) + } + if flags[0].Value != "-λ" { + die(t, "flags[0].Value", "-λ", flags[0].Value) + } +} + +func TestInvalidFlag(t *testing.T) { + args := []string{"foo", "-X"} + assertGet(t, args, 0, 0, BadOptionError{r: 'X'}) +} + +func TestInvalidFlagWithArg(t *testing.T) { + args := []string{"foo", "-X", "bar"} + assertGet(t, args, 0, 0, BadOptionError{r: 'X'}) +} + +func TestAAfterArg(t *testing.T) { + args := []string{"foo", "bar", "-a"} + assertGet(t, args, 0, 2, nil) +} + +func TestXAfterDash(t *testing.T) { + args := []string{"foo", "-", "-x"} + assertGet(t, args, 0, 2, nil) +} + +func TestĦWithSpaceAndArg(t *testing.T) { + args := []string{"foo", "-Ħ", "bar"} + flags := assertGet(t, args, 1, 1, nil) + if flags[0].Key != 'Ħ' { + die(t, "flags[0].Key", 'Ħ', flags[0].Key) + } + if flags[0].Value != "" { + die(t, "flags[0].Value", "", flags[0].Value) + } +} + +func TestĦWithArg(t *testing.T) { + args := []string{"foo", "-Ħbar"} + flags := assertGet(t, args, 1, 0, nil) + if flags[0].Key != 'Ħ' { + die(t, "flags[0].Key", 'Ħ', flags[0].Key) + } + if flags[0].Value != "bar" { + die(t, "flags[0].Value", "bar", flags[0].Value) + } +} + +func TestΛĦWithArg(t *testing.T) { + args := []string{"foo", "-λĦbar"} + flags := assertGet(t, args, 2, 0, nil) + if flags[0].Key != 'λ' { + die(t, "flags[0].Key", 'λ', flags[0].Key) + } + if flags[0].Value != "" { + die(t, "flags[0].Value", "", flags[0].Value) + } + if flags[1].Key != 'Ħ' { + die(t, "flags[1].Key", 'Ħ', flags[1].Key) + } + if flags[1].Value != "bar" { + die(t, "flags[1].Value", "bar", flags[1].Value) + } +} + +// LONG OPTS + +func assertGetLong(t *testing.T, args []string, fw, rw int, ew error) []Flag { + opts := []LongOpt{ + {Short: 'a', Long: "add", Arg: None}, + {Short: 'b', Long: "back", Arg: None}, + {Short: 'λ', Long: "λεωνίδας", Arg: None}, + {Short: 'c', Long: "change", Arg: Required}, + {Short: 'C', Long: "count", Arg: None}, + {Short: 'd', Long: "delete", Arg: None}, + {Short: 'ß', Long: "scheiße", Arg: None}, + {Short: 'Ħ', Long: "Ħaġrat", Arg: Optional}, + } + flags, rest, err := GetLong(args, opts) + if err != ew { + die(t, "err", ew, err) + } + if len(rest) != rw { + die(t, "rest", rw, rest) + } + if len(flags) != fw { + die(t, "flags", fw, flags) + } + return flags +} + +func TestNoArgL(t *testing.T) { + args := []string{} + assertGetLong(t, args, 0, 0, nil) +} + +func TestNoFlagL(t *testing.T) { + args := []string{"foo"} + assertGetLong(t, args, 0, 0, nil) +} + +func TestChangeNoArg(t *testing.T) { + args := []string{"foo", "--change"} + assertGetLong(t, args, 0, 0, NoArgumentError{s: "change"}) +} + +func TestChangeArgEqual(t *testing.T) { + args := []string{"foo", "--change=bar"} + flags := assertGetLong(t, args, 1, 0, nil) + if flags[0].Key != 'c' { + die(t, "flags[0].Key", 'c', flags[0].Key) + } + if flags[0].Value != "bar" { + die(t, "flags[0].Value", "bar", flags[0].Value) + } +} + +func TestChangeArgSpace(t *testing.T) { + args := []string{"foo", "--change", "bar"} + flags := assertGetLong(t, args, 1, 0, nil) + if flags[0].Key != 'c' { + die(t, "flags[0].Key", 'c', flags[0].Key) + } + if flags[0].Value != "bar" { + die(t, "flags[0].Value", "bar", flags[0].Value) + } +} + +func TestChangeArgSpaceShort(t *testing.T) { + args := []string{"foo", "--ch", "bar"} + flags := assertGetLong(t, args, 1, 0, nil) + if flags[0].Key != 'c' { + die(t, "flags[0].Key", 'c', flags[0].Key) + } + if flags[0].Value != "bar" { + die(t, "flags[0].Value", "bar", flags[0].Value) + } +} + +func TestChangeArgSpaceShortFail(t *testing.T) { + args := []string{"foo", "--c", "bar"} + assertGetLong(t, args, 0, 0, BadOptionError{s: "c"}) +} + +func TestĦaġratNoArg(t *testing.T) { + args := []string{"foo", "--Ħ"} + assertGetLong(t, args, 1, 0, nil) +} + +func TestĦaġratArgEqual(t *testing.T) { + args := []string{"foo", "--Ħ=bar"} + flags := assertGetLong(t, args, 1, 0, nil) + if flags[0].Key != 'Ħ' { + die(t, "flags[0].Key", 'Ħ', flags[0].Key) + } + if flags[0].Value != "bar" { + die(t, "flags[0].Value", "bar", flags[0].Value) + } +} + +func TestĦaġratArgSpace(t *testing.T) { + args := []string{"foo", "--Ħ", "bar"} + flags := assertGetLong(t, args, 1, 1, nil) + if flags[0].Key != 'Ħ' { + die(t, "flags[0].Key", 'Ħ', flags[0].Key) + } + if flags[0].Value != "" { + die(t, "flags[0].Value", "", flags[0].Value) + } +} |