github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/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 10 "launchpad.net/gnuflag" 11 gc "launchpad.net/gocheck" 12 13 "launchpad.net/juju-core/cmd" 14 ) 15 16 // NewFlagSet creates a new flag set using the standard options, particularly 17 // the option to stop the gnuflag methods from writing to StdErr or StdOut. 18 func NewFlagSet() *gnuflag.FlagSet { 19 fs := gnuflag.NewFlagSet("", gnuflag.ContinueOnError) 20 fs.SetOutput(ioutil.Discard) 21 return fs 22 } 23 24 // InitCommand will create a new flag set, and call the Command's SetFlags and 25 // Init methods with the appropriate args. 26 func InitCommand(c cmd.Command, args []string) error { 27 f := NewFlagSet() 28 c.SetFlags(f) 29 if err := f.Parse(c.AllowInterspersedFlags(), args); err != nil { 30 return err 31 } 32 return c.Init(f.Args()) 33 } 34 35 // Context creates a simple command execution context with the current 36 // dir set to a newly created directory within the test directory. 37 func Context(c *gc.C) *cmd.Context { 38 return &cmd.Context{ 39 Dir: c.MkDir(), 40 Stdin: &bytes.Buffer{}, 41 Stdout: &bytes.Buffer{}, 42 Stderr: &bytes.Buffer{}, 43 } 44 } 45 46 // ContextForDir creates a simple command execution context with the current 47 // dir set to the specified directory. 48 func ContextForDir(c *gc.C, dir string) *cmd.Context { 49 return &cmd.Context{ 50 Dir: dir, 51 Stdin: &bytes.Buffer{}, 52 Stdout: &bytes.Buffer{}, 53 Stderr: &bytes.Buffer{}, 54 } 55 } 56 57 // Stdout takes a command Context that we assume has been created in this 58 // package, and gets the content of the Stdout buffer as a string. 59 func Stdout(ctx *cmd.Context) string { 60 return ctx.Stdout.(*bytes.Buffer).String() 61 } 62 63 // Stderr takes a command Context that we assume has been created in this 64 // package, and gets the content of the Stderr buffer as a string. 65 func Stderr(ctx *cmd.Context) string { 66 return ctx.Stderr.(*bytes.Buffer).String() 67 } 68 69 // RunCommand runs a command with the specified args. The returned error 70 // may come from either the parsing of the args, the command initialisation, or 71 // the actual running of the command. Access to the resulting output streams 72 // is provided through the returned context instance. 73 func RunCommand(c *gc.C, com cmd.Command, args []string) (*cmd.Context, error) { 74 if err := InitCommand(com, args); err != nil { 75 return nil, err 76 } 77 var context = Context(c) 78 return context, com.Run(context) 79 } 80 81 // RunCommandInDir works like RunCommand, but runs with a context that uses dir. 82 func RunCommandInDir(c *gc.C, com cmd.Command, args []string, dir string) (*cmd.Context, error) { 83 if err := InitCommand(com, args); err != nil { 84 return nil, err 85 } 86 var context = ContextForDir(c, dir) 87 return context, com.Run(context) 88 } 89 90 // TestInit checks that a command initialises correctly with the given set of 91 // arguments. 92 func TestInit(c *gc.C, com cmd.Command, args []string, errPat string) { 93 err := InitCommand(com, args) 94 if errPat != "" { 95 c.Assert(err, gc.ErrorMatches, errPat) 96 } else { 97 c.Assert(err, gc.IsNil) 98 } 99 }