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