github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/testing/cmd.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package testing 5 6 import ( 7 "bytes" 8 "io/ioutil" 9 "strings" 10 11 "github.com/juju/cmd" 12 jc "github.com/juju/testing/checkers" 13 gc "gopkg.in/check.v1" 14 "launchpad.net/gnuflag" 15 ) 16 17 // NewFlagSet creates a new flag set using the standard options, particularly 18 // the option to stop the gnuflag methods from writing to StdErr or StdOut. 19 func NewFlagSet() *gnuflag.FlagSet { 20 fs := gnuflag.NewFlagSet("", gnuflag.ContinueOnError) 21 fs.SetOutput(ioutil.Discard) 22 return fs 23 } 24 25 // InitCommand will create a new flag set, and call the Command's SetFlags and 26 // Init methods with the appropriate args. 27 func InitCommand(c cmd.Command, args []string) error { 28 f := NewFlagSet() 29 c.SetFlags(f) 30 if err := f.Parse(c.AllowInterspersedFlags(), args); err != nil { 31 return err 32 } 33 return c.Init(f.Args()) 34 } 35 36 // Context creates a simple command execution context with the current 37 // dir set to a newly created directory within the test directory. 38 func Context(c *gc.C) *cmd.Context { 39 return &cmd.Context{ 40 Dir: c.MkDir(), 41 Stdin: &bytes.Buffer{}, 42 Stdout: &bytes.Buffer{}, 43 Stderr: &bytes.Buffer{}, 44 } 45 } 46 47 // ContextForDir creates a simple command execution context with the current 48 // dir set to the specified directory. 49 func ContextForDir(c *gc.C, dir string) *cmd.Context { 50 return &cmd.Context{ 51 Dir: dir, 52 Stdin: &bytes.Buffer{}, 53 Stdout: &bytes.Buffer{}, 54 Stderr: &bytes.Buffer{}, 55 } 56 } 57 58 // Stdout takes a command Context that we assume has been created in this 59 // package, and gets the content of the Stdout buffer as a string. 60 func Stdout(ctx *cmd.Context) string { 61 return ctx.Stdout.(*bytes.Buffer).String() 62 } 63 64 // Stderr takes a command Context that we assume has been created in this 65 // package, and gets the content of the Stderr buffer as a string. 66 func Stderr(ctx *cmd.Context) string { 67 return ctx.Stderr.(*bytes.Buffer).String() 68 } 69 70 // RunCommand runs a command with the specified args. The returned error 71 // may come from either the parsing of the args, the command initialisation, or 72 // the actual running of the command. Access to the resulting output streams 73 // is provided through the returned context instance. 74 func RunCommand(c *gc.C, com cmd.Command, args ...string) (*cmd.Context, error) { 75 if err := InitCommand(com, args); err != nil { 76 return nil, err 77 } 78 var context = Context(c) 79 return context, com.Run(context) 80 } 81 82 // RunCommandInDir works like RunCommand, but runs with a context that uses dir. 83 func RunCommandInDir(c *gc.C, com cmd.Command, args []string, dir string) (*cmd.Context, error) { 84 if err := InitCommand(com, args); err != nil { 85 return nil, err 86 } 87 var context = ContextForDir(c, dir) 88 return context, com.Run(context) 89 } 90 91 // TestInit checks that a command initialises correctly with the given set of 92 // arguments. 93 func TestInit(c *gc.C, com cmd.Command, args []string, errPat string) { 94 err := InitCommand(com, args) 95 if errPat != "" { 96 c.Assert(err, gc.ErrorMatches, errPat) 97 } else { 98 c.Assert(err, jc.ErrorIsNil) 99 } 100 } 101 102 // ExtractCommandsFromHelpOutput takes the standard output from the 103 // command context and looks for the "commands:" string and returns the 104 // commands output after that. 105 func ExtractCommandsFromHelpOutput(ctx *cmd.Context) []string { 106 var namesFound []string 107 commandHelp := strings.SplitAfter(Stdout(ctx), "commands:")[1] 108 commandHelp = strings.TrimSpace(commandHelp) 109 for _, line := range strings.Split(commandHelp, "\n") { 110 namesFound = append(namesFound, strings.TrimSpace(strings.Split(line, " - ")[0])) 111 } 112 return namesFound 113 }