Skip to content

Commit

Permalink
Added 'Get' methods
Browse files Browse the repository at this point in the history
  • Loading branch information
ibraimgm committed Sep 26, 2019
1 parent 3918829 commit 69d8b6f
Show file tree
Hide file tree
Showing 4 changed files with 294 additions and 3 deletions.
121 changes: 121 additions & 0 deletions get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package libcmd

func (cmd *Cmd) getOptVal(name string) interface{} {
if opt := cmd.findOpt("-" + name); opt != nil {
return opt.val.raw
}

return cmd.findOpt("--" + name).val.raw
}

// GetString returns the string pointer used as value
// for the argument 'name' (you can use either the short or long name).
// If the argument does not exist, this routine panics.
func (cmd *Cmd) GetString(name string) *string {
return cmd.getOptVal(name).(*string)
}

// GetBool returns the bool pointer used as value
// for the argument 'name' (you can use either the short or long name).
// If the argument does not exist, this routine panics.
func (cmd *Cmd) GetBool(name string) *bool {
return cmd.getOptVal(name).(*bool)
}

// GetInt returns the int pointer used as value
// for the argument 'name' (you can use either the short or long name).
// If the argument does not exist, this routine panics.
func (cmd *Cmd) GetInt(name string) *int {
return cmd.getOptVal(name).(*int)
}

// GetInt8 returns the int8 pointer used as value
// for the argument 'name' (you can use either the short or long name).
// If the argument does not exist, this routine panics.
func (cmd *Cmd) GetInt8(name string) *int8 {
return cmd.getOptVal(name).(*int8)
}

// GetInt16 returns the int16 pointer used as value
// for the argument 'name' (you can use either the short or long name).
// If the argument does not exist, this routine panics.
func (cmd *Cmd) GetInt16(name string) *int16 {
return cmd.getOptVal(name).(*int16)
}

// GetInt32 returns the int32 pointer used as value
// for the argument 'name' (you can use either the short or long name).
// If the argument does not exist, this routine panics.
func (cmd *Cmd) GetInt32(name string) *int32 {
return cmd.getOptVal(name).(*int32)
}

// GetInt64 returns the int64 pointer used as value
// for the argument 'name' (you can use either the short or long name).
// If the argument does not exist, this routine panics.
func (cmd *Cmd) GetInt64(name string) *int64 {
return cmd.getOptVal(name).(*int64)
}

// GetUint returns the uint pointer used as value
// for the argument 'name' (you can use either the short or long name).
// If the argument does not exist, this routine panics.
func (cmd *Cmd) GetUint(name string) *uint {
return cmd.getOptVal(name).(*uint)
}

// GetUint8 returns the uint8 pointer used as value
// for the argument 'name' (you can use either the short or long name).
// If the argument does not exist, this routine panics.
func (cmd *Cmd) GetUint8(name string) *uint8 {
return cmd.getOptVal(name).(*uint8)
}

// GetUint16 returns the uint16 pointer used as value
// for the argument 'name' (you can use either the short or long name).
// If the argument does not exist, this routine panics.
func (cmd *Cmd) GetUint16(name string) *uint16 {
return cmd.getOptVal(name).(*uint16)
}

// GetUint32 returns the uint32 pointer used as value
// for the argument 'name' (you can use either the short or long name).
// If the argument does not exist, this routine panics.
func (cmd *Cmd) GetUint32(name string) *uint32 {
return cmd.getOptVal(name).(*uint32)
}

// GetUint64 returns the uint64 pointer used as value
// for the argument 'name' (you can use either the short or long name).
// If the argument does not exist, this routine panics.
func (cmd *Cmd) GetUint64(name string) *uint64 {
return cmd.getOptVal(name).(*uint64)
}

// GetFloat32 returns the float32 pointer used as value
// for the argument 'name' (you can use either the short or long name).
// If the argument does not exist, this routine panics.
func (cmd *Cmd) GetFloat32(name string) *float32 {
return cmd.getOptVal(name).(*float32)
}

// GetFloat64 returns the float64 pointer used as value
// for the argument 'name' (you can use either the short or long name).
// If the argument does not exist, this routine panics.
func (cmd *Cmd) GetFloat64(name string) *float64 {
return cmd.getOptVal(name).(*float64)
}

// GetChoice returns the string pointer used as value
// for the argument 'name' (you can use either the short or long name).
// If the argument does not exist, this routine panics.
func (cmd *Cmd) GetChoice(name string) *string {
return cmd.GetCustom(name).(*choiceString).value
}

// GetCustom returns the CustomArg value used as value
// for the argument 'name' (you can use either the short or long name).
// If the argument does not exist, this routine panics.
func (cmd *Cmd) GetCustom(name string) CustomArg {
return cmd.getOptVal(name).(CustomArg)
}
167 changes: 167 additions & 0 deletions get_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package libcmd_test

import (
"math"
"strconv"
"testing"

"github.com/ibraimgm/libcmd"
)

func TestGet(t *testing.T) {
tests := []struct {
cmd []string
abool bool
aint int
auint uint
astring string
afloat32 float32
afloat64 float64
args []string
}{
{cmd: []string{}},
{cmd: []string{"-b", "-i", "5", "-u", "9", "-s", "foo"}, abool: true, aint: 5, auint: 9, astring: "foo"},
{cmd: []string{"--abool", "--aint", "5", "--auint", "9", "--astring", "foo"}, abool: true, aint: 5, auint: 9, astring: "foo"},
{cmd: []string{"--aint=5", "--astring=foo"}, aint: 5, astring: "foo"},
{cmd: []string{"-b", "--abool=false"}},
{cmd: []string{"-b", "--no-abool"}},
{cmd: []string{"-i", "5", "--aint", "6", "-i", "7"}, aint: 7},
{cmd: []string{"-u", "5", "--auint", "6", "-u", "7"}, auint: 7},
{cmd: []string{"-b", "-i", "5", "foo", "bar"}, abool: true, aint: 5, args: []string{"foo", "bar"}},
{cmd: []string{"foo", "bar"}, args: []string{"foo", "bar"}},
{cmd: []string{"foo", "-i", "5"}, args: []string{"foo", "-i", "5"}},
{cmd: []string{"-b", "--no-abool=true"}},
{cmd: []string{"--no-abool=false"}, abool: true},
{cmd: []string{"-s", "foo", "--astring="}},
{cmd: []string{"--astring", "--aint", "5"}, astring: "--aint", args: []string{"5"}},
{cmd: []string{"-i", "5", "-f32", "3.14", "-f64", "3.1415"}, aint: 5, afloat32: float32(3.14), afloat64: float64(3.1415)},
{cmd: []string{"--afloat32", "3.14", "--afloat64", "3.1415"}, afloat32: float32(3.14), afloat64: float64(3.1415)},
{cmd: []string{"--afloat32=3.14", "--afloat64=3.1415"}, afloat32: float32(3.14), afloat64: float64(3.1415)},
}

for i, test := range tests {
app := libcmd.NewApp("", "")

app.Bool("abool", "b", false, "specifies a bool value")
app.Int("aint", "i", 0, "specifies an int value")
app.Uint("auint", "u", 0, "specifies an uint value")
app.String("astring", "s", "", "specifies a string value")
app.Float32("afloat32", "f32", 0, "specifies a float32 value")
app.Float64("afloat64", "f64", 0, "specifies a float64 value")

if err := app.RunArgs(test.cmd); err != nil {
t.Errorf("Case %d, error parsing args: %v", i, err)
continue
}

abool := app.GetBool("abool")
aint := app.GetInt("aint")
auint := app.GetUint("auint")
astring := app.GetString("astring")
afloat32 := app.GetFloat32("afloat32")
afloat64 := app.GetFloat64("afloat64")

compareValue(t, i, test.abool, *abool)
compareValue(t, i, test.aint, *aint)
compareValue(t, i, test.auint, *auint)
compareValue(t, i, test.astring, *astring)
compareValue(t, i, test.afloat32, *afloat32)
compareValue(t, i, test.afloat64, *afloat64)
compareArgs(t, i, test.args, app.Args())
}
}

func TestGetIntLimit(t *testing.T) {
tests := []struct {
cmd []string
a int8
b int16
c int32
d int64
e uint8
f uint16
g uint32
h uint64
}{
{cmd: []string{"-a", strconv.FormatInt(math.MaxInt8, 10)}, a: math.MaxInt8},
{cmd: []string{"-b", strconv.FormatInt(math.MaxInt16, 10)}, b: math.MaxInt16},
{cmd: []string{"-c", strconv.FormatInt(math.MaxInt32, 10)}, c: math.MaxInt32},
{cmd: []string{"-d", strconv.FormatInt(math.MaxInt64, 10)}, d: math.MaxInt64},
{cmd: []string{"-e", strconv.FormatUint(math.MaxUint8, 10)}, e: math.MaxUint8},
{cmd: []string{"-f", strconv.FormatUint(math.MaxUint16, 10)}, f: math.MaxUint16},
{cmd: []string{"-g", strconv.FormatUint(math.MaxUint32, 10)}, g: math.MaxUint32},
{cmd: []string{"-h", strconv.FormatUint(math.MaxUint64, 10)}, h: math.MaxUint64},
}

for i, test := range tests {
app := libcmd.NewApp("", "")
app.Options.SuppressHelpFlag = true

app.Int8("", "a", 0, "specifies a int8 value")
app.Int16("", "b", 0, "specifies a int16 value")
app.Int32("", "c", 0, "specifies a int32 value")
app.Int64("", "d", 0, "specifies a int64 value")
app.Uint8("", "e", 0, "specifies a uint8 value")
app.Uint16("", "f", 0, "specifies a uint16 value")
app.Uint32("", "g", 0, "specifies a uint32 value")
app.Uint64("", "h", 0, "specifies a uint64 value")

if err := app.RunArgs(test.cmd); err != nil {
t.Errorf("Case %d, error parsing args: %v", i, err)
continue
}

a := app.GetInt8("a")
b := app.GetInt16("b")
c := app.GetInt32("c")
d := app.GetInt64("d")
e := app.GetUint8("e")
f := app.GetUint16("f")
g := app.GetUint32("g")
h := app.GetUint64("h")

compareValue(t, i, test.a, *a)
compareValue(t, i, test.b, *b)
compareValue(t, i, test.c, *c)
compareValue(t, i, test.d, *d)
compareValue(t, i, test.e, *e)
compareValue(t, i, test.f, *f)
compareValue(t, i, test.g, *g)
compareValue(t, i, test.h, *h)
}
}

func TestGetChoice(t *testing.T) {
tests := []struct {
cmd []string
expected string
expectErr bool
}{
{cmd: []string{}},
{cmd: []string{"-c", "foo"}, expected: "foo"},
{cmd: []string{"-c", "bar"}, expected: "bar"},
{cmd: []string{"-c", "baz"}, expected: "baz"},
{cmd: []string{"-c", "hey"}, expectErr: true},
}

for i, test := range tests {
app := libcmd.NewApp("", "")
app.Choice([]string{"foo", "bar", "baz"}, "", "c", "", "")

err := app.RunArgs(test.cmd)
if !test.expectErr && err != nil {
t.Errorf("Case %d, error parsing args: %v", i, err)
continue
}

if test.expectErr && err == nil {
t.Errorf("Case %d, expected error but none received", i)
continue
}

s := app.GetChoice("c")
if *s != test.expected {
t.Errorf("Case %d, wrong value: expected '%s', received '%s'", i, test.expected, *s)
}
}
}
2 changes: 1 addition & 1 deletion opt.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ func (cmd *Cmd) runLeafCommand() error {
arg = cmd.longopt["--help"]
}

if arg != nil {
if arg != nil && arg.val.isBool {
showHelp = arg.val.refValue.Bool()
}
}
Expand Down
7 changes: 5 additions & 2 deletions variant.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
)

type variant struct {
raw interface{}
refValue reflect.Value
defaultValue reflect.Value
isBool bool
Expand All @@ -27,11 +28,12 @@ func varFromInterface(target, defaultValue interface{}) *variant {

def := reflect.ValueOf(defaultValue)

return varFromReflect(ref, def)
return varFromReflect(target, ref, def)
}

func varFromReflect(target, defaultValue reflect.Value) *variant {
func varFromReflect(raw interface{}, target, defaultValue reflect.Value) *variant {
return &variant{
raw: raw,
refValue: target,
defaultValue: defaultValue,
isBool: target.Kind() == reflect.Bool,
Expand All @@ -41,6 +43,7 @@ func varFromReflect(target, defaultValue reflect.Value) *variant {

func varFromCustom(target CustomArg, defaultValue string) *variant {
return &variant{
raw: target,
refValue: reflect.ValueOf(target),
defaultValue: reflect.ValueOf(defaultValue),
isStr: true,
Expand Down

0 comments on commit 69d8b6f

Please sign in to comment.