OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / github.com / spf13 / cobra / command_test.go
diff --git a/vendor/github.com/spf13/cobra/command_test.go b/vendor/github.com/spf13/cobra/command_test.go
new file mode 100644 (file)
index 0000000..dda355f
--- /dev/null
@@ -0,0 +1,526 @@
+package cobra
+
+import (
+       "bytes"
+       "fmt"
+       "os"
+       "reflect"
+       "strings"
+       "testing"
+
+       "github.com/spf13/pflag"
+)
+
+// test to ensure hidden commands run as intended
+func TestHiddenCommandExecutes(t *testing.T) {
+
+       // ensure that outs does not already equal what the command will be setting it
+       // to, if it did this test would not actually be testing anything...
+       if outs == "hidden" {
+               t.Errorf("outs should NOT EQUAL hidden")
+       }
+
+       cmdHidden.Execute()
+
+       // upon running the command, the value of outs should now be 'hidden'
+       if outs != "hidden" {
+               t.Errorf("Hidden command failed to run!")
+       }
+}
+
+// test to ensure hidden commands do not show up in usage/help text
+func TestHiddenCommandIsHidden(t *testing.T) {
+       if cmdHidden.IsAvailableCommand() {
+               t.Errorf("Hidden command found!")
+       }
+}
+
+func TestStripFlags(t *testing.T) {
+       tests := []struct {
+               input  []string
+               output []string
+       }{
+               {
+                       []string{"foo", "bar"},
+                       []string{"foo", "bar"},
+               },
+               {
+                       []string{"foo", "--bar", "-b"},
+                       []string{"foo"},
+               },
+               {
+                       []string{"-b", "foo", "--bar", "bar"},
+                       []string{},
+               },
+               {
+                       []string{"-i10", "echo"},
+                       []string{"echo"},
+               },
+               {
+                       []string{"-i=10", "echo"},
+                       []string{"echo"},
+               },
+               {
+                       []string{"--int=100", "echo"},
+                       []string{"echo"},
+               },
+               {
+                       []string{"-ib", "echo", "-bfoo", "baz"},
+                       []string{"echo", "baz"},
+               },
+               {
+                       []string{"-i=baz", "bar", "-i", "foo", "blah"},
+                       []string{"bar", "blah"},
+               },
+               {
+                       []string{"--int=baz", "-bbar", "-i", "foo", "blah"},
+                       []string{"blah"},
+               },
+               {
+                       []string{"--cat", "bar", "-i", "foo", "blah"},
+                       []string{"bar", "blah"},
+               },
+               {
+                       []string{"-c", "bar", "-i", "foo", "blah"},
+                       []string{"bar", "blah"},
+               },
+               {
+                       []string{"--persist", "bar"},
+                       []string{"bar"},
+               },
+               {
+                       []string{"-p", "bar"},
+                       []string{"bar"},
+               },
+       }
+
+       cmdPrint := &Command{
+               Use:   "print [string to print]",
+               Short: "Print anything to the screen",
+               Long:  `an utterly useless command for testing.`,
+               Run: func(cmd *Command, args []string) {
+                       tp = args
+               },
+       }
+
+       var flagi int
+       var flagstr string
+       var flagbool bool
+       cmdPrint.PersistentFlags().BoolVarP(&flagbool, "persist", "p", false, "help for persistent one")
+       cmdPrint.Flags().IntVarP(&flagi, "int", "i", 345, "help message for flag int")
+       cmdPrint.Flags().StringVarP(&flagstr, "bar", "b", "bar", "help message for flag string")
+       cmdPrint.Flags().BoolVarP(&flagbool, "cat", "c", false, "help message for flag bool")
+
+       for _, test := range tests {
+               output := stripFlags(test.input, cmdPrint)
+               if !reflect.DeepEqual(test.output, output) {
+                       t.Errorf("expected: %v, got: %v", test.output, output)
+               }
+       }
+}
+
+func TestDisableFlagParsing(t *testing.T) {
+       targs := []string{}
+       cmdPrint := &Command{
+               DisableFlagParsing: true,
+               Run: func(cmd *Command, args []string) {
+                       targs = args
+               },
+       }
+       args := []string{"cmd", "-v", "-race", "-file", "foo.go"}
+       cmdPrint.SetArgs(args)
+       err := cmdPrint.Execute()
+       if err != nil {
+               t.Error(err)
+       }
+       if !reflect.DeepEqual(args, targs) {
+               t.Errorf("expected: %v, got: %v", args, targs)
+       }
+}
+
+func TestInitHelpFlagMergesFlags(t *testing.T) {
+       usage := "custom flag"
+       baseCmd := Command{Use: "testcmd"}
+       baseCmd.PersistentFlags().Bool("help", false, usage)
+       cmd := Command{Use: "do"}
+       baseCmd.AddCommand(&cmd)
+
+       cmd.InitDefaultHelpFlag()
+       actual := cmd.Flags().Lookup("help").Usage
+       if actual != usage {
+               t.Fatalf("Expected the help flag from the base command with usage '%s', but got the default with usage '%s'", usage, actual)
+       }
+}
+
+func TestCommandsAreSorted(t *testing.T) {
+       EnableCommandSorting = true
+
+       originalNames := []string{"middle", "zlast", "afirst"}
+       expectedNames := []string{"afirst", "middle", "zlast"}
+
+       var tmpCommand = &Command{Use: "tmp"}
+
+       for _, name := range originalNames {
+               tmpCommand.AddCommand(&Command{Use: name})
+       }
+
+       for i, c := range tmpCommand.Commands() {
+               if expectedNames[i] != c.Name() {
+                       t.Errorf("expected: %s, got: %s", expectedNames[i], c.Name())
+               }
+       }
+
+       EnableCommandSorting = true
+}
+
+func TestEnableCommandSortingIsDisabled(t *testing.T) {
+       EnableCommandSorting = false
+
+       originalNames := []string{"middle", "zlast", "afirst"}
+
+       var tmpCommand = &Command{Use: "tmp"}
+
+       for _, name := range originalNames {
+               tmpCommand.AddCommand(&Command{Use: name})
+       }
+
+       for i, c := range tmpCommand.Commands() {
+               if originalNames[i] != c.Name() {
+                       t.Errorf("expected: %s, got: %s", originalNames[i], c.Name())
+               }
+       }
+
+       EnableCommandSorting = true
+}
+
+func TestSetOutput(t *testing.T) {
+       cmd := &Command{}
+       cmd.SetOutput(nil)
+       if out := cmd.OutOrStdout(); out != os.Stdout {
+               t.Fatalf("expected setting output to nil to revert back to stdout, got %v", out)
+       }
+}
+
+func TestFlagErrorFunc(t *testing.T) {
+       cmd := &Command{
+               Use: "print",
+               RunE: func(cmd *Command, args []string) error {
+                       return nil
+               },
+       }
+       expectedFmt := "This is expected: %s"
+
+       cmd.SetFlagErrorFunc(func(c *Command, err error) error {
+               return fmt.Errorf(expectedFmt, err)
+       })
+       cmd.SetArgs([]string{"--bogus-flag"})
+       cmd.SetOutput(new(bytes.Buffer))
+
+       err := cmd.Execute()
+
+       expected := fmt.Sprintf(expectedFmt, "unknown flag: --bogus-flag")
+       if err.Error() != expected {
+               t.Errorf("expected %v, got %v", expected, err.Error())
+       }
+}
+
+// TestSortedFlags checks,
+// if cmd.LocalFlags() is unsorted when cmd.Flags().SortFlags set to false.
+// Related to https://github.com/spf13/cobra/issues/404.
+func TestSortedFlags(t *testing.T) {
+       cmd := &Command{}
+       cmd.Flags().SortFlags = false
+       names := []string{"C", "B", "A", "D"}
+       for _, name := range names {
+               cmd.Flags().Bool(name, false, "")
+       }
+
+       i := 0
+       cmd.LocalFlags().VisitAll(func(f *pflag.Flag) {
+               if i == len(names) {
+                       return
+               }
+               if isStringInStringSlice(f.Name, names) {
+                       if names[i] != f.Name {
+                               t.Errorf("Incorrect order. Expected %v, got %v", names[i], f.Name)
+                       }
+                       i++
+               }
+       })
+}
+
+// contains checks, if s is in ss.
+func isStringInStringSlice(s string, ss []string) bool {
+       for _, v := range ss {
+               if v == s {
+                       return true
+               }
+       }
+       return false
+}
+
+// TestHelpFlagInHelp checks,
+// if '--help' flag is shown in help for child (executing `parent help child`),
+// that has no other flags.
+// Related to https://github.com/spf13/cobra/issues/302.
+func TestHelpFlagInHelp(t *testing.T) {
+       output := new(bytes.Buffer)
+       parent := &Command{Use: "parent", Run: func(*Command, []string) {}}
+       parent.SetOutput(output)
+
+       child := &Command{Use: "child", Run: func(*Command, []string) {}}
+       parent.AddCommand(child)
+
+       parent.SetArgs([]string{"help", "child"})
+       err := parent.Execute()
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       if !strings.Contains(output.String(), "[flags]") {
+               t.Errorf("\nExpecting to contain: %v\nGot: %v", "[flags]", output.String())
+       }
+}
+
+// TestMergeCommandLineToFlags checks,
+// if pflag.CommandLine is correctly merged to c.Flags() after first call
+// of c.mergePersistentFlags.
+// Related to https://github.com/spf13/cobra/issues/443.
+func TestMergeCommandLineToFlags(t *testing.T) {
+       pflag.Bool("boolflag", false, "")
+       c := &Command{Use: "c", Run: func(*Command, []string) {}}
+       c.mergePersistentFlags()
+       if c.Flags().Lookup("boolflag") == nil {
+               t.Fatal("Expecting to have flag from CommandLine in c.Flags()")
+       }
+
+       // Reset pflag.CommandLine flagset.
+       pflag.CommandLine = pflag.NewFlagSet(os.Args[0], pflag.ExitOnError)
+}
+
+// TestUseDeprecatedFlags checks,
+// if cobra.Execute() prints a message, if a deprecated flag is used.
+// Related to https://github.com/spf13/cobra/issues/463.
+func TestUseDeprecatedFlags(t *testing.T) {
+       c := &Command{Use: "c", Run: func(*Command, []string) {}}
+       output := new(bytes.Buffer)
+       c.SetOutput(output)
+       c.Flags().BoolP("deprecated", "d", false, "deprecated flag")
+       c.Flags().MarkDeprecated("deprecated", "This flag is deprecated")
+
+       c.SetArgs([]string{"c", "-d"})
+       if err := c.Execute(); err != nil {
+               t.Error("Unexpected error:", err)
+       }
+       if !strings.Contains(output.String(), "This flag is deprecated") {
+               t.Errorf("Expected to contain deprecated message, but got %q", output.String())
+       }
+}
+
+// TestSetHelpCommand checks, if SetHelpCommand works correctly.
+func TestSetHelpCommand(t *testing.T) {
+       c := &Command{Use: "c", Run: func(*Command, []string) {}}
+       output := new(bytes.Buffer)
+       c.SetOutput(output)
+       c.SetArgs([]string{"help"})
+
+       // Help will not be shown, if c has no subcommands.
+       c.AddCommand(&Command{
+               Use: "empty",
+               Run: func(cmd *Command, args []string) {},
+       })
+
+       correctMessage := "WORKS"
+       c.SetHelpCommand(&Command{
+               Use:   "help [command]",
+               Short: "Help about any command",
+               Long: `Help provides help for any command in the application.
+       Simply type ` + c.Name() + ` help [path to command] for full details.`,
+               Run: func(c *Command, args []string) { c.Print(correctMessage) },
+       })
+
+       if err := c.Execute(); err != nil {
+               t.Error("Unexpected error:", err)
+       }
+
+       if output.String() != correctMessage {
+               t.Errorf("Expected to contain %q message, but got %q", correctMessage, output.String())
+       }
+}
+
+func TestTraverseWithParentFlags(t *testing.T) {
+       cmd := &Command{
+               Use:              "do",
+               TraverseChildren: true,
+       }
+       cmd.Flags().String("foo", "", "foo things")
+       cmd.Flags().BoolP("goo", "g", false, "foo things")
+
+       sub := &Command{Use: "next"}
+       sub.Flags().String("add", "", "add things")
+       cmd.AddCommand(sub)
+
+       c, args, err := cmd.Traverse([]string{"-g", "--foo", "ok", "next", "--add"})
+       if err != nil {
+               t.Fatalf("Expected no error: %s", err)
+       }
+       if len(args) != 1 && args[0] != "--add" {
+               t.Fatalf("wrong args %s", args)
+       }
+       if c.Name() != sub.Name() {
+               t.Fatalf("wrong command %q expected %q", c.Name(), sub.Name())
+       }
+}
+
+func TestTraverseNoParentFlags(t *testing.T) {
+       cmd := &Command{
+               Use:              "do",
+               TraverseChildren: true,
+       }
+       cmd.Flags().String("foo", "", "foo things")
+
+       sub := &Command{Use: "next"}
+       sub.Flags().String("add", "", "add things")
+       cmd.AddCommand(sub)
+
+       c, args, err := cmd.Traverse([]string{"next"})
+       if err != nil {
+               t.Fatalf("Expected no error: %s", err)
+       }
+       if len(args) != 0 {
+               t.Fatalf("wrong args %s", args)
+       }
+       if c.Name() != sub.Name() {
+               t.Fatalf("wrong command %q expected %q", c.Name(), sub.Name())
+       }
+}
+
+func TestTraverseWithBadParentFlags(t *testing.T) {
+       cmd := &Command{
+               Use:              "do",
+               TraverseChildren: true,
+       }
+       sub := &Command{Use: "next"}
+       sub.Flags().String("add", "", "add things")
+       cmd.AddCommand(sub)
+
+       expected := "got unknown flag: --add"
+
+       c, _, err := cmd.Traverse([]string{"--add", "ok", "next"})
+       if err == nil || strings.Contains(err.Error(), expected) {
+               t.Fatalf("Expected error %s got %s", expected, err)
+       }
+       if c != nil {
+               t.Fatalf("Expected nil command")
+       }
+}
+
+func TestTraverseWithBadChildFlag(t *testing.T) {
+       cmd := &Command{
+               Use:              "do",
+               TraverseChildren: true,
+       }
+       cmd.Flags().String("foo", "", "foo things")
+
+       sub := &Command{Use: "next"}
+       cmd.AddCommand(sub)
+
+       // Expect no error because the last commands args shouldn't be parsed in
+       // Traverse
+       c, args, err := cmd.Traverse([]string{"next", "--add"})
+       if err != nil {
+               t.Fatalf("Expected no error: %s", err)
+       }
+       if len(args) != 1 && args[0] != "--add" {
+               t.Fatalf("wrong args %s", args)
+       }
+       if c.Name() != sub.Name() {
+               t.Fatalf("wrong command %q expected %q", c.Name(), sub.Name())
+       }
+}
+
+func TestTraverseWithTwoSubcommands(t *testing.T) {
+       cmd := &Command{
+               Use:              "do",
+               TraverseChildren: true,
+       }
+
+       sub := &Command{
+               Use:              "sub",
+               TraverseChildren: true,
+       }
+       cmd.AddCommand(sub)
+
+       subsub := &Command{
+               Use: "subsub",
+       }
+       sub.AddCommand(subsub)
+
+       c, _, err := cmd.Traverse([]string{"sub", "subsub"})
+       if err != nil {
+               t.Fatalf("Expected no error: %s", err)
+       }
+       if c.Name() != subsub.Name() {
+               t.Fatalf("wrong command %q expected %q", c.Name(), subsub.Name())
+       }
+}
+
+func TestRequiredFlags(t *testing.T) {
+       c := &Command{Use: "c", Run: func(*Command, []string) {}}
+       output := new(bytes.Buffer)
+       c.SetOutput(output)
+       c.Flags().String("foo1", "", "required foo1")
+       c.MarkFlagRequired("foo1")
+       c.Flags().String("foo2", "", "required foo2")
+       c.MarkFlagRequired("foo2")
+       c.Flags().String("bar", "", "optional bar")
+
+       expected := fmt.Sprintf("Required flag(s) %q, %q have/has not been set", "foo1", "foo2")
+
+       if err := c.Execute(); err != nil {
+               if err.Error() != expected {
+                       t.Errorf("expected %v, got %v", expected, err.Error())
+               }
+       }
+}
+
+func TestPersistentRequiredFlags(t *testing.T) {
+       parent := &Command{Use: "parent", Run: func(*Command, []string) {}}
+       output := new(bytes.Buffer)
+       parent.SetOutput(output)
+       parent.PersistentFlags().String("foo1", "", "required foo1")
+       parent.MarkPersistentFlagRequired("foo1")
+       parent.PersistentFlags().String("foo2", "", "required foo2")
+       parent.MarkPersistentFlagRequired("foo2")
+       parent.Flags().String("foo3", "", "optional foo3")
+
+       child := &Command{Use: "child", Run: func(*Command, []string) {}}
+       child.Flags().String("bar1", "", "required bar1")
+       child.MarkFlagRequired("bar1")
+       child.Flags().String("bar2", "", "required bar2")
+       child.MarkFlagRequired("bar2")
+       child.Flags().String("bar3", "", "optional bar3")
+
+       parent.AddCommand(child)
+       parent.SetArgs([]string{"child"})
+
+       expected := fmt.Sprintf("Required flag(s) %q, %q, %q, %q have/has not been set", "bar1", "bar2", "foo1", "foo2")
+
+       if err := parent.Execute(); err != nil {
+               if err.Error() != expected {
+                       t.Errorf("expected %v, got %v", expected, err.Error())
+               }
+       }
+}
+
+// TestUpdateName checks if c.Name() updates on changed c.Use.
+// Related to https://github.com/spf13/cobra/pull/422#discussion_r143918343.
+func TestUpdateName(t *testing.T) {
+       c := &Command{Use: "name xyz"}
+       originalName := c.Name()
+
+       c.Use = "changedName abc"
+       if originalName == c.Name() || c.Name() != "changedName" {
+               t.Error("c.Name() should be updated on changed c.Use")
+       }
+}