Merge pull request #364 from codegangsta/assert-before-command-after-ordering

Revising/adding tests that assert order of operations inside App.Run
main
Dan Buch 9 years ago
commit 222ec6fb7e

@ -13,6 +13,10 @@ import (
"testing" "testing"
) )
type opCounts struct {
Total, BashComplete, OnUsageError, Before, CommandNotFound, Action, After, SubCommand int
}
func ExampleApp_Run() { func ExampleApp_Run() {
// set args for examples sake // set args for examples sake
os.Args = []string{"greet", "--name", "Jeremy"} os.Args = []string{"greet", "--name", "Jeremy"}
@ -439,14 +443,15 @@ func TestApp_SetStdout(t *testing.T) {
} }
func TestApp_BeforeFunc(t *testing.T) { func TestApp_BeforeFunc(t *testing.T) {
beforeRun, subcommandRun := false, false counts := &opCounts{}
beforeError := fmt.Errorf("fail") beforeError := fmt.Errorf("fail")
var err error var err error
app := NewApp() app := NewApp()
app.Before = func(c *Context) error { app.Before = func(c *Context) error {
beforeRun = true counts.Total++
counts.Before = counts.Total
s := c.String("opt") s := c.String("opt")
if s == "fail" { if s == "fail" {
return beforeError return beforeError
@ -459,7 +464,8 @@ func TestApp_BeforeFunc(t *testing.T) {
Command{ Command{
Name: "sub", Name: "sub",
Action: func(c *Context) { Action: func(c *Context) {
subcommandRun = true counts.Total++
counts.SubCommand = counts.Total
}, },
}, },
} }
@ -475,16 +481,16 @@ func TestApp_BeforeFunc(t *testing.T) {
t.Fatalf("Run error: %s", err) t.Fatalf("Run error: %s", err)
} }
if beforeRun == false { if counts.Before != 1 {
t.Errorf("Before() not executed when expected") t.Errorf("Before() not executed when expected")
} }
if subcommandRun == false { if counts.SubCommand != 2 {
t.Errorf("Subcommand not executed when expected") t.Errorf("Subcommand not executed when expected")
} }
// reset // reset
beforeRun, subcommandRun = false, false counts = &opCounts{}
// run with the Before() func failing // run with the Before() func failing
err = app.Run([]string{"command", "--opt", "fail", "sub"}) err = app.Run([]string{"command", "--opt", "fail", "sub"})
@ -494,25 +500,26 @@ func TestApp_BeforeFunc(t *testing.T) {
t.Errorf("Run error expected, but not received") t.Errorf("Run error expected, but not received")
} }
if beforeRun == false { if counts.Before != 1 {
t.Errorf("Before() not executed when expected") t.Errorf("Before() not executed when expected")
} }
if subcommandRun == true { if counts.SubCommand != 0 {
t.Errorf("Subcommand executed when NOT expected") t.Errorf("Subcommand executed when NOT expected")
} }
} }
func TestApp_AfterFunc(t *testing.T) { func TestApp_AfterFunc(t *testing.T) {
afterRun, subcommandRun := false, false counts := &opCounts{}
afterError := fmt.Errorf("fail") afterError := fmt.Errorf("fail")
var err error var err error
app := NewApp() app := NewApp()
app.After = func(c *Context) error { app.After = func(c *Context) error {
afterRun = true counts.Total++
counts.After = counts.Total
s := c.String("opt") s := c.String("opt")
if s == "fail" { if s == "fail" {
return afterError return afterError
@ -525,7 +532,8 @@ func TestApp_AfterFunc(t *testing.T) {
Command{ Command{
Name: "sub", Name: "sub",
Action: func(c *Context) { Action: func(c *Context) {
subcommandRun = true counts.Total++
counts.SubCommand = counts.Total
}, },
}, },
} }
@ -541,16 +549,16 @@ func TestApp_AfterFunc(t *testing.T) {
t.Fatalf("Run error: %s", err) t.Fatalf("Run error: %s", err)
} }
if afterRun == false { if counts.After != 2 {
t.Errorf("After() not executed when expected") t.Errorf("After() not executed when expected")
} }
if subcommandRun == false { if counts.SubCommand != 1 {
t.Errorf("Subcommand not executed when expected") t.Errorf("Subcommand not executed when expected")
} }
// reset // reset
afterRun, subcommandRun = false, false counts = &opCounts{}
// run with the Before() func failing // run with the Before() func failing
err = app.Run([]string{"command", "--opt", "fail", "sub"}) err = app.Run([]string{"command", "--opt", "fail", "sub"})
@ -560,11 +568,11 @@ func TestApp_AfterFunc(t *testing.T) {
t.Errorf("Run error expected, but not received") t.Errorf("Run error expected, but not received")
} }
if afterRun == false { if counts.After != 2 {
t.Errorf("After() not executed when expected") t.Errorf("After() not executed when expected")
} }
if subcommandRun == false { if counts.SubCommand != 1 {
t.Errorf("Subcommand not executed when expected") t.Errorf("Subcommand not executed when expected")
} }
} }
@ -605,7 +613,7 @@ func TestAppHelpPrinter(t *testing.T) {
} }
} }
func TestAppVersionPrinter(t *testing.T) { func TestApp_VersionPrinter(t *testing.T) {
oldPrinter := VersionPrinter oldPrinter := VersionPrinter
defer func() { defer func() {
VersionPrinter = oldPrinter VersionPrinter = oldPrinter
@ -625,81 +633,168 @@ func TestAppVersionPrinter(t *testing.T) {
} }
} }
func TestAppCommandNotFound(t *testing.T) { func TestApp_CommandNotFound(t *testing.T) {
beforeRun, subcommandRun := false, false counts := &opCounts{}
app := NewApp() app := NewApp()
app.CommandNotFound = func(c *Context, command string) { app.CommandNotFound = func(c *Context, command string) {
beforeRun = true counts.Total++
counts.CommandNotFound = counts.Total
} }
app.Commands = []Command{ app.Commands = []Command{
Command{ Command{
Name: "bar", Name: "bar",
Action: func(c *Context) { Action: func(c *Context) {
subcommandRun = true counts.Total++
counts.SubCommand = counts.Total
}, },
}, },
} }
app.Run([]string{"command", "foo"}) app.Run([]string{"command", "foo"})
expect(t, beforeRun, true) expect(t, counts.CommandNotFound, 1)
expect(t, subcommandRun, false) expect(t, counts.SubCommand, 0)
expect(t, counts.Total, 1)
} }
func TestGlobalFlag(t *testing.T) { func TestApp_OrderOfOperations(t *testing.T) {
var globalFlag string counts := &opCounts{}
var globalFlagSet bool
resetCounts := func() { counts = &opCounts{} }
app := NewApp() app := NewApp()
app.Flags = []Flag{ app.EnableBashCompletion = true
StringFlag{Name: "global, g", Usage: "global"}, app.BashComplete = func(c *Context) {
counts.Total++
counts.BashComplete = counts.Total
} }
app.Action = func(c *Context) { app.OnUsageError = func(c *Context, err error, isSubcommand bool) error {
globalFlag = c.GlobalString("global") counts.Total++
globalFlagSet = c.GlobalIsSet("global") counts.OnUsageError = counts.Total
return errors.New("hay OnUsageError")
} }
app.Run([]string{"command", "-g", "foo"})
expect(t, globalFlag, "foo")
expect(t, globalFlagSet, true)
} beforeNoError := func(c *Context) error {
counts.Total++
counts.Before = counts.Total
return nil
}
func TestGlobalFlagsInSubcommands(t *testing.T) { beforeError := func(c *Context) error {
subcommandRun := false counts.Total++
parentFlag := false counts.Before = counts.Total
app := NewApp() return errors.New("hay Before")
}
app.Flags = []Flag{ app.Before = beforeNoError
BoolFlag{Name: "debug, d", Usage: "Enable debugging"}, app.CommandNotFound = func(c *Context, command string) {
counts.Total++
counts.CommandNotFound = counts.Total
} }
afterNoError := func(c *Context) error {
counts.Total++
counts.After = counts.Total
return nil
}
afterError := func(c *Context) error {
counts.Total++
counts.After = counts.Total
return errors.New("hay After")
}
app.After = afterNoError
app.Commands = []Command{ app.Commands = []Command{
Command{ Command{
Name: "foo",
Flags: []Flag{
BoolFlag{Name: "parent, p", Usage: "Parent flag"},
},
Subcommands: []Command{
{
Name: "bar", Name: "bar",
Action: func(c *Context) { Action: func(c *Context) {
if c.GlobalBool("debug") { counts.Total++
subcommandRun = true counts.SubCommand = counts.Total
}
if c.GlobalBool("parent") {
parentFlag = true
}
},
},
}, },
}, },
} }
app.Run([]string{"command", "-d", "foo", "-p", "bar"}) app.Action = func(c *Context) {
counts.Total++
counts.Action = counts.Total
}
_ = app.Run([]string{"command", "--nope"})
expect(t, counts.OnUsageError, 1)
expect(t, counts.Total, 1)
resetCounts()
expect(t, subcommandRun, true) _ = app.Run([]string{"command", "--generate-bash-completion"})
expect(t, parentFlag, true) expect(t, counts.BashComplete, 1)
expect(t, counts.Total, 1)
resetCounts()
oldOnUsageError := app.OnUsageError
app.OnUsageError = nil
_ = app.Run([]string{"command", "--nope"})
expect(t, counts.Total, 0)
app.OnUsageError = oldOnUsageError
resetCounts()
_ = app.Run([]string{"command", "foo"})
expect(t, counts.OnUsageError, 0)
expect(t, counts.Before, 1)
expect(t, counts.CommandNotFound, 0)
expect(t, counts.Action, 2)
expect(t, counts.After, 3)
expect(t, counts.Total, 3)
resetCounts()
app.Before = beforeError
_ = app.Run([]string{"command", "bar"})
expect(t, counts.OnUsageError, 0)
expect(t, counts.Before, 1)
expect(t, counts.After, 2)
expect(t, counts.Total, 2)
app.Before = beforeNoError
resetCounts()
app.After = nil
_ = app.Run([]string{"command", "bar"})
expect(t, counts.OnUsageError, 0)
expect(t, counts.Before, 1)
expect(t, counts.SubCommand, 2)
expect(t, counts.Total, 2)
app.After = afterNoError
resetCounts()
app.After = afterError
err := app.Run([]string{"command", "bar"})
if err == nil {
t.Fatalf("expected a non-nil error")
}
expect(t, counts.OnUsageError, 0)
expect(t, counts.Before, 1)
expect(t, counts.SubCommand, 2)
expect(t, counts.After, 3)
expect(t, counts.Total, 3)
app.After = afterNoError
resetCounts()
oldCommands := app.Commands
app.Commands = nil
_ = app.Run([]string{"command"})
expect(t, counts.OnUsageError, 0)
expect(t, counts.Before, 1)
expect(t, counts.Action, 2)
expect(t, counts.After, 3)
expect(t, counts.Total, 3)
app.Commands = oldCommands
} }
func TestApp_Run_CommandWithSubcommandHasHelpTopic(t *testing.T) { func TestApp_Run_CommandWithSubcommandHasHelpTopic(t *testing.T) {

@ -146,3 +146,57 @@ func TestContext_NumFlags(t *testing.T) {
globalSet.Parse([]string{"--myflagGlobal"}) globalSet.Parse([]string{"--myflagGlobal"})
expect(t, c.NumFlags(), 2) expect(t, c.NumFlags(), 2)
} }
func TestContext_GlobalFlag(t *testing.T) {
var globalFlag string
var globalFlagSet bool
app := NewApp()
app.Flags = []Flag{
StringFlag{Name: "global, g", Usage: "global"},
}
app.Action = func(c *Context) {
globalFlag = c.GlobalString("global")
globalFlagSet = c.GlobalIsSet("global")
}
app.Run([]string{"command", "-g", "foo"})
expect(t, globalFlag, "foo")
expect(t, globalFlagSet, true)
}
func TestContext_GlobalFlagsInSubcommands(t *testing.T) {
subcommandRun := false
parentFlag := false
app := NewApp()
app.Flags = []Flag{
BoolFlag{Name: "debug, d", Usage: "Enable debugging"},
}
app.Commands = []Command{
Command{
Name: "foo",
Flags: []Flag{
BoolFlag{Name: "parent, p", Usage: "Parent flag"},
},
Subcommands: []Command{
{
Name: "bar",
Action: func(c *Context) {
if c.GlobalBool("debug") {
subcommandRun = true
}
if c.GlobalBool("parent") {
parentFlag = true
}
},
},
},
},
}
app.Run([]string{"command", "-d", "foo", "-p", "bar"})
expect(t, subcommandRun, true)
expect(t, parentFlag, true)
}

@ -1,14 +1,23 @@
package cli package cli
import ( import (
"os"
"reflect" "reflect"
"runtime"
"strings"
"testing" "testing"
) )
/* Test Helpers */ var (
wd, _ = os.Getwd()
)
func expect(t *testing.T, a interface{}, b interface{}) { func expect(t *testing.T, a interface{}, b interface{}) {
_, fn, line, _ := runtime.Caller(1)
fn = strings.Replace(fn, wd+"/", "", -1)
if !reflect.DeepEqual(a, b) { if !reflect.DeepEqual(a, b) {
t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a)) t.Errorf("(%s:%d) Expected %v (type %v) - Got %v (type %v)", fn, line, b, reflect.TypeOf(b), a, reflect.TypeOf(a))
} }
} }

Loading…
Cancel
Save