Merge remote-tracking branch 'origin/master' into string-slice-flag-default-160
This commit is contained in:
commit
ee736e063a
@ -7,6 +7,9 @@
|
||||
### Added
|
||||
- Support for placeholders in flag usage strings
|
||||
|
||||
### Fixed
|
||||
- Added missing `*cli.Context.GlobalFloat64` method
|
||||
|
||||
## [2.0.0]
|
||||
### Added
|
||||
- `NewStringSlice` and `NewIntSlice` for creating their related types
|
||||
|
219
app_test.go
219
app_test.go
@ -13,6 +13,10 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type opCounts struct {
|
||||
Total, BashComplete, OnUsageError, Before, CommandNotFound, Action, After, SubCommand int
|
||||
}
|
||||
|
||||
func ExampleApp_Run() {
|
||||
// set args for examples sake
|
||||
os.Args = []string{"greet", "--name", "Jeremy"}
|
||||
@ -439,14 +443,15 @@ func TestApp_SetStdout(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestApp_BeforeFunc(t *testing.T) {
|
||||
beforeRun, subcommandRun := false, false
|
||||
counts := &opCounts{}
|
||||
beforeError := fmt.Errorf("fail")
|
||||
var err error
|
||||
|
||||
app := NewApp()
|
||||
|
||||
app.Before = func(c *Context) error {
|
||||
beforeRun = true
|
||||
counts.Total++
|
||||
counts.Before = counts.Total
|
||||
s := c.String("opt")
|
||||
if s == "fail" {
|
||||
return beforeError
|
||||
@ -459,7 +464,8 @@ func TestApp_BeforeFunc(t *testing.T) {
|
||||
Command{
|
||||
Name: "sub",
|
||||
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)
|
||||
}
|
||||
|
||||
if beforeRun == false {
|
||||
if counts.Before != 1 {
|
||||
t.Errorf("Before() not executed when expected")
|
||||
}
|
||||
|
||||
if subcommandRun == false {
|
||||
if counts.SubCommand != 2 {
|
||||
t.Errorf("Subcommand not executed when expected")
|
||||
}
|
||||
|
||||
// reset
|
||||
beforeRun, subcommandRun = false, false
|
||||
counts = &opCounts{}
|
||||
|
||||
// run with the Before() func failing
|
||||
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")
|
||||
}
|
||||
|
||||
if beforeRun == false {
|
||||
if counts.Before != 1 {
|
||||
t.Errorf("Before() not executed when expected")
|
||||
}
|
||||
|
||||
if subcommandRun == true {
|
||||
if counts.SubCommand != 0 {
|
||||
t.Errorf("Subcommand executed when NOT expected")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestApp_AfterFunc(t *testing.T) {
|
||||
afterRun, subcommandRun := false, false
|
||||
counts := &opCounts{}
|
||||
afterError := fmt.Errorf("fail")
|
||||
var err error
|
||||
|
||||
app := NewApp()
|
||||
|
||||
app.After = func(c *Context) error {
|
||||
afterRun = true
|
||||
counts.Total++
|
||||
counts.After = counts.Total
|
||||
s := c.String("opt")
|
||||
if s == "fail" {
|
||||
return afterError
|
||||
@ -525,7 +532,8 @@ func TestApp_AfterFunc(t *testing.T) {
|
||||
Command{
|
||||
Name: "sub",
|
||||
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)
|
||||
}
|
||||
|
||||
if afterRun == false {
|
||||
if counts.After != 2 {
|
||||
t.Errorf("After() not executed when expected")
|
||||
}
|
||||
|
||||
if subcommandRun == false {
|
||||
if counts.SubCommand != 1 {
|
||||
t.Errorf("Subcommand not executed when expected")
|
||||
}
|
||||
|
||||
// reset
|
||||
afterRun, subcommandRun = false, false
|
||||
counts = &opCounts{}
|
||||
|
||||
// run with the Before() func failing
|
||||
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")
|
||||
}
|
||||
|
||||
if afterRun == false {
|
||||
if counts.After != 2 {
|
||||
t.Errorf("After() not executed when expected")
|
||||
}
|
||||
|
||||
if subcommandRun == false {
|
||||
if counts.SubCommand != 1 {
|
||||
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
|
||||
defer func() {
|
||||
VersionPrinter = oldPrinter
|
||||
@ -625,81 +633,168 @@ func TestAppVersionPrinter(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppCommandNotFound(t *testing.T) {
|
||||
beforeRun, subcommandRun := false, false
|
||||
func TestApp_CommandNotFound(t *testing.T) {
|
||||
counts := &opCounts{}
|
||||
app := NewApp()
|
||||
|
||||
app.CommandNotFound = func(c *Context, command string) {
|
||||
beforeRun = true
|
||||
counts.Total++
|
||||
counts.CommandNotFound = counts.Total
|
||||
}
|
||||
|
||||
app.Commands = []Command{
|
||||
Command{
|
||||
Name: "bar",
|
||||
Action: func(c *Context) {
|
||||
subcommandRun = true
|
||||
counts.Total++
|
||||
counts.SubCommand = counts.Total
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.Run([]string{"command", "foo"})
|
||||
|
||||
expect(t, beforeRun, true)
|
||||
expect(t, subcommandRun, false)
|
||||
expect(t, counts.CommandNotFound, 1)
|
||||
expect(t, counts.SubCommand, 0)
|
||||
expect(t, counts.Total, 1)
|
||||
}
|
||||
|
||||
func TestGlobalFlag(t *testing.T) {
|
||||
var globalFlag string
|
||||
var globalFlagSet bool
|
||||
func TestApp_OrderOfOperations(t *testing.T) {
|
||||
counts := &opCounts{}
|
||||
|
||||
resetCounts := func() { counts = &opCounts{} }
|
||||
|
||||
app := NewApp()
|
||||
app.Flags = []Flag{
|
||||
StringFlag{Name: "global, g", Usage: "global"},
|
||||
app.EnableBashCompletion = true
|
||||
app.BashComplete = func(c *Context) {
|
||||
counts.Total++
|
||||
counts.BashComplete = counts.Total
|
||||
}
|
||||
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 TestGlobalFlagsInSubcommands(t *testing.T) {
|
||||
subcommandRun := false
|
||||
parentFlag := false
|
||||
app := NewApp()
|
||||
|
||||
app.Flags = []Flag{
|
||||
BoolFlag{Name: "debug, d", Usage: "Enable debugging"},
|
||||
app.OnUsageError = func(c *Context, err error, isSubcommand bool) error {
|
||||
counts.Total++
|
||||
counts.OnUsageError = counts.Total
|
||||
return errors.New("hay OnUsageError")
|
||||
}
|
||||
|
||||
beforeNoError := func(c *Context) error {
|
||||
counts.Total++
|
||||
counts.Before = counts.Total
|
||||
return nil
|
||||
}
|
||||
|
||||
beforeError := func(c *Context) error {
|
||||
counts.Total++
|
||||
counts.Before = counts.Total
|
||||
return errors.New("hay Before")
|
||||
}
|
||||
|
||||
app.Before = beforeNoError
|
||||
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{
|
||||
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
|
||||
}
|
||||
},
|
||||
},
|
||||
counts.Total++
|
||||
counts.SubCommand = counts.Total
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.Run([]string{"command", "-d", "foo", "-p", "bar"})
|
||||
app.Action = func(c *Context) {
|
||||
counts.Total++
|
||||
counts.Action = counts.Total
|
||||
}
|
||||
|
||||
expect(t, subcommandRun, true)
|
||||
expect(t, parentFlag, true)
|
||||
_ = app.Run([]string{"command", "--nope"})
|
||||
expect(t, counts.OnUsageError, 1)
|
||||
expect(t, counts.Total, 1)
|
||||
|
||||
resetCounts()
|
||||
|
||||
_ = app.Run([]string{"command", "--generate-bash-completion"})
|
||||
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) {
|
||||
|
@ -79,6 +79,15 @@ func (c *Context) GlobalInt(name string) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Looks up the value of a global float64 flag, returns float64(0) if no float64
|
||||
// flag exists
|
||||
func (c *Context) GlobalFloat64(name string) float64 {
|
||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
||||
return lookupFloat64(name, fs)
|
||||
}
|
||||
return float64(0)
|
||||
}
|
||||
|
||||
// Looks up the value of a global time.Duration flag, returns 0 if no time.Duration flag exists
|
||||
func (c *Context) GlobalDuration(name string) time.Duration {
|
||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
||||
|
@ -9,14 +9,18 @@ import (
|
||||
func TestNewContext(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Int("myflag", 12, "doc")
|
||||
set.Float64("myflag64", float64(17), "doc")
|
||||
globalSet := flag.NewFlagSet("test", 0)
|
||||
globalSet.Int("myflag", 42, "doc")
|
||||
globalSet.Float64("myflag64", float64(47), "doc")
|
||||
globalCtx := NewContext(nil, globalSet, nil)
|
||||
command := Command{Name: "mycommand"}
|
||||
c := NewContext(nil, set, globalCtx)
|
||||
c.Command = command
|
||||
expect(t, c.Int("myflag"), 12)
|
||||
expect(t, c.Float64("myflag64"), float64(17))
|
||||
expect(t, c.GlobalInt("myflag"), 42)
|
||||
expect(t, c.GlobalFloat64("myflag64"), float64(47))
|
||||
expect(t, c.Command.Name, "mycommand")
|
||||
}
|
||||
|
||||
@ -27,6 +31,29 @@ func TestContext_Int(t *testing.T) {
|
||||
expect(t, c.Int("myflag"), 12)
|
||||
}
|
||||
|
||||
func TestContext_GlobalInt(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Int("myflag", 12, "doc")
|
||||
c := NewContext(nil, set, nil)
|
||||
expect(t, c.GlobalInt("myflag"), 12)
|
||||
expect(t, c.GlobalInt("nope"), 0)
|
||||
}
|
||||
|
||||
func TestContext_Float64(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Float64("myflag", float64(17), "doc")
|
||||
c := NewContext(nil, set, nil)
|
||||
expect(t, c.Float64("myflag"), float64(17))
|
||||
}
|
||||
|
||||
func TestContext_GlobalFloat64(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Float64("myflag", float64(17), "doc")
|
||||
c := NewContext(nil, set, nil)
|
||||
expect(t, c.GlobalFloat64("myflag"), float64(17))
|
||||
expect(t, c.GlobalFloat64("nope"), float64(0))
|
||||
}
|
||||
|
||||
func TestContext_Duration(t *testing.T) {
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Duration("myflag", time.Duration(12*time.Second), "doc")
|
||||
@ -119,3 +146,57 @@ func TestContext_NumFlags(t *testing.T) {
|
||||
globalSet.Parse([]string{"--myflagGlobal"})
|
||||
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
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
/* Test Helpers */
|
||||
var (
|
||||
wd, _ = os.Getwd()
|
||||
)
|
||||
|
||||
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) {
|
||||
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…
Reference in New Issue
Block a user