2015-03-11 21:52:35 +03:00
|
|
|
package cobra
|
|
|
|
|
|
|
|
import (
|
2016-05-26 00:27:02 +03:00
|
|
|
"bytes"
|
|
|
|
"fmt"
|
2016-06-04 03:25:52 +03:00
|
|
|
"os"
|
2015-03-11 21:52:35 +03:00
|
|
|
"reflect"
|
2017-04-23 10:50:55 +03:00
|
|
|
"strings"
|
2015-03-11 21:52:35 +03:00
|
|
|
"testing"
|
2017-04-19 14:59:20 +03:00
|
|
|
|
|
|
|
"github.com/spf13/pflag"
|
2015-03-11 21:52:35 +03:00
|
|
|
)
|
|
|
|
|
2015-09-04 23:34:51 +03:00
|
|
|
// 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!")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-11 21:52:35 +03:00
|
|
|
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"},
|
|
|
|
},
|
2015-03-16 22:47:32 +03:00
|
|
|
{
|
|
|
|
[]string{"--persist", "bar"},
|
|
|
|
[]string{"bar"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
[]string{"-p", "bar"},
|
|
|
|
[]string{"bar"},
|
|
|
|
},
|
2015-03-11 21:52:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2015-03-16 22:47:32 +03:00
|
|
|
cmdPrint.PersistentFlags().BoolVarP(&flagbool, "persist", "p", false, "help for persistent one")
|
2015-03-11 21:52:35 +03:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-06-04 03:25:52 +03:00
|
|
|
|
2017-04-23 10:50:55 +03:00
|
|
|
func TestDisableFlagParsing(t *testing.T) {
|
2016-06-04 03:25:52 +03:00
|
|
|
as := []string{"-v", "-race", "-file", "foo.go"}
|
|
|
|
targs := []string{}
|
|
|
|
cmdPrint := &Command{
|
|
|
|
DisableFlagParsing: true,
|
|
|
|
Run: func(cmd *Command, args []string) {
|
|
|
|
targs = args
|
|
|
|
},
|
|
|
|
}
|
|
|
|
osargs := []string{"cmd"}
|
|
|
|
os.Args = append(osargs, as...)
|
|
|
|
err := cmdPrint.Execute()
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(as, targs) {
|
|
|
|
t.Errorf("expected: %v, got: %v", as, targs)
|
|
|
|
}
|
|
|
|
}
|
2016-06-14 17:04:53 +03:00
|
|
|
|
2016-06-01 01:38:12 +03:00
|
|
|
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.initHelpFlag()
|
|
|
|
actual := cmd.Flags().Lookup("help").Usage
|
|
|
|
if actual != usage {
|
2016-10-26 04:28:26 +03:00
|
|
|
t.Fatalf("Expected the help flag from the base command with usage '%s', but got the default with usage '%s'", usage, actual)
|
2016-06-01 01:38:12 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-14 17:04:53 +03:00
|
|
|
func TestCommandsAreSorted(t *testing.T) {
|
|
|
|
EnableCommandSorting = true
|
|
|
|
|
|
|
|
originalNames := []string{"middle", "zlast", "afirst"}
|
|
|
|
expectedNames := []string{"afirst", "middle", "zlast"}
|
|
|
|
|
|
|
|
var tmpCommand = &Command{Use: "tmp"}
|
|
|
|
|
2016-08-20 10:09:46 +03:00
|
|
|
for _, name := range originalNames {
|
2016-06-14 17:04:53 +03:00
|
|
|
tmpCommand.AddCommand(&Command{Use: name})
|
|
|
|
}
|
|
|
|
|
2016-08-20 10:09:46 +03:00
|
|
|
for i, c := range tmpCommand.Commands() {
|
2016-06-14 17:04:53 +03:00
|
|
|
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"}
|
|
|
|
|
2016-08-20 10:09:46 +03:00
|
|
|
for _, name := range originalNames {
|
2016-06-14 17:04:53 +03:00
|
|
|
tmpCommand.AddCommand(&Command{Use: name})
|
|
|
|
}
|
|
|
|
|
2016-08-20 10:09:46 +03:00
|
|
|
for i, c := range tmpCommand.Commands() {
|
2016-06-14 17:04:53 +03:00
|
|
|
if originalNames[i] != c.Name() {
|
|
|
|
t.Errorf("expected: %s, got: %s", originalNames[i], c.Name())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EnableCommandSorting = true
|
|
|
|
}
|
2016-05-26 00:27:02 +03:00
|
|
|
|
2017-04-02 17:14:34 +03:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-26 00:27:02 +03:00
|
|
|
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())
|
|
|
|
}
|
|
|
|
}
|
2017-04-19 14:59:20 +03:00
|
|
|
|
|
|
|
// TestSortedFlags checks,
|
|
|
|
// if cmd.LocalFlags() is unsorted when cmd.Flags().SortFlags set to false.
|
2017-04-23 10:50:55 +03:00
|
|
|
//
|
|
|
|
// Source: https://github.com/spf13/cobra/issues/404
|
2017-04-19 14:59:20 +03:00
|
|
|
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
|
|
|
|
}
|
2017-04-23 10:50:55 +03:00
|
|
|
if isStringInStringSlice(f.Name, names) {
|
2017-04-19 14:59:20 +03:00
|
|
|
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.
|
2017-04-23 10:50:55 +03:00
|
|
|
func isStringInStringSlice(s string, ss []string) bool {
|
2017-04-19 14:59:20 +03:00
|
|
|
for _, v := range ss {
|
|
|
|
if v == s {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
2017-04-23 10:50:55 +03:00
|
|
|
|
|
|
|
// TestHelpFlagInHelp checks,
|
|
|
|
// if '--help' flag is shown in help for child (executing `parent help child`),
|
|
|
|
// that has no other flags.
|
|
|
|
//
|
|
|
|
// Source: https://github.com/spf13/cobra/issues/302
|
|
|
|
func TestHelpFlagInHelp(t *testing.T) {
|
|
|
|
output := new(bytes.Buffer)
|
|
|
|
parent := &Command{Use: "parent", Long: "long", Run: func(*Command, []string) { return }}
|
|
|
|
parent.SetOutput(output)
|
|
|
|
|
|
|
|
child := &Command{Use: "child", Long: "long", Run: func(*Command, []string) { return }}
|
|
|
|
parent.AddCommand(child)
|
|
|
|
|
|
|
|
parent.SetArgs([]string{"help", "child"})
|
|
|
|
err := parent.Execute()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !strings.Contains(output.String(), "[flags]") {
|
|
|
|
t.Fatalf("\nExpecting to contain: %v\nGot: %v", "[flags]", output.String())
|
|
|
|
}
|
|
|
|
}
|