OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / github.com / spf13 / cobra / cobra_test.go
1 package cobra
2
3 import (
4         "bytes"
5         "fmt"
6         "os"
7         "reflect"
8         "runtime"
9         "strings"
10         "testing"
11         "text/template"
12
13         "github.com/spf13/pflag"
14 )
15
16 var tp, te, tt, tr []string
17 var rootPersPre, echoPre, echoPersPre, timesPersPre []string
18 var flagb1, flagb2, flagb3, flagbr, flagbp bool
19 var flags1, flags2a, flags2b, flags3, outs string
20 var flagi1, flagi2, flagi3, flagi4, flagir int
21 var rootcalled bool
22 var versionUsed int
23
24 const strtwoParentHelp = "help message for parent flag strtwo"
25 const strtwoChildHelp = "help message for child flag strtwo"
26
27 var cmdHidden = &Command{
28         Use:   "hide [secret string to print]",
29         Short: "Print anything to screen (if command is known)",
30         Long:  `an absolutely utterly useless command for testing.`,
31         Run: func(cmd *Command, args []string) {
32                 outs = "hidden"
33         },
34         Hidden: true,
35 }
36
37 var cmdPrint = &Command{
38         Use:   "print [string to print]",
39         Args:  MinimumNArgs(1),
40         Short: "Print anything to the screen",
41         Long:  `an absolutely utterly useless command for testing.`,
42         Run: func(cmd *Command, args []string) {
43                 tp = args
44         },
45 }
46
47 var cmdEcho = &Command{
48         Use:     "echo [string to echo]",
49         Aliases: []string{"say"},
50         Short:   "Echo anything to the screen",
51         Long:    `an utterly useless command for testing.`,
52         Example: "Just run cobra-test echo",
53         PersistentPreRun: func(cmd *Command, args []string) {
54                 echoPersPre = args
55         },
56         PreRun: func(cmd *Command, args []string) {
57                 echoPre = args
58         },
59         Run: func(cmd *Command, args []string) {
60                 te = args
61         },
62 }
63
64 var cmdEchoSub = &Command{
65         Use:   "echosub [string to print]",
66         Short: "second sub command for echo",
67         Long:  `an absolutely utterly useless command for testing gendocs!.`,
68         Run: func(cmd *Command, args []string) {
69         },
70 }
71
72 var cmdDeprecated = &Command{
73         Use:        "deprecated [can't do anything here]",
74         Short:      "A command which is deprecated",
75         Long:       `an absolutely utterly useless command for testing deprecation!.`,
76         Deprecated: "Please use echo instead",
77         Run: func(cmd *Command, args []string) {
78         },
79         Args: NoArgs,
80 }
81
82 var cmdTimes = &Command{
83         Use:        "times [# times] [string to echo]",
84         SuggestFor: []string{"counts"},
85         Short:      "Echo anything to the screen more times",
86         Long:       `a slightly useless command for testing.`,
87         PersistentPreRun: func(cmd *Command, args []string) {
88                 timesPersPre = args
89         },
90         Run: func(cmd *Command, args []string) {
91                 tt = args
92         },
93         Args:      OnlyValidArgs,
94         ValidArgs: []string{"one", "two", "three", "four"},
95 }
96
97 var cmdRootNoRun = &Command{
98         Use:   "cobra-test",
99         Short: "The root can run its own function",
100         Long:  "The root description for help",
101         PersistentPreRun: func(cmd *Command, args []string) {
102                 rootPersPre = args
103         },
104 }
105
106 var cmdRootSameName = &Command{
107         Use:   "print",
108         Short: "Root with the same name as a subcommand",
109         Long:  "The root description for help",
110 }
111
112 var cmdRootTakesArgs = &Command{
113         Use:   "root-with-args [random args]",
114         Short: "The root can run it's own function and takes args!",
115         Long:  "The root description for help, and some args",
116         Run: func(cmd *Command, args []string) {
117                 tr = args
118         },
119         Args: ArbitraryArgs,
120 }
121
122 var cmdRootWithRun = &Command{
123         Use:   "cobra-test",
124         Short: "The root can run its own function",
125         Long:  "The root description for help",
126         Run: func(cmd *Command, args []string) {
127                 tr = args
128                 rootcalled = true
129         },
130 }
131
132 var cmdSubNoRun = &Command{
133         Use:   "subnorun",
134         Short: "A subcommand without a Run function",
135         Long:  "A long output about a subcommand without a Run function",
136 }
137
138 var cmdCustomFlags = &Command{
139         Use:   "customflags [flags] -- REMOTE_COMMAND",
140         Short: "A command that expects flags in a custom location",
141         Long:  "A long output about a command that expects flags in a custom location",
142         Run: func(cmd *Command, args []string) {
143         },
144 }
145
146 var cmdVersion1 = &Command{
147         Use:   "version",
148         Short: "Print the version number",
149         Long:  `First version of the version command`,
150         Run: func(cmd *Command, args []string) {
151                 versionUsed = 1
152         },
153 }
154
155 var cmdVersion2 = &Command{
156         Use:   "version",
157         Short: "Print the version number",
158         Long:  `Second version of the version command`,
159         Run: func(cmd *Command, args []string) {
160                 versionUsed = 2
161         },
162 }
163
164 var cmdColon = &Command{
165         Use: "cmd:colon",
166         Run: func(cmd *Command, args []string) {
167         },
168 }
169
170 func flagInit() {
171         cmdEcho.ResetFlags()
172         cmdPrint.ResetFlags()
173         cmdTimes.ResetFlags()
174         cmdRootNoRun.ResetFlags()
175         cmdRootSameName.ResetFlags()
176         cmdRootWithRun.ResetFlags()
177         cmdSubNoRun.ResetFlags()
178         cmdCustomFlags.ResetFlags()
179         cmdVersion1.ResetFlags()
180         cmdVersion2.ResetFlags()
181
182         cmdRootNoRun.PersistentFlags().StringVarP(&flags2a, "strtwo", "t", "two", strtwoParentHelp)
183         cmdCustomFlags.Flags().IntVar(&flagi4, "intfour", 456, "help message for flag intfour")
184         cmdEcho.Flags().BoolVarP(&flagb1, "boolone", "b", true, "help message for flag boolone")
185         cmdEcho.Flags().IntVarP(&flagi1, "intone", "i", 123, "help message for flag intone")
186         cmdEcho.PersistentFlags().BoolVarP(&flagbp, "persistentbool", "p", false, "help message for flag persistentbool")
187         cmdEcho.PersistentFlags().StringVarP(&flags1, "strone", "s", "one", "help message for flag strone")
188         cmdPrint.Flags().IntVarP(&flagi3, "intthree", "i", 345, "help message for flag intthree")
189         cmdTimes.Flags().BoolVarP(&flagb2, "booltwo", "c", false, "help message for flag booltwo")
190         cmdTimes.Flags().IntVarP(&flagi2, "inttwo", "j", 234, "help message for flag inttwo")
191         cmdTimes.Flags().StringVarP(&flags2b, "strtwo", "t", "2", strtwoChildHelp)
192         cmdTimes.PersistentFlags().StringVarP(&flags2b, "strtwo", "t", "2", strtwoChildHelp)
193         cmdTimes.LocalFlags() // populate lflags before parent is set
194         cmdPrint.Flags().BoolVarP(&flagb3, "boolthree", "b", true, "help message for flag boolthree")
195         cmdPrint.PersistentFlags().StringVarP(&flags3, "strthree", "s", "three", "help message for flag strthree")
196 }
197
198 func commandInit() {
199         cmdEcho.ResetCommands()
200         cmdPrint.ResetCommands()
201         cmdTimes.ResetCommands()
202         cmdRootNoRun.ResetCommands()
203         cmdRootSameName.ResetCommands()
204         cmdRootWithRun.ResetCommands()
205         cmdSubNoRun.ResetCommands()
206         cmdCustomFlags.ResetCommands()
207 }
208
209 func initialize() *Command {
210         tt, tp, te = nil, nil, nil
211         rootPersPre, echoPre, echoPersPre, timesPersPre = nil, nil, nil, nil
212
213         var c = cmdRootNoRun
214         commandInit()
215         flagInit()
216         return c
217 }
218
219 func initializeWithSameName() *Command {
220         tt, tp, te = nil, nil, nil
221         rootPersPre, echoPre, echoPersPre, timesPersPre = nil, nil, nil, nil
222         var c = cmdRootSameName
223         commandInit()
224         flagInit()
225         return c
226 }
227
228 func initializeWithRootCmd() *Command {
229         cmdRootWithRun.ResetCommands()
230         tt, tp, te, tr, rootcalled = nil, nil, nil, nil, false
231         flagInit()
232         cmdRootWithRun.Flags().BoolVarP(&flagbr, "boolroot", "b", false, "help message for flag boolroot")
233         cmdRootWithRun.Flags().IntVarP(&flagir, "introot", "i", 321, "help message for flag introot")
234         commandInit()
235         return cmdRootWithRun
236 }
237
238 type resulter struct {
239         Error   error
240         Output  string
241         Command *Command
242 }
243
244 func fullSetupTest(args ...string) resulter {
245         c := initializeWithRootCmd()
246
247         return fullTester(c, args...)
248 }
249
250 func noRRSetupTestSilenced(args ...string) resulter {
251         c := initialize()
252         c.SilenceErrors = true
253         c.SilenceUsage = true
254         return fullTester(c, args...)
255 }
256
257 func noRRSetupTest(args ...string) resulter {
258         c := initialize()
259
260         return fullTester(c, args...)
261 }
262
263 func rootOnlySetupTest(args ...string) resulter {
264         c := initializeWithRootCmd()
265
266         return simpleTester(c, args...)
267 }
268
269 func simpleTester(c *Command, args ...string) resulter {
270         buf := new(bytes.Buffer)
271         // Testing flag with invalid input
272         c.SetOutput(buf)
273         c.SetArgs(args)
274
275         err := c.Execute()
276         output := buf.String()
277
278         return resulter{err, output, c}
279 }
280
281 func simpleTesterC(c *Command, args ...string) resulter {
282         buf := new(bytes.Buffer)
283         // Testing flag with invalid input
284         c.SetOutput(buf)
285         c.SetArgs(args)
286
287         cmd, err := c.ExecuteC()
288         output := buf.String()
289
290         return resulter{err, output, cmd}
291 }
292
293 func fullTester(c *Command, args ...string) resulter {
294         buf := new(bytes.Buffer)
295         // Testing flag with invalid input
296         c.SetOutput(buf)
297         cmdEcho.AddCommand(cmdTimes)
298         c.AddCommand(cmdPrint, cmdEcho, cmdSubNoRun, cmdCustomFlags, cmdDeprecated)
299         c.SetArgs(args)
300
301         err := c.Execute()
302         output := buf.String()
303
304         return resulter{err, output, c}
305 }
306
307 func logErr(t *testing.T, found, expected string) {
308         out := new(bytes.Buffer)
309
310         _, _, line, ok := runtime.Caller(2)
311         if ok {
312                 fmt.Fprintf(out, "Line: %d ", line)
313         }
314         fmt.Fprintf(out, "Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found)
315         t.Errorf(out.String())
316 }
317
318 func checkStringContains(t *testing.T, found, expected string) {
319         if !strings.Contains(found, expected) {
320                 logErr(t, found, expected)
321         }
322 }
323
324 func checkResultContains(t *testing.T, x resulter, check string) {
325         checkStringContains(t, x.Output, check)
326 }
327
328 func checkStringOmits(t *testing.T, found, expected string) {
329         if strings.Contains(found, expected) {
330                 logErr(t, found, expected)
331         }
332 }
333
334 func checkResultOmits(t *testing.T, x resulter, check string) {
335         checkStringOmits(t, x.Output, check)
336 }
337
338 func checkOutputContains(t *testing.T, c *Command, check string) {
339         buf := new(bytes.Buffer)
340         c.SetOutput(buf)
341         c.Execute()
342
343         if !strings.Contains(buf.String(), check) {
344                 logErr(t, buf.String(), check)
345         }
346 }
347
348 func TestSingleCommand(t *testing.T) {
349         noRRSetupTest("print", "one", "two")
350
351         if te != nil || tt != nil {
352                 t.Error("Wrong command called")
353         }
354         if tp == nil {
355                 t.Error("Wrong command called")
356         }
357         if strings.Join(tp, " ") != "one two" {
358                 t.Error("Command didn't parse correctly")
359         }
360 }
361
362 func TestChildCommand(t *testing.T) {
363         noRRSetupTest("echo", "times", "one", "two")
364
365         if te != nil || tp != nil {
366                 t.Error("Wrong command called")
367         }
368         if tt == nil {
369                 t.Error("Wrong command called")
370         }
371         if strings.Join(tt, " ") != "one two" {
372                 t.Error("Command didn't parse correctly")
373         }
374 }
375
376 func TestCommandAlias(t *testing.T) {
377         noRRSetupTest("say", "times", "one", "two")
378
379         if te != nil || tp != nil {
380                 t.Error("Wrong command called")
381         }
382         if tt == nil {
383                 t.Error("Wrong command called")
384         }
385         if strings.Join(tt, " ") != "one two" {
386                 t.Error("Command didn't parse correctly")
387         }
388 }
389
390 func TestPrefixMatching(t *testing.T) {
391         EnablePrefixMatching = true
392         noRRSetupTest("ech", "times", "one", "two")
393
394         if te != nil || tp != nil {
395                 t.Error("Wrong command called")
396         }
397         if tt == nil {
398                 t.Error("Wrong command called")
399         }
400         if strings.Join(tt, " ") != "one two" {
401                 t.Error("Command didn't parse correctly")
402         }
403
404         EnablePrefixMatching = false
405 }
406
407 func TestNoPrefixMatching(t *testing.T) {
408         EnablePrefixMatching = false
409
410         noRRSetupTest("ech", "times", "one", "two")
411
412         if !(tt == nil && te == nil && tp == nil) {
413                 t.Error("Wrong command called")
414         }
415 }
416
417 func TestAliasPrefixMatching(t *testing.T) {
418         EnablePrefixMatching = true
419         noRRSetupTest("sa", "times", "one", "two")
420
421         if te != nil || tp != nil {
422                 t.Error("Wrong command called")
423         }
424         if tt == nil {
425                 t.Error("Wrong command called")
426         }
427         if strings.Join(tt, " ") != "one two" {
428                 t.Error("Command didn't parse correctly")
429         }
430         EnablePrefixMatching = false
431 }
432
433 func TestChildSameName(t *testing.T) {
434         c := initializeWithSameName()
435         c.AddCommand(cmdPrint, cmdEcho)
436         c.SetArgs([]string{"print", "one", "two"})
437         c.Execute()
438
439         if te != nil || tt != nil {
440                 t.Error("Wrong command called")
441         }
442         if tp == nil {
443                 t.Error("Wrong command called")
444         }
445         if strings.Join(tp, " ") != "one two" {
446                 t.Error("Command didn't parse correctly")
447         }
448 }
449
450 func TestGrandChildSameName(t *testing.T) {
451         c := initializeWithSameName()
452         cmdTimes.AddCommand(cmdPrint)
453         c.AddCommand(cmdTimes)
454         c.SetArgs([]string{"times", "print", "one", "two"})
455         c.Execute()
456
457         if te != nil || tt != nil {
458                 t.Error("Wrong command called")
459         }
460         if tp == nil {
461                 t.Error("Wrong command called")
462         }
463         if strings.Join(tp, " ") != "one two" {
464                 t.Error("Command didn't parse correctly")
465         }
466 }
467
468 func TestUsage(t *testing.T) {
469         x := fullSetupTest("help")
470         checkResultContains(t, x, cmdRootWithRun.Use+" [flags]")
471         x = fullSetupTest("help", "customflags")
472         checkResultContains(t, x, cmdCustomFlags.Use)
473         checkResultOmits(t, x, cmdCustomFlags.Use+" [flags]")
474 }
475
476 func TestRootTakesNoArgs(t *testing.T) {
477         c := initializeWithSameName()
478         c.AddCommand(cmdPrint, cmdEcho)
479         result := simpleTester(c, "illegal")
480
481         if result.Error == nil {
482                 t.Fatal("Expected an error")
483         }
484
485         expectedError := `unknown command "illegal" for "print"`
486         if !strings.Contains(result.Error.Error(), expectedError) {
487                 t.Errorf("exptected %v, got %v", expectedError, result.Error.Error())
488         }
489 }
490
491 func TestRootTakesArgs(t *testing.T) {
492         c := cmdRootTakesArgs
493         result := simpleTester(c, "legal")
494
495         if result.Error != nil {
496                 t.Errorf("expected no error, but got %v", result.Error)
497         }
498 }
499
500 func TestSubCmdTakesNoArgs(t *testing.T) {
501         result := fullSetupTest("deprecated", "illegal")
502
503         if result.Error == nil {
504                 t.Fatal("Expected an error")
505         }
506
507         expectedError := `unknown command "illegal" for "cobra-test deprecated"`
508         if !strings.Contains(result.Error.Error(), expectedError) {
509                 t.Errorf("expected %v, got %v", expectedError, result.Error.Error())
510         }
511 }
512
513 func TestSubCmdTakesArgs(t *testing.T) {
514         noRRSetupTest("echo", "times", "one", "two")
515         if strings.Join(tt, " ") != "one two" {
516                 t.Error("Command didn't parse correctly")
517         }
518 }
519
520 func TestCmdOnlyValidArgs(t *testing.T) {
521         result := noRRSetupTest("echo", "times", "one", "two", "five")
522
523         if result.Error == nil {
524                 t.Fatal("Expected an error")
525         }
526
527         expectedError := `invalid argument "five"`
528         if !strings.Contains(result.Error.Error(), expectedError) {
529                 t.Errorf("expected %v, got %v", expectedError, result.Error.Error())
530         }
531 }
532
533 func TestFlagLong(t *testing.T) {
534         noRRSetupTest("echo", "--intone=13", "something", "--", "here")
535
536         if cmdEcho.ArgsLenAtDash() != 1 {
537                 t.Errorf("expected argsLenAtDash: %d but got %d", 1, cmdRootNoRun.ArgsLenAtDash())
538         }
539         if strings.Join(te, " ") != "something here" {
540                 t.Errorf("flags didn't leave proper args remaining..%s given", te)
541         }
542         if flagi1 != 13 {
543                 t.Errorf("int flag didn't get correct value, had %d", flagi1)
544         }
545         if flagi2 != 234 {
546                 t.Errorf("default flag value changed, 234 expected, %d given", flagi2)
547         }
548 }
549
550 func TestFlagShort(t *testing.T) {
551         noRRSetupTest("echo", "-i13", "--", "something", "here")
552
553         if cmdEcho.ArgsLenAtDash() != 0 {
554                 t.Errorf("expected argsLenAtDash: %d but got %d", 0, cmdRootNoRun.ArgsLenAtDash())
555         }
556         if strings.Join(te, " ") != "something here" {
557                 t.Errorf("flags didn't leave proper args remaining..%s given", te)
558         }
559         if flagi1 != 13 {
560                 t.Errorf("int flag didn't get correct value, had %d", flagi1)
561         }
562         if flagi2 != 234 {
563                 t.Errorf("default flag value changed, 234 expected, %d given", flagi2)
564         }
565
566         noRRSetupTest("echo", "-i", "13", "something", "here")
567
568         if strings.Join(te, " ") != "something here" {
569                 t.Errorf("flags didn't leave proper args remaining..%s given", te)
570         }
571         if flagi1 != 13 {
572                 t.Errorf("int flag didn't get correct value, had %d", flagi1)
573         }
574         if flagi2 != 234 {
575                 t.Errorf("default flag value changed, 234 expected, %d given", flagi2)
576         }
577
578         noRRSetupTest("print", "-i99", "one", "two")
579
580         if strings.Join(tp, " ") != "one two" {
581                 t.Errorf("flags didn't leave proper args remaining..%s given", tp)
582         }
583         if flagi3 != 99 {
584                 t.Errorf("int flag didn't get correct value, had %d", flagi3)
585         }
586         if flagi1 != 123 {
587                 t.Errorf("default flag value changed on different command with same shortname, 234 expected, %d given", flagi2)
588         }
589 }
590
591 func TestChildCommandFlags(t *testing.T) {
592         noRRSetupTest("echo", "times", "-j", "99", "one", "two")
593
594         if strings.Join(tt, " ") != "one two" {
595                 t.Errorf("flags didn't leave proper args remaining..%s given", tt)
596         }
597
598         // Testing with flag that shouldn't be persistent
599         r := noRRSetupTest("echo", "times", "-j", "99", "-i77", "one", "two")
600
601         if r.Error == nil {
602                 t.Errorf("invalid flag should generate error")
603         }
604
605         if !strings.Contains(r.Error.Error(), "unknown shorthand") {
606                 t.Errorf("Wrong error message displayed, \n %s", r.Error)
607         }
608
609         if flagi2 != 99 {
610                 t.Errorf("flag value should be 99, %d given", flagi2)
611         }
612
613         if flagi1 != 123 {
614                 t.Errorf("unset flag should have default value, expecting 123, given %d", flagi1)
615         }
616
617         // Testing with flag only existing on child
618         r = noRRSetupTest("echo", "-j", "99", "-i77", "one", "two")
619
620         if r.Error == nil {
621                 t.Errorf("invalid flag should generate error")
622         }
623         if !strings.Contains(r.Error.Error(), "unknown shorthand flag") {
624                 t.Errorf("Wrong error message displayed, \n %s", r.Error)
625         }
626
627         // Testing with persistent flag overwritten by child
628         noRRSetupTest("echo", "times", "--strtwo=child", "one", "two")
629
630         if flags2b != "child" {
631                 t.Errorf("flag value should be child, %s given", flags2b)
632         }
633
634         if flags2a != "two" {
635                 t.Errorf("unset flag should have default value, expecting two, given %s", flags2a)
636         }
637
638         // Testing flag with invalid input
639         r = noRRSetupTest("echo", "-i10E")
640
641         if r.Error == nil {
642                 t.Errorf("invalid input should generate error")
643         }
644         if !strings.Contains(r.Error.Error(), "invalid syntax") {
645                 t.Errorf("Wrong error message displayed, \n %s", r.Error)
646         }
647 }
648
649 func TestTrailingCommandFlags(t *testing.T) {
650         x := fullSetupTest("echo", "two", "-x")
651
652         if x.Error == nil {
653                 t.Errorf("invalid flag should generate error")
654         }
655 }
656
657 func TestInvalidSubcommandFlags(t *testing.T) {
658         cmd := initializeWithRootCmd()
659         cmd.AddCommand(cmdTimes)
660
661         result := simpleTester(cmd, "times", "--inttwo=2", "--badflag=bar")
662         // given that we are not checking here result.Error we check for
663         // stock usage message
664         checkResultContains(t, result, "cobra-test times [# times]")
665         if strings.Contains(result.Error.Error(), "unknown flag: --inttwo") {
666                 t.Errorf("invalid --badflag flag shouldn't fail on 'unknown' --inttwo flag")
667         }
668
669 }
670
671 func TestSubcommandExecuteC(t *testing.T) {
672         cmd := initializeWithRootCmd()
673         double := &Command{
674                 Use: "double message",
675                 Run: func(c *Command, args []string) {
676                         msg := strings.Join(args, " ")
677                         c.Println(msg, msg)
678                 },
679         }
680
681         echo := &Command{
682                 Use: "echo message",
683                 Run: func(c *Command, args []string) {
684                         msg := strings.Join(args, " ")
685                         c.Println(msg)
686                 },
687         }
688
689         cmd.AddCommand(double, echo)
690
691         result := simpleTesterC(cmd, "double", "hello", "world")
692         checkResultContains(t, result, "hello world hello world")
693
694         if result.Command.Name() != "double" {
695                 t.Errorf("invalid cmd returned from ExecuteC: should be 'double' but got %s", result.Command.Name())
696         }
697
698         result = simpleTesterC(cmd, "echo", "msg", "to", "be", "echoed")
699         checkResultContains(t, result, "msg to be echoed")
700
701         if result.Command.Name() != "echo" {
702                 t.Errorf("invalid cmd returned from ExecuteC: should be 'echo' but got %s", result.Command.Name())
703         }
704 }
705
706 func TestSubcommandArgEvaluation(t *testing.T) {
707         cmd := initializeWithRootCmd()
708
709         first := &Command{
710                 Use: "first",
711                 Run: func(cmd *Command, args []string) {
712                 },
713         }
714         cmd.AddCommand(first)
715
716         second := &Command{
717                 Use: "second",
718                 Run: func(cmd *Command, args []string) {
719                         fmt.Fprintf(cmd.OutOrStdout(), "%v", args)
720                 },
721         }
722         first.AddCommand(second)
723
724         result := simpleTester(cmd, "first", "second", "first", "third")
725
726         expectedOutput := fmt.Sprint([]string{"first third"})
727         if result.Output != expectedOutput {
728                 t.Errorf("exptected %v, got %v", expectedOutput, result.Output)
729         }
730 }
731
732 func TestPersistentFlags(t *testing.T) {
733         fullSetupTest("echo", "-s", "something", "-p", "more", "here")
734
735         // persistentFlag should act like normal flag on its own command
736         if strings.Join(te, " ") != "more here" {
737                 t.Errorf("flags didn't leave proper args remaining..%s given", te)
738         }
739         if flags1 != "something" {
740                 t.Errorf("string flag didn't get correct value, had %v", flags1)
741         }
742         if !flagbp {
743                 t.Errorf("persistent bool flag not parsed correctly. Expected true, had %v", flagbp)
744         }
745
746         // persistentFlag should act like normal flag on its own command
747         fullSetupTest("echo", "times", "-s", "again", "-c", "-p", "one", "two")
748
749         if strings.Join(tt, " ") != "one two" {
750                 t.Errorf("flags didn't leave proper args remaining. %s given", tt)
751         }
752
753         if flags1 != "again" {
754                 t.Errorf("string flag didn't get correct value, had %v", flags1)
755         }
756
757         if !flagb2 {
758                 t.Errorf("local flag not parsed correctly. Expected true, had %v", flagb2)
759         }
760         if !flagbp {
761                 t.Errorf("persistent bool flag not parsed correctly. Expected true, had %v", flagbp)
762         }
763 }
764
765 func TestHelpCommand(t *testing.T) {
766         x := fullSetupTest("help")
767         checkResultContains(t, x, cmdRootWithRun.Long)
768
769         x = fullSetupTest("help", "echo")
770         checkResultContains(t, x, cmdEcho.Long)
771
772         x = fullSetupTest("help", "echo", "times")
773         checkResultContains(t, x, cmdTimes.Long)
774 }
775
776 func TestChildCommandHelp(t *testing.T) {
777         c := noRRSetupTest("print", "--help")
778         checkResultContains(t, c, strtwoParentHelp)
779         r := noRRSetupTest("echo", "times", "--help")
780         checkResultContains(t, r, strtwoChildHelp)
781 }
782
783 func TestNonRunChildHelp(t *testing.T) {
784         x := noRRSetupTest("subnorun")
785         checkResultContains(t, x, cmdSubNoRun.Long)
786 }
787
788 func TestRunnableRootCommand(t *testing.T) {
789         x := fullSetupTest("")
790
791         if !rootcalled {
792                 t.Errorf("Root Function was not called\n out:%v", x.Error)
793         }
794 }
795
796 func TestVisitParents(t *testing.T) {
797         c := &Command{Use: "app"}
798         sub := &Command{Use: "sub"}
799         dsub := &Command{Use: "dsub"}
800         sub.AddCommand(dsub)
801         c.AddCommand(sub)
802         total := 0
803         add := func(x *Command) {
804                 total++
805         }
806         sub.VisitParents(add)
807         if total != 1 {
808                 t.Errorf("Should have visited 1 parent but visited %d", total)
809         }
810
811         total = 0
812         dsub.VisitParents(add)
813         if total != 2 {
814                 t.Errorf("Should have visited 2 parent but visited %d", total)
815         }
816
817         total = 0
818         c.VisitParents(add)
819         if total != 0 {
820                 t.Errorf("Should have not visited any parent but visited %d", total)
821         }
822 }
823
824 func TestRunnableRootCommandNilInput(t *testing.T) {
825         c := initializeWithRootCmd()
826
827         buf := new(bytes.Buffer)
828         // Testing flag with invalid input
829         c.SetOutput(buf)
830         cmdEcho.AddCommand(cmdTimes)
831         c.AddCommand(cmdPrint, cmdEcho)
832         c.SetArgs([]string{})
833
834         err := c.Execute()
835         if err != nil {
836                 t.Errorf("Execute() failed with %v", err)
837         }
838
839         if !rootcalled {
840                 t.Errorf("Root Function was not called")
841         }
842 }
843
844 func TestRunnableRootCommandEmptyInput(t *testing.T) {
845         args := []string{"", "--introot=12", ""}
846         c := initializeWithRootCmd()
847
848         buf := new(bytes.Buffer)
849         // Testing flag with invalid input
850         c.SetOutput(buf)
851         cmdEcho.AddCommand(cmdTimes)
852         c.AddCommand(cmdPrint, cmdEcho)
853         c.SetArgs(args)
854
855         c.Execute()
856
857         if !rootcalled {
858                 t.Errorf("Root Function was not called.\nOutput was:\n%s\n", buf)
859         }
860 }
861
862 func TestInvalidSubcommandWhenArgsAllowed(t *testing.T) {
863         fullSetupTest("echo", "invalid-sub")
864
865         if te[0] != "invalid-sub" {
866                 t.Errorf("Subcommand didn't work...")
867         }
868 }
869
870 func TestRootFlags(t *testing.T) {
871         fullSetupTest("-i", "17", "-b")
872
873         if !flagbr {
874                 t.Errorf("flag value should be true, %v given", flagbr)
875         }
876
877         if flagir != 17 {
878                 t.Errorf("flag value should be 17, %d given", flagir)
879         }
880 }
881
882 func TestRootHelp(t *testing.T) {
883         x := fullSetupTest("--help")
884
885         checkResultContains(t, x, "Available Commands:")
886         checkResultContains(t, x, "for more information about a command")
887
888         if strings.Contains(x.Output, "unknown flag: --help") {
889                 t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
890         }
891
892         if strings.Contains(x.Output, cmdEcho.Use) {
893                 t.Errorf("--help shouldn't display subcommand's usage, Got: \n %s", x.Output)
894         }
895
896         x = fullSetupTest("echo", "--help")
897
898         if strings.Contains(x.Output, cmdTimes.Use) {
899                 t.Errorf("--help shouldn't display subsubcommand's usage, Got: \n %s", x.Output)
900         }
901
902         checkResultContains(t, x, "Available Commands:")
903         checkResultContains(t, x, "for more information about a command")
904
905         if strings.Contains(x.Output, "unknown flag: --help") {
906                 t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
907         }
908
909 }
910
911 func TestFlagAccess(t *testing.T) {
912         initialize()
913
914         cmdEcho.AddCommand(cmdTimes)
915         local := cmdTimes.LocalFlags()
916         inherited := cmdTimes.InheritedFlags()
917
918         for _, f := range []string{"inttwo", "strtwo", "booltwo"} {
919                 if local.Lookup(f) == nil {
920                         t.Errorf("LocalFlags expected to contain %s, Got: nil", f)
921                 }
922         }
923         if inherited.Lookup("strone") == nil {
924                 t.Errorf("InheritedFlags expected to contain strone, Got: nil")
925         }
926         if inherited.Lookup("strtwo") != nil {
927                 t.Errorf("InheritedFlags shouldn not contain overwritten flag strtwo")
928         }
929 }
930
931 func TestNoNRunnableRootCommandNilInput(t *testing.T) {
932         c := initialize()
933
934         buf := new(bytes.Buffer)
935         // Testing flag with invalid input
936         c.SetOutput(buf)
937         cmdEcho.AddCommand(cmdTimes)
938         c.AddCommand(cmdPrint, cmdEcho)
939         c.SetArgs([]string{})
940
941         c.Execute()
942
943         if !strings.Contains(buf.String(), cmdRootNoRun.Long) {
944                 t.Errorf("Expected to get help output, Got: \n %s", buf)
945         }
946 }
947
948 func TestRootNoCommandHelp(t *testing.T) {
949         x := rootOnlySetupTest("--help")
950
951         checkResultOmits(t, x, "Available Commands:")
952         checkResultOmits(t, x, "for more information about a command")
953
954         if strings.Contains(x.Output, "unknown flag: --help") {
955                 t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
956         }
957
958         x = rootOnlySetupTest("echo", "--help")
959
960         checkResultOmits(t, x, "Available Commands:")
961         checkResultOmits(t, x, "for more information about a command")
962
963         if strings.Contains(x.Output, "unknown flag: --help") {
964                 t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
965         }
966 }
967
968 func TestRootUnknownCommand(t *testing.T) {
969         r := noRRSetupTest("bogus")
970         s := "Error: unknown command \"bogus\" for \"cobra-test\"\nRun 'cobra-test --help' for usage.\n"
971
972         if r.Output != s {
973                 t.Errorf("Unexpected response.\nExpecting to be:\n %q\nGot:\n %q\n", s, r.Output)
974         }
975
976         r = noRRSetupTest("--strtwo=a", "bogus")
977         if r.Output != s {
978                 t.Errorf("Unexpected response.\nExpecting to be:\n %q\nGot:\n %q\n", s, r.Output)
979         }
980 }
981
982 func TestRootUnknownCommandSilenced(t *testing.T) {
983         r := noRRSetupTestSilenced("bogus")
984
985         if r.Output != "" {
986                 t.Errorf("Unexpected response.\nExpecting to be: \n\"\"\n Got:\n %q\n", r.Output)
987         }
988
989         r = noRRSetupTestSilenced("--strtwo=a", "bogus")
990         if r.Output != "" {
991                 t.Errorf("Unexpected response.\nExpecting to be:\n\"\"\nGot:\n %q\n", r.Output)
992         }
993 }
994
995 func TestRootSuggestions(t *testing.T) {
996         outputWithSuggestions := "Error: unknown command \"%s\" for \"cobra-test\"\n\nDid you mean this?\n\t%s\n\nRun 'cobra-test --help' for usage.\n"
997         outputWithoutSuggestions := "Error: unknown command \"%s\" for \"cobra-test\"\nRun 'cobra-test --help' for usage.\n"
998
999         cmd := initializeWithRootCmd()
1000         cmd.AddCommand(cmdTimes)
1001
1002         tests := map[string]string{
1003                 "time":     "times",
1004                 "tiems":    "times",
1005                 "tims":     "times",
1006                 "timeS":    "times",
1007                 "rimes":    "times",
1008                 "ti":       "times",
1009                 "t":        "times",
1010                 "timely":   "times",
1011                 "ri":       "",
1012                 "timezone": "",
1013                 "foo":      "",
1014                 "counts":   "times",
1015         }
1016
1017         for typo, suggestion := range tests {
1018                 for _, suggestionsDisabled := range []bool{false, true} {
1019                         cmd.DisableSuggestions = suggestionsDisabled
1020                         result := simpleTester(cmd, typo)
1021                         expected := ""
1022                         if len(suggestion) == 0 || suggestionsDisabled {
1023                                 expected = fmt.Sprintf(outputWithoutSuggestions, typo)
1024                         } else {
1025                                 expected = fmt.Sprintf(outputWithSuggestions, typo, suggestion)
1026                         }
1027                         if result.Output != expected {
1028                                 t.Errorf("Unexpected response.\nExpecting to be:\n %q\nGot:\n %q\n", expected, result.Output)
1029                         }
1030                 }
1031         }
1032 }
1033
1034 func TestFlagsBeforeCommand(t *testing.T) {
1035         // short without space
1036         x := fullSetupTest("-i10", "echo")
1037         if x.Error != nil {
1038                 t.Errorf("Valid Input shouldn't have errors, got:\n %q", x.Error)
1039         }
1040
1041         x = noRRSetupTest("echo", "-i=10")
1042         if x.Error != nil {
1043                 t.Errorf("Valid Input shouldn't have errors, got:\n %s", x.Error)
1044         }
1045
1046         // long with equals
1047         x = noRRSetupTest("--intone=123", "echo", "one", "two")
1048         if x.Error != nil {
1049                 t.Errorf("Valid Input shouldn't have errors, got:\n %s", x.Error)
1050         }
1051
1052         // With parsing error properly reported
1053         x = fullSetupTest("-i10E", "echo")
1054         if !strings.Contains(x.Error.Error(), "invalid syntax") {
1055                 t.Errorf("Wrong error message displayed, \n %s", x.Error)
1056         }
1057 }
1058
1059 func TestRemoveCommand(t *testing.T) {
1060         versionUsed = 0
1061         c := initializeWithRootCmd()
1062         c.AddCommand(cmdVersion1)
1063         c.RemoveCommand(cmdVersion1)
1064         x := fullTester(c, "version")
1065         if x.Error == nil {
1066                 t.Errorf("Removed command should not have been called\n")
1067                 return
1068         }
1069 }
1070
1071 func TestCommandWithoutSubcommands(t *testing.T) {
1072         c := initializeWithRootCmd()
1073
1074         x := simpleTester(c, "")
1075         if x.Error != nil {
1076                 t.Errorf("Calling command without subcommands should not have error: %v", x.Error)
1077                 return
1078         }
1079 }
1080
1081 func TestCommandWithoutSubcommandsWithArg(t *testing.T) {
1082         c := initializeWithRootCmd()
1083         expectedArgs := []string{"arg"}
1084
1085         x := simpleTester(c, "arg")
1086         if x.Error != nil {
1087                 t.Errorf("Calling command without subcommands but with arg should not have error: %v", x.Error)
1088                 return
1089         }
1090         if !reflect.DeepEqual(expectedArgs, tr) {
1091                 t.Errorf("Calling command without subcommands but with arg has wrong args: expected: %v, actual: %v", expectedArgs, tr)
1092                 return
1093         }
1094 }
1095
1096 func TestReplaceCommandWithRemove(t *testing.T) {
1097         versionUsed = 0
1098         c := initializeWithRootCmd()
1099         c.AddCommand(cmdVersion1)
1100         c.RemoveCommand(cmdVersion1)
1101         c.AddCommand(cmdVersion2)
1102         x := fullTester(c, "version")
1103         if x.Error != nil {
1104                 t.Errorf("Valid Input shouldn't have errors, got:\n %q", x.Error)
1105                 return
1106         }
1107         if versionUsed == 1 {
1108                 t.Errorf("Removed command shouldn't be called\n")
1109         }
1110         if versionUsed != 2 {
1111                 t.Errorf("Replacing command should have been called but didn't\n")
1112         }
1113 }
1114
1115 func TestDeprecatedSub(t *testing.T) {
1116         c := fullSetupTest("deprecated")
1117
1118         checkResultContains(t, c, cmdDeprecated.Deprecated)
1119 }
1120
1121 func TestPreRun(t *testing.T) {
1122         noRRSetupTest("echo", "one", "two")
1123         if echoPre == nil || echoPersPre == nil {
1124                 t.Error("PreRun or PersistentPreRun not called")
1125         }
1126         if rootPersPre != nil || timesPersPre != nil {
1127                 t.Error("Wrong *Pre functions called!")
1128         }
1129
1130         noRRSetupTest("echo", "times", "one", "two")
1131         if timesPersPre == nil {
1132                 t.Error("PreRun or PersistentPreRun not called")
1133         }
1134         if echoPre != nil || echoPersPre != nil || rootPersPre != nil {
1135                 t.Error("Wrong *Pre functions called!")
1136         }
1137
1138         noRRSetupTest("print", "one", "two")
1139         if rootPersPre == nil {
1140                 t.Error("Parent PersistentPreRun not called but should not have been")
1141         }
1142         if echoPre != nil || echoPersPre != nil || timesPersPre != nil {
1143                 t.Error("Wrong *Pre functions called!")
1144         }
1145 }
1146
1147 // Check if cmdEchoSub gets PersistentPreRun from rootCmd even if is added last
1148 func TestPeristentPreRunPropagation(t *testing.T) {
1149         rootCmd := initialize()
1150
1151         // First add the cmdEchoSub to cmdPrint
1152         cmdPrint.AddCommand(cmdEchoSub)
1153         // Now add cmdPrint to rootCmd
1154         rootCmd.AddCommand(cmdPrint)
1155
1156         rootCmd.SetArgs([]string{"print", "echosub", "lala"})
1157         rootCmd.Execute()
1158
1159         if len(rootPersPre) == 0 || rootPersPre[0] != "lala" {
1160                 t.Error("RootCmd PersistentPreRun not called but should have been")
1161         }
1162 }
1163
1164 func TestGlobalNormFuncPropagation(t *testing.T) {
1165         normFunc := func(f *pflag.FlagSet, name string) pflag.NormalizedName {
1166                 return pflag.NormalizedName(name)
1167         }
1168
1169         rootCmd := initialize()
1170         rootCmd.AddCommand(cmdEcho)
1171
1172         rootCmd.SetGlobalNormalizationFunc(normFunc)
1173         if reflect.ValueOf(normFunc).Pointer() != reflect.ValueOf(rootCmd.GlobalNormalizationFunc()).Pointer() {
1174                 t.Error("rootCmd seems to have a wrong normalization function")
1175         }
1176
1177         // Also check it propagates retroactively
1178         if reflect.ValueOf(normFunc).Pointer() != reflect.ValueOf(cmdEcho.GlobalNormalizationFunc()).Pointer() {
1179                 t.Error("cmdEcho should have had the normalization function of rootCmd")
1180         }
1181
1182         // First add the cmdEchoSub to cmdPrint
1183         cmdPrint.AddCommand(cmdEchoSub)
1184         if cmdPrint.GlobalNormalizationFunc() != nil && cmdEchoSub.GlobalNormalizationFunc() != nil {
1185                 t.Error("cmdPrint and cmdEchoSub should had no normalization functions")
1186         }
1187
1188         // Now add cmdPrint to rootCmd
1189         rootCmd.AddCommand(cmdPrint)
1190         if reflect.ValueOf(cmdPrint.GlobalNormalizationFunc()).Pointer() != reflect.ValueOf(rootCmd.GlobalNormalizationFunc()).Pointer() ||
1191                 reflect.ValueOf(cmdEchoSub.GlobalNormalizationFunc()).Pointer() != reflect.ValueOf(rootCmd.GlobalNormalizationFunc()).Pointer() {
1192                 t.Error("cmdPrint and cmdEchoSub should had the normalization function of rootCmd")
1193         }
1194 }
1195
1196 func TestNormPassedOnLocal(t *testing.T) {
1197         n := func(f *pflag.FlagSet, name string) pflag.NormalizedName {
1198                 return pflag.NormalizedName(strings.ToUpper(name))
1199         }
1200
1201         cmd := &Command{}
1202         flagVal := false
1203
1204         cmd.Flags().BoolVar(&flagVal, "flagname", true, "this is a dummy flag")
1205         cmd.SetGlobalNormalizationFunc(n)
1206         if cmd.LocalFlags().Lookup("flagname") != cmd.LocalFlags().Lookup("FLAGNAME") {
1207                 t.Error("Normalization function should be passed on to Local flag set")
1208         }
1209 }
1210
1211 func TestNormPassedOnInherited(t *testing.T) {
1212         n := func(f *pflag.FlagSet, name string) pflag.NormalizedName {
1213                 return pflag.NormalizedName(strings.ToUpper(name))
1214         }
1215
1216         cmd, childBefore, childAfter := &Command{}, &Command{}, &Command{}
1217         flagVal := false
1218         cmd.AddCommand(childBefore)
1219
1220         cmd.PersistentFlags().BoolVar(&flagVal, "flagname", true, "this is a dummy flag")
1221         cmd.SetGlobalNormalizationFunc(n)
1222
1223         cmd.AddCommand(childAfter)
1224
1225         if f := childBefore.InheritedFlags(); f.Lookup("flagname") == nil || f.Lookup("flagname") != f.Lookup("FLAGNAME") {
1226                 t.Error("Normalization function should be passed on to inherited flag set in command added before flag")
1227         }
1228         if f := childAfter.InheritedFlags(); f.Lookup("flagname") == nil || f.Lookup("flagname") != f.Lookup("FLAGNAME") {
1229                 t.Error("Normalization function should be passed on to inherited flag set in command added after flag")
1230         }
1231 }
1232
1233 // Related to https://github.com/spf13/cobra/issues/521.
1234 func TestNormConsistent(t *testing.T) {
1235         n := func(f *pflag.FlagSet, name string) pflag.NormalizedName {
1236                 return pflag.NormalizedName(strings.ToUpper(name))
1237         }
1238         id := func(f *pflag.FlagSet, name string) pflag.NormalizedName {
1239                 return pflag.NormalizedName(name)
1240         }
1241
1242         cmd := &Command{}
1243         flagVal := false
1244
1245         cmd.Flags().BoolVar(&flagVal, "flagname", true, "this is a dummy flag")
1246         // Build local flag set
1247         cmd.LocalFlags()
1248
1249         cmd.SetGlobalNormalizationFunc(n)
1250         cmd.SetGlobalNormalizationFunc(id)
1251
1252         if cmd.LocalFlags().Lookup("flagname") == cmd.LocalFlags().Lookup("FLAGNAME") {
1253                 t.Error("Normalizing flag names should not result in duplicate flags")
1254         }
1255 }
1256
1257 func TestFlagOnPflagCommandLine(t *testing.T) {
1258         flagName := "flagOnCommandLine"
1259         pflag.String(flagName, "", "about my flag")
1260         r := fullSetupTest("--help")
1261
1262         checkResultContains(t, r, flagName)
1263
1264         // Reset pflag.CommandLine flagset.
1265         pflag.CommandLine = pflag.NewFlagSet(os.Args[0], pflag.ExitOnError)
1266 }
1267
1268 func TestAddTemplateFunctions(t *testing.T) {
1269         AddTemplateFunc("t", func() bool { return true })
1270         AddTemplateFuncs(template.FuncMap{
1271                 "f": func() bool { return false },
1272                 "h": func() string { return "Hello," },
1273                 "w": func() string { return "world." }})
1274
1275         const usage = "Hello, world."
1276
1277         c := &Command{}
1278         c.SetUsageTemplate(`{{if t}}{{h}}{{end}}{{if f}}{{h}}{{end}} {{w}}`)
1279
1280         if us := c.UsageString(); us != usage {
1281                 t.Errorf("c.UsageString() != \"%s\", is \"%s\"", usage, us)
1282         }
1283 }
1284
1285 func TestUsageIsNotPrintedTwice(t *testing.T) {
1286         var cmd = &Command{Use: "root"}
1287         var sub = &Command{Use: "sub"}
1288         cmd.AddCommand(sub)
1289
1290         r := simpleTester(cmd, "")
1291         if strings.Count(r.Output, "Usage:") != 1 {
1292                 t.Error("Usage output is not printed exactly once")
1293         }
1294 }
1295
1296 func BenchmarkInheritedFlags(b *testing.B) {
1297         initialize()
1298         cmdEcho.AddCommand(cmdTimes)
1299         b.ResetTimer()
1300
1301         for i := 0; i < b.N; i++ {
1302                 cmdTimes.InheritedFlags()
1303         }
1304 }
1305
1306 func BenchmarkLocalFlags(b *testing.B) {
1307         initialize()
1308         cmdEcho.AddCommand(cmdTimes)
1309         b.ResetTimer()
1310
1311         for i := 0; i < b.N; i++ {
1312                 cmdTimes.LocalFlags()
1313         }
1314 }