aboutsummaryrefslogtreecommitdiff
path: root/v2/opts_test.go
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2023-12-05 01:32:52 +0100
committerThomas Voss <mail@thomasvoss.com> 2023-12-05 01:32:52 +0100
commit264780bb60dda33e8d06c48be5f1991212d62a9a (patch)
tree684d61e3e7aaddf73ce4e7c6fc731f72a23a7fac /v2/opts_test.go
parent799bb3be1d099ce6979cd6baa8b84acc507130bd (diff)
Replace ‘optind’ with ‘rest’ in Get() and GetLong() returnsHEADv2.0.0master
Diffstat (limited to 'v2/opts_test.go')
-rw-r--r--v2/opts_test.go366
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)
+ }
+}