2
0
This commit is contained in:
eschao 2017-12-10 23:58:12 +08:00
parent 413d39119d
commit 50ac8e4572
5 changed files with 574 additions and 263 deletions

257
cli/cmd.go Normal file
View File

@ -0,0 +1,257 @@
package cli
import (
"flag"
"fmt"
"reflect"
"strconv"
"strings"
"unsafe"
"github.com/eschao/config/utils"
)
type anyValue struct {
any reflect.Value
}
func newAnyValue(v reflect.Value) *anyValue {
return &anyValue{any: v}
}
func (this *anyValue) String() string {
kind := this.any.Kind()
switch kind {
case reflect.Bool:
return strconv.FormatBool(this.any.Bool())
case reflect.String:
return this.any.String()
case reflect.Int8,
reflect.Int16,
reflect.Int,
reflect.Int32,
reflect.Int64:
return strconv.FormatInt(this.any.Int(), 10)
case reflect.Uint8,
reflect.Uint16,
reflect.Uint,
reflect.Uint32,
reflect.Uint64:
return strconv.FormatUint(this.any.Uint(), 10)
case reflect.Float32:
return strconv.FormatFloat(this.any.Float(), 'E', -1, 32)
case reflect.Float64:
return strconv.FormatFloat(this.any.Float(), 'E', -1, 64)
}
return fmt.Sprintf("unsupport type %s", kind.String())
}
func (this *anyValue) Set(v string) error {
kind := this.any.Kind()
switch kind {
case reflect.String:
this.any.SetString(v)
case reflect.Float32:
return utils.SetValueWithFloatX(this.any, v, 32)
case reflect.Float64:
return utils.SetValueWithFloatX(this.any, v, 64)
case reflect.Int8:
return utils.SetValueWithIntX(this.any, v, 8)
case reflect.Int16:
return utils.SetValueWithIntX(this.any, v, 16)
case reflect.Int, reflect.Int32:
return utils.SetValueWithIntX(this.any, v, 32)
case reflect.Int64:
return utils.SetValueWithIntX(this.any, v, 64)
case reflect.Uint8:
return utils.SetValueWithUintX(this.any, v, 8)
case reflect.Uint16:
return utils.SetValueWithUintX(this.any, v, 16)
case reflect.Uint, reflect.Uint32:
return utils.SetValueWithUintX(this.any, v, 32)
case reflect.Uint64:
return utils.SetValueWithUintX(this.any, v, 64)
default:
return fmt.Errorf("Can't support type %s", kind.String())
}
return nil
}
var errorHandling = flag.ExitOnError
type UsageFunc func(*Command) func()
var usageHandler UsageFunc = nil
type Command struct {
Name string
FlagSet *flag.FlagSet
Usage string
SubCommands map[string]*Command
}
func New(name string) *Command {
cmd := Command{
Name: name,
FlagSet: flag.NewFlagSet(name, errorHandling),
SubCommands: make(map[string]*Command),
}
return &cmd
}
func NewWith(name string, errHandling flag.ErrorHandling,
usageHandling UsageFunc) *Command {
errorHandling = errHandling
usageHandler = usageHandling
cmd := Command{
Name: name,
FlagSet: flag.NewFlagSet(name, errorHandling),
SubCommands: make(map[string]*Command),
}
if usageHandler != nil {
cmd.FlagSet.Usage = usageHandler(&cmd)
}
return &cmd
}
func (this *Command) Init(i interface{}) error {
ptrRef := reflect.ValueOf(i)
if ptrRef.IsNil() || ptrRef.Kind() != reflect.Ptr {
return fmt.Errorf("Expect a structure pointer type instead of %s",
ptrRef.Kind().String())
}
valueOfStruct := ptrRef.Elem()
if valueOfStruct.Kind() != reflect.Struct {
return fmt.Errorf("Expect a structure type instead of %s",
valueOfStruct.Kind().String())
}
return this.parseValue(valueOfStruct)
}
func (this *Command) parseValue(v reflect.Value) error {
typeOfStruct := v.Type()
for i := 0; i < v.NumField(); i++ {
valueOfField := v.Field(i)
kindOfField := valueOfField.Kind()
structOfField := typeOfStruct.Field(i)
if kindOfField == reflect.Ptr {
if !valueOfField.IsNil() && valueOfField.CanSet() {
cmd := this.createCliFlagSet(structOfField.Tag)
if err := cmd.Init(valueOfField.Interface()); err != nil {
return err
}
}
} else if kindOfField == reflect.Struct {
cmd := this.createCliFlagSet(structOfField.Tag)
if err := cmd.parseValue(valueOfField); err != nil {
return err
}
} else {
if err := this.addFlag(valueOfField, structOfField); err != nil {
return err
}
}
}
return nil
}
func (this *Command) addFlag(v reflect.Value, f reflect.StructField) error {
cmdTag, ok := f.Tag.Lookup("cmd")
if !ok || cmdTag == "" {
return nil
}
firstSpace := strings.Index(cmdTag, " ")
name := cmdTag
usage := ""
if firstSpace > 0 {
name = cmdTag[0:firstSpace]
usage = cmdTag[firstSpace+1:]
}
kind := v.Kind()
switch kind {
case reflect.Bool:
this.FlagSet.BoolVar((*bool)(unsafe.Pointer(v.UnsafeAddr())), name,
false, usage)
return nil
case reflect.String,
reflect.Int8,
reflect.Int16,
reflect.Int,
reflect.Int32,
reflect.Int64,
reflect.Uint8,
reflect.Uint16,
reflect.Uint,
reflect.Uint32,
reflect.Uint64,
reflect.Float32,
reflect.Float64:
anyValue := newAnyValue(v)
this.FlagSet.Var(anyValue, name, usage)
default:
return fmt.Errorf("Can't support type %s", kind.String())
}
return nil
}
func (this *Command) createCliFlagSet(tag reflect.StructTag) *Command {
cmdTag, ok := tag.Lookup("cmd")
if !ok || cmdTag == "" {
return this
}
cmd := Command{SubCommands: make(map[string]*Command)}
firstSpace := strings.Index(cmdTag, " ")
name := cmdTag
usage := ""
if firstSpace > 0 {
name = cmdTag[0:firstSpace]
usage = cmdTag[firstSpace+1:]
}
cmd.Name = name
cmd.FlagSet = flag.NewFlagSet(name, errorHandling)
cmd.Usage = usage
if usageHandler != nil {
cmd.FlagSet.Usage = usageHandler(&cmd)
}
this.SubCommands[name] = &cmd
return &cmd
}
func (this *Command) Parse(args []string) error {
if err := this.FlagSet.Parse(args); err != nil {
return err
}
unprocessed := this.FlagSet.Args()
if len(unprocessed) < 1 {
return nil
}
if this.SubCommands == nil {
return fmt.Errorf("Command: %s is unsupport", unprocessed[0])
}
cmd := this.SubCommands[unprocessed[0]]
if cmd == nil {
return fmt.Errorf("Command: %s is unsupport", unprocessed[0])
}
return cmd.Parse(unprocessed[1:])
}

313
cli/cmd_test.go Normal file
View File

@ -0,0 +1,313 @@
package cli
import (
"flag"
"strconv"
"testing"
"github.com/stretchr/testify/assert"
)
type dbConfig struct {
Host string `cmd:"dbHost database server hostname"`
Port int `cmd:"dbPort database server port"`
User string `cmd:"dbUser database username"`
Password string `cmd:"dbPassword database user password"`
Log logConfig `cmd:"log database log configuration"`
}
type loginConfig struct {
User string `cmd:"user login username"`
Password string `cmd:"password login password"`
}
type logConfig struct {
Path string `cmd:"path log path"`
Level string `cmd:"level log level {debug|warning|error}"`
}
type serviceConfig struct {
Host string `cmd:"hostname service hostname"`
Port int `cmd:"port service port"`
DBConfig dbConfig `cmd:"database database configuration"`
Login *loginConfig `cmd:"login login user and password"`
Log logConfig `cmd:"log service log configuration"`
}
type typesConfig struct {
BoolValue bool `cmd:"bool boolean value"`
StrValue string `cmd:"str string value"`
Int8Value int8 `cmd:"int8 int8 value"`
Int16Value int16 `cmd:"int16 int16 value"`
IntValue int `cmd:"int int value"`
Int32Value int32 `cmd:"int32 int32 value"`
Int64Value int64 `cmd:"int64 int64 value"`
Uint8Value uint8 `cmd:"uint8 uint8 value"`
Uint16Value uint16 `cmd:"uint16 uint16 value"`
UintValue uint `cmd:"uint uint value"`
Uint32Value uint32 `cmd:"uint32 uint32 value"`
Uint64Value uint64 `cmd:"uint64 uint64 value"`
Float32Value float32 `cmd:"float32 float32 value"`
Float64Value float64 `cmd:"float64 float64 value"`
}
type defValueConfig struct {
BoolValue bool `cmd:"bool boolean value" default:"true"`
}
func TestServiceCommand(t *testing.T) {
assert := assert.New(t)
serviceConfig := serviceConfig{}
cmd := New("Service")
err := cmd.Init(&serviceConfig)
if err != nil {
t.Errorf("Can't init service command. %s", err.Error())
}
// assert service cmd
assert.NotNil(cmd.FlagSet)
assert.NotNil(cmd.FlagSet.Lookup("hostname"),
"service cmd should have {hostname} parameter")
assert.NotNil(cmd.FlagSet.Lookup("port"),
"service cmd should have {port} parameter")
assert.Equal(2, len(cmd.SubCommands),
"service cmd should have 2 sub cmds")
assert.Nil(cmd.SubCommands["login"],
"service cmd shouldn't have {login} sub cmd")
// assert database sub cmd
dbCmd := cmd.SubCommands["database"]
assert.NotNil(dbCmd, "service cmd should have {database} sub cmd")
assert.NotNil(dbCmd.FlagSet.Lookup("dbHost"),
"database cmd should have {dbHost} parameter")
assert.NotNil(dbCmd.FlagSet.Lookup("dbPort"),
"database cmd should have {dbPort} parameter")
assert.NotNil(dbCmd.FlagSet.Lookup("dbUser"),
"database cmd should have {dbUser} parameter")
assert.NotNil(dbCmd.FlagSet.Lookup("dbPassword"),
"database cmd should have {dbPassword} parameter")
// assert database log sub cmd
dbLogCmd := dbCmd.SubCommands["log"]
assert.NotNil(dbCmd, "database cmd should have {log} sub cmd")
assert.NotNil(dbLogCmd.FlagSet.Lookup("path"),
"database log cmd should have {path} parameter")
assert.NotNil(dbLogCmd.FlagSet.Lookup("level"),
"database log cmd should have {level} parameter")
assert.Equal(0, len(dbLogCmd.SubCommands),
"database log cmd shouldn't have sub cmd")
// assert log cmd
logCmd := cmd.SubCommands["log"]
assert.NotNil(logCmd, "service cmd should have {log} sub cmd")
assert.NotNil(logCmd.FlagSet.Lookup("path"),
"log cmd should have {path} parameter")
assert.NotNil(logCmd.FlagSet.Lookup("level"),
"log cmd should have {level} parameter")
}
func TestLoginSubCommand(t *testing.T) {
assert := assert.New(t)
serviceConfig := serviceConfig{Login: &loginConfig{}}
cmd := New("Service")
assert.NoError(cmd.Init(&serviceConfig), "Can't init service command")
// assert login sub command
loginCmd := cmd.SubCommands["login"]
assert.NotNil(loginCmd, "service cmd should have {login} sub cmd")
assert.NotNil(loginCmd.FlagSet.Lookup("user"),
"login cmd should have {user} parameter")
assert.NotNil(loginCmd.FlagSet.Lookup("password"),
"login cmd should have {password} parameter")
}
func TestLoginCommandWithValues(t *testing.T) {
assert := assert.New(t)
loginConfig := loginConfig{}
cmd := New("Login")
assert.NoError(cmd.Init(&loginConfig), "Can't init login command")
username := "test-user"
password := "test-passwd"
args := []string{"-user", username, "--password", password}
assert.NoError(cmd.Parse(args), "Can't parse login command")
assert.Equal(username, loginConfig.User, "Failed to parse login command")
assert.Equal(password, loginConfig.Password, "Failed to parse login command")
}
func TestServiceCommandWithValues(t *testing.T) {
assert := assert.New(t)
serviceConfig := serviceConfig{Login: &loginConfig{}}
cmd := New("Service")
assert.NoError(cmd.Init(&serviceConfig), "Can't init service command")
serviceHost := "service-hostname"
servicePort := 8080
serviceLogPath := "service-log-path"
serviceLogLevel := "service-log-debug"
dbHost := "database-hostname"
dbPort := 9080
dbUser := "database-user"
dbPassword := "database-passwd"
dbLogPath := "database-log-path"
dbLogLevel := "database-log-error"
loginUser := "login-user"
loginPassword := "login-passwd"
serviceArgs := []string{"--hostname", serviceHost, "--port",
strconv.Itoa(servicePort), "log", "-path", serviceLogPath, "-level",
serviceLogLevel}
assert.NoError(cmd.Parse(serviceArgs), "Can't parse service command")
assert.Equal(serviceHost, serviceConfig.Host,
"Service hostname is not equal")
assert.Equal(servicePort, serviceConfig.Port,
"Service port is not equal")
assert.Equal(serviceLogPath, serviceConfig.Log.Path,
"Service log path is not equal")
assert.Equal(serviceLogLevel, serviceConfig.Log.Level,
"Service log level is not equal")
dbCmdArgs := []string{"database", "-dbHost", dbHost, "-dbPort",
strconv.Itoa(dbPort), "-dbUser", dbUser, "-dbPassword", dbPassword}
assert.NoError(cmd.Parse(dbCmdArgs), "Can't parse service database command")
assert.Equal(dbHost, serviceConfig.DBConfig.Host,
"Database hostname is not equal")
assert.Equal(dbPort, serviceConfig.DBConfig.Port,
"Database port is not equal")
assert.Equal(dbUser, serviceConfig.DBConfig.User,
"Database username is not equal")
assert.Equal(dbPassword, serviceConfig.DBConfig.Password,
"Database password is not equal")
loginCmdArgs := []string{"login", "--user", loginUser, "-password",
loginPassword}
assert.NoError(cmd.Parse(loginCmdArgs), "Can't parse service login command")
assert.Equal(loginUser, serviceConfig.Login.User,
"Login username is not equal")
assert.Equal(loginPassword, serviceConfig.Login.Password,
"Login password is not equal")
dbLogCmdArgs := []string{"database", "log", "-path", dbLogPath, "-level",
dbLogLevel}
assert.NoError(cmd.Parse(dbLogCmdArgs), "Can't parse database log command")
assert.Equal(dbLogPath, serviceConfig.DBConfig.Log.Path,
"Database log path is not equal")
assert.Equal(dbLogLevel, serviceConfig.DBConfig.Log.Level,
"Database log level is not equal")
}
func TestVariousTypeCommand(t *testing.T) {
assert := assert.New(t)
typesConfig := typesConfig{}
cmd := NewWith("Types", flag.ContinueOnError, nil)
assert.NoError(cmd.Init(&typesConfig))
// bool value
assert.NoError(cmd.Parse([]string{"-bool=true"}),
"Can't parse bool value command")
assert.Equal(true, typesConfig.BoolValue, "Bool value is not true")
assert.NoError(cmd.Parse([]string{"-bool"}),
"Can't parse bool value command")
assert.Equal(true, typesConfig.BoolValue, "Bool value is not false")
assert.Error(cmd.Parse([]string{"-bool=xxx"}),
"Parsing string as bool should have an error")
// string value
assert.NoError(cmd.Parse([]string{"-str=xxx"}),
"Can't parse string value command")
assert.Equal("xxx", typesConfig.StrValue, "String value it not equal")
assert.NoError(cmd.Parse([]string{"-str", "yyy"}),
"Can't parse string value command")
assert.Equal("yyy", typesConfig.StrValue, "String value is not equal")
// int8 value
assert.NoError(cmd.Parse([]string{"-int8=100"}),
"Can't parse int8 value command")
assert.Equal(int8(100), typesConfig.Int8Value, "Int8 value is not equal")
assert.Error(cmd.Parse([]string{"-int8=xxx"}),
"Parsing string as int8 should have an error")
// int16 value
assert.NoError(cmd.Parse([]string{"-int16=200"}),
"Can't parse int16 value command")
assert.Equal(int16(200), typesConfig.Int16Value, "Int16 value is not equal")
assert.Error(cmd.Parse([]string{"-int16=xxx"}),
"Parsing string as int16 should have an error")
// int value
assert.NoError(cmd.Parse([]string{"-int=300"}),
"Can't parse int value command")
assert.Equal(int(300), typesConfig.IntValue, "Int value is not equal")
assert.Error(cmd.Parse([]string{"-int=xxx"}),
"Parsing string as int should have an error")
// int32 value
assert.NoError(cmd.Parse([]string{"-int32=400"}),
"Can't parse int32 value command")
assert.Equal(int32(400), typesConfig.Int32Value, "Int32 value is not equal")
assert.Error(cmd.Parse([]string{"-int32=xxx"}),
"Parsing string as int32 should have an error")
// int64 value
assert.NoError(cmd.Parse([]string{"-int64=500"}),
"Can't parse int64 value command")
assert.Equal(int64(500), typesConfig.Int64Value, "Int64 value is not equal")
assert.Error(cmd.Parse([]string{"-int64=xxx"}),
"Parsing string as int64 should have an error")
// uint8 value
assert.NoError(cmd.Parse([]string{"-uint8=10"}),
"Can't parse uint8 value command")
assert.Equal(uint8(10), typesConfig.Uint8Value, "Uint8 value is not equal")
assert.Error(cmd.Parse([]string{"-uint8=-10"}),
"Parsing string as uint8 should have an error")
// uint16 value
assert.NoError(cmd.Parse([]string{"-uint16=1000"}),
"Can't parse uint16 value command")
assert.Equal(uint16(1000), typesConfig.Uint16Value,
"Uint16 value is not equal")
assert.Error(cmd.Parse([]string{"-uint16=xxx"}),
"Parsing string as uint16 should have an error")
// uint value
assert.NoError(cmd.Parse([]string{"-uint=2000"}),
"Can't parse uint value command")
assert.Equal(uint(2000), typesConfig.UintValue, "Uint value is not equal")
assert.Error(cmd.Parse([]string{"-uint=xxx"}),
"Parsing string as uint should have an error")
// uint32 value
assert.NoError(cmd.Parse([]string{"-uint32=3000"}),
"Can't parse uint32 value command")
assert.Equal(uint32(3000), typesConfig.Uint32Value,
"Uint32 value is not equal")
assert.Error(cmd.Parse([]string{"-uint32=xxx"}),
"Parsing string as uint32 should have an error")
// uint64 value
assert.NoError(cmd.Parse([]string{"-uint64=4000"}),
"Can't parse uint64 value command")
assert.Equal(uint64(4000), typesConfig.Uint64Value,
"Uint64 value is not equal")
assert.Error(cmd.Parse([]string{"-uint64=xxx"}),
"Parsing string as uint64 should have an error")
// float32 value
assert.NoError(cmd.Parse([]string{"-float32=1.234"}),
"Can't parse float32 value command")
assert.Equal(float32(1.234), typesConfig.Float32Value,
"Float32 value is not equal")
assert.Error(cmd.Parse([]string{"-float32=xxx"}),
"Parsing string as float32 should have an error")
// float64 value
assert.NoError(cmd.Parse([]string{"-float64=2.345"}),
"Can't parse float64 value command")
assert.Equal(float64(2.345), typesConfig.Float64Value,
"Float64 value is not equal")
assert.Error(cmd.Parse([]string{"-float64=xxx"}),
"Parsing string as float64 should have an error")
}

View File

@ -1,139 +0,0 @@
package cmd
import (
"flag"
"fmt"
"reflect"
"strings"
"github.com/eschao/config/util"
)
type anyValue struct {
any reflect.Value
}
func newAnyValue(v Value) *anyValue {
return anyValue{any: v}
}
func (this *anyValue) String() string {
return this.any.Kind().String()
}
func (this *anyValue) Set(v string) error {
kind := this.any.Kind()
switch kind {
case reflect.Bool:
}
return nil
}
type Command struct {
Name string
FlagSet *flag.FlagSet
Usage string
SubCommands map[string]*Command
}
func New(name string) *Command {
cmd := Command{
Name: name,
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
SubCommands: make(map[string]*Command),
}
return &cmd
}
func (this *Command) Init(i interface{}) error {
ptrRef := reflect.ValueOf(i)
if ptrRef.IsNil() || ptrRef.Kind() != reflect.Ptr {
return fmt.Errorf("Expect a structure pointer type instead of %s",
ptrRef.Kind().String())
}
valueOfStruct := ptrRef.Elem()
if valueOfStruct.Kind() != reflect.Struct {
return fmt.Errorf("Expect a structure type instead of %s",
valueOfStruct.Kind().String())
}
return this.parseValue(valueOfStruct)
}
func (this *Command) parseValue(v reflect.Value) error {
typeOfStruct := v.Type()
for i := 0; i < v.NumField(); i++ {
valueOfField := v.Field(i)
kindOfField := valueOfField.Kind()
structOfField := typeOfStruct.Field(i)
if kindOfField == reflect.Ptr {
if !valueOfField.IsNil() && valueOfField.CanSet() {
cmd := this.createCliFlagSet(structOfField.Tag)
if err := cmd.Init(valueOfField.Interface()); err != nil {
return err
}
}
} else if kindOfField == reflect.Struct {
cmd := this.createCliFlagSet(structOfField.Tag)
if err := cmd.parseValue(valueOfField); err != nil {
return err
}
} else {
this.addFlag(valueOfField, structOfField)
}
}
return nil
}
func (this *Command) addFlag(v reflect.Value, f reflect.StructField) {
cmdTag, ok := f.Tag.Lookup("cmd")
if !ok || cmdTag == "" {
return
}
firstSpace := strings.Index(cmdTag, " ")
name := cmdTag
usage := ""
if firstSpace > 0 {
name = cmdTag[0:firstSpace]
usage = cmdTag[firstSpace+1:]
}
//defValue, ok := f.Tag.Lookup("default")
vFlag := ValueFlag{Value: v}
this.FlagSet.Var(&vFlag, name, usage)
//fmt.Printf("[%s]: Added Flag: %s\n", this.Name, name)
}
func (this *Command) createCliFlagSet(tag reflect.StructTag) *Command {
cmdTag, ok := tag.Lookup("cmd")
if !ok || cmdTag == "" {
return this
}
cmd := Command{SubCommands: make(map[string]*Command)}
firstSpace := strings.Index(cmdTag, " ")
name := cmdTag
usage := ""
if firstSpace > 0 {
name = cmdTag[0:firstSpace]
usage = cmdTag[firstSpace+1:]
}
cmd.Name = name
cmd.FlagSet = flag.NewFlagSet(name, flag.ExitOnError)
cmd.Usage = usage
this.SubCommands[name] = &cmd
return &cmd
}
func (this *Command) Parse(i interface{}, args []string) error {
return nil
}

View File

@ -1,120 +0,0 @@
package cmd
import (
"testing"
"github.com/stretchr/testify/assert"
)
type dbConfig struct {
Host string `cmd:"dbHost database server hostname"`
Port int `cmd:"dbPort database server port"`
User string `cmd:"dbUser database username"`
Password string `cmd:"dbPassword database user password"`
Log logConfig `cmd:"log database log configuration"`
}
type loginConfig struct {
User string `cmd:"user login username"`
Password string `cmd:"password login password"`
}
type logConfig struct {
Path string `cmd:"path log path"`
Level string `cmd:"level log level {debug|warning|error}"`
}
type serviceConfig struct {
Host string `cmd:"hostname service hostname"`
Port int `cmd:"port service port"`
DBConfig dbConfig `cmd:"database database configuration"`
Login *loginConfig `cmd:"login login user and password"`
Log logConfig `cmd:"log service log configuration"`
}
func TestServiceCommand(t *testing.T) {
assert := assert.New(t)
serviceConfig := serviceConfig{}
cmd := New("Service")
err := cmd.Init(&serviceConfig)
if err != nil {
t.Errorf("Can't init service command. %s", err.Error())
}
// assert service cmd
assert.NotNil(cmd.FlagSet)
assert.NotNil(cmd.FlagSet.Lookup("hostname"),
"service cmd should have {hostname} parameter")
assert.NotNil(cmd.FlagSet.Lookup("port"),
"service cmd should have {port} parameter")
assert.Equal(2, len(cmd.SubCommands),
"service cmd should have 2 sub cmds")
assert.Nil(cmd.SubCommands["login"],
"service cmd shouldn't have {login} sub cmd")
// assert database sub cmd
dbCmd := cmd.SubCommands["database"]
assert.NotNil(dbCmd, "service cmd should have {database} sub cmd")
assert.NotNil(dbCmd.FlagSet.Lookup("dbHost"),
"database cmd should have {dbHost} parameter")
assert.NotNil(dbCmd.FlagSet.Lookup("dbPort"),
"database cmd should have {dbPort} parameter")
assert.NotNil(dbCmd.FlagSet.Lookup("dbUser"),
"database cmd should have {dbUser} parameter")
assert.NotNil(dbCmd.FlagSet.Lookup("dbPassword"),
"database cmd should have {dbPassword} parameter")
// assert database log sub cmd
dbLogCmd := dbCmd.SubCommands["log"]
assert.NotNil(dbCmd, "database cmd should have {log} sub cmd")
assert.NotNil(dbLogCmd.FlagSet.Lookup("path"),
"database log cmd should have {path} parameter")
assert.NotNil(dbLogCmd.FlagSet.Lookup("level"),
"database log cmd should have {level} parameter")
assert.Equal(0, len(dbLogCmd.SubCommands),
"database log cmd shouldn't have sub cmd")
// assert log cmd
logCmd := cmd.SubCommands["log"]
assert.NotNil(logCmd, "service cmd should have {log} sub cmd")
assert.NotNil(logCmd.FlagSet.Lookup("path"),
"log cmd should have {path} parameter")
assert.NotNil(logCmd.FlagSet.Lookup("level"),
"log cmd should have {level} parameter")
}
func TestLoginSubCommand(t *testing.T) {
assert := assert.New(t)
serviceConfig := serviceConfig{Login: &loginConfig{}}
cmd := New("Service")
err := cmd.Init(&serviceConfig)
if err != nil {
t.Errorf("Can't init service command. %s", err.Error())
}
// assert login sub command
loginCmd := cmd.SubCommands["login"]
assert.NotNil(loginCmd, "service cmd should have {login} sub cmd")
assert.NotNil(loginCmd.FlagSet.Lookup("user"),
"login cmd should have {user} parameter")
assert.NotNil(loginCmd.FlagSet.Lookup("password"),
"login cmd should have {password} parameter")
}
func TestLoginCommand(t *testing.T) {
loginConfig := loginConfig{}
cmd := New("Login")
if err := cmd.Init(&loginConfig); err != nil {
t.Errorf("Can't init login command. %s", err.Error())
}
args := []string{"-user", "test", "-password", "pass", "log", "database"}
if err := cmd.FlagSet.Parse(args); err != nil {
t.Errorf("Can't parse login command. %s", err.Error())
}
uknArgs := cmd.FlagSet.Args()
for i, arg := range uknArgs {
t.Logf("arg[%d]=%s", i, arg)
}
}

View File

@ -1,4 +1,4 @@
package util
package utils
import (
"reflect"
@ -26,7 +26,7 @@ func SetValueWithFloatX(v reflect.Value, floatValue string, bitSize int) error {
}
func SetValueWithIntX(v reflect.Value, intValue string, bitSize int) error {
value, err := strconv.ParseInt(envValue, 10, bitSize)
value, err := strconv.ParseInt(intValue, 10, bitSize)
if err != nil {
return err
}
@ -35,8 +35,8 @@ func SetValueWithIntX(v reflect.Value, intValue string, bitSize int) error {
return nil
}
func SetValueWithUintX(v reflect.Value, envValue string, bitSize int) error {
value, err := strconv.ParseUint(envValue, 10, bitSize)
func SetValueWithUintX(v reflect.Value, uintValue string, bitSize int) error {
value, err := strconv.ParseUint(uintValue, 10, bitSize)
if err != nil {
return err
}