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  }