2
0
config/cli_test.go
2024-10-24 17:58:16 +07:00

320 lines
9.9 KiB
Go

/*
* Copyright (C) 2017 eschao <esc.chao@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package config
import (
"flag"
"log/slog"
"os"
"strconv"
"testing"
"time"
"git.mousesoft.ru/ms/config/test"
"github.com/stretchr/testify/assert"
)
func TestServiceCommand(t *testing.T) {
assert := assert.New(t)
serviceConfig := test.ServiceConfig{}
cmd := NewCLI("Service")
err := cmd.Init(&serviceConfig)
assert.NoError(err, "init service command")
// assert service cmd
assert.NotNil(cmd.FlagSet)
assert.NotNil(cmd.FlagSet.Lookup("hostname"))
assert.NotNil(cmd.FlagSet.Lookup("port"))
assert.Equal(2, len(cmd.SubCommands))
assert.Nil(cmd.SubCommands["login"])
// assert database sub cmd
dbCmd := cmd.SubCommands["database"]
assert.NotNil(dbCmd, "service cmd should have {database} sub cmd")
assert.NotNil(cmd.FlagSet.Lookup("database-host"))
assert.NotNil(cmd.FlagSet.Lookup("database-port"))
assert.NotNil(cmd.FlagSet.Lookup("database-user"))
assert.NotNil(cmd.FlagSet.Lookup("database-password"))
// assert database log sub cmd
dbLogCmd := dbCmd.SubCommands["log"]
assert.NotNil(dbCmd, "database cmd should have {log} sub cmd")
assert.NotNil(cmd.FlagSet.Lookup("database-log-path"))
assert.NotNil(cmd.FlagSet.Lookup("database-log-level"))
assert.Equal(0, len(dbLogCmd.SubCommands))
// assert log cmd
logCmd := cmd.SubCommands["log"]
assert.NotNil(logCmd, "service cmd should have {log} sub cmd")
assert.NotNil(cmd.FlagSet.Lookup("log-path"))
assert.NotNil(cmd.FlagSet.Lookup("log-level"))
}
func TestPrintUsage(t *testing.T) {
assert := assert.New(t)
serviceConfig := test.ServiceConfig{}
cmd := NewCLI("Service")
err := cmd.Init(&serviceConfig)
assert.NoError(err, "init service command")
assert.NoError(cmd.PrintUsage(os.Stdout))
}
func TestLoginSubCommand(t *testing.T) {
assert := assert.New(t)
serviceConfig := test.ServiceConfig{Login: &test.LoginConfig{}}
cmd := NewCLI("Service")
assert.NoError(cmd.Init(&serviceConfig))
// assert login sub command
loginCmd := cmd.SubCommands["login"]
assert.NotNil(loginCmd, "service cmd should have {login} sub cmd")
assert.NotNil(cmd.FlagSet.Lookup("login-user"))
assert.NotNil(cmd.FlagSet.Lookup("login-password"))
}
func TestLoginCommandWithValues(t *testing.T) {
assert := assert.New(t)
loginConfig := test.LoginConfig{}
cmd := NewCLI("Login")
assert.NoError(cmd.Init(&loginConfig), "init login command failed")
username := "test-user"
password := "test-passwd"
args := []string{"-user", username, "--password", password}
assert.NoError(cmd.Parse(args))
assert.Equal(username, loginConfig.User)
assert.Equal(password, loginConfig.Password)
}
func TestServiceCommandWithValues(t *testing.T) {
assert := assert.New(t)
serviceConfig := test.ServiceConfig{Login: &test.LoginConfig{}}
cmd := NewCLI("Service")
assert.NoError(cmd.Init(&serviceConfig))
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, "--log-level", serviceLogLevel,
}
assert.NoError(cmd.Parse(serviceArgs))
assert.Equal(serviceHost, serviceConfig.Host)
assert.Equal(servicePort, serviceConfig.Port)
assert.Equal(serviceLogPath, serviceConfig.Log.Path)
assert.Equal(serviceLogLevel, serviceConfig.Log.Level)
dbCmdArgs := []string{
"--database-host", dbHost, "--database-port", strconv.Itoa(dbPort),
"--database-user", dbUser, "--database-password", dbPassword,
}
assert.NoError(cmd.Parse(dbCmdArgs))
assert.Equal(dbHost, serviceConfig.DBConfig.Host)
assert.Equal(dbPort, serviceConfig.DBConfig.Port)
assert.Equal(dbUser, serviceConfig.DBConfig.User)
assert.Equal(dbPassword, serviceConfig.DBConfig.Password)
loginCmdArgs := []string{
"--login-user", loginUser, "--login-password", loginPassword,
}
assert.NoError(cmd.Parse(loginCmdArgs))
assert.Equal(loginUser, serviceConfig.Login.User)
assert.Equal(loginPassword, serviceConfig.Login.Password)
dbLogCmdArgs := []string{
"--database-log-path", dbLogPath, "--database-log-level", dbLogLevel,
}
assert.NoError(cmd.Parse(dbLogCmdArgs))
assert.Equal(dbLogPath, serviceConfig.DBConfig.Log.Path)
assert.Equal(dbLogLevel, serviceConfig.DBConfig.Log.Level)
}
func TestVariousTypeCommand(t *testing.T) {
assert := assert.New(t)
typesConfig := test.TypesConfig{}
cmd := NewCliWith("Types", flag.ContinueOnError, func(cmd *Command) func() {
return func() {
// Stub
}
})
assert.NoError(cmd.Init(&typesConfig))
// bool value
assert.NoError(cmd.Parse([]string{"-bool=true"}))
assert.Equal(true, typesConfig.BoolValue)
assert.NoError(cmd.Parse([]string{"-bool"}))
assert.Equal(true, typesConfig.BoolValue)
assert.Error(cmd.Parse([]string{"-bool=xxx"}))
// string value
assert.NoError(cmd.Parse([]string{"-str=xxx"}))
assert.Equal("xxx", typesConfig.StrValue)
assert.NoError(cmd.Parse([]string{"-str", "yyy"}))
assert.Equal("yyy", typesConfig.StrValue)
// int8 value
assert.NoError(cmd.Parse([]string{"-int8=100"}))
assert.Equal(int8(100), typesConfig.Int8Value)
assert.Error(cmd.Parse([]string{"-int8=xxx"}))
// int16 value
assert.NoError(cmd.Parse([]string{"-int16=200"}))
assert.Equal(int16(200), typesConfig.Int16Value)
assert.Error(cmd.Parse([]string{"-int16=xxx"}))
// int value
assert.NoError(cmd.Parse([]string{"-int=300"}))
assert.Equal(int(300), typesConfig.IntValue)
assert.Error(cmd.Parse([]string{"-int=xxx"}))
// int32 value
assert.NoError(cmd.Parse([]string{"-int32=400"}))
assert.Equal(int32(400), typesConfig.Int32Value)
assert.Error(cmd.Parse([]string{"-int32=xxx"}))
// int64 value
assert.NoError(cmd.Parse([]string{"-int64=500"}))
assert.Equal(int64(500), typesConfig.Int64Value)
assert.Error(cmd.Parse([]string{"-int64=xxx"}))
// uint8 value
assert.NoError(cmd.Parse([]string{"-uint8=10"}))
assert.Equal(uint8(10), typesConfig.Uint8Value)
assert.Error(cmd.Parse([]string{"-uint8=-10"}))
// uint16 value
assert.NoError(cmd.Parse([]string{"-uint16=1000"}))
assert.Equal(uint16(1000), typesConfig.Uint16Value)
assert.Error(cmd.Parse([]string{"-uint16=xxx"}))
// uint value
assert.NoError(cmd.Parse([]string{"-uint=2000"}))
assert.Equal(uint(2000), typesConfig.UintValue)
assert.Error(cmd.Parse([]string{"-uint=xxx"}))
// uint32 value
assert.NoError(cmd.Parse([]string{"-uint32=3000"}))
assert.Equal(uint32(3000), typesConfig.Uint32Value)
assert.Error(cmd.Parse([]string{"-uint32=xxx"}))
// uint64 value
assert.NoError(cmd.Parse([]string{"-uint64=4000"}))
assert.Equal(uint64(4000), typesConfig.Uint64Value)
assert.Error(cmd.Parse([]string{"-uint64=xxx"}))
// float32 value
assert.NoError(cmd.Parse([]string{"-float32=1.234"}))
assert.Equal(float32(1.234), typesConfig.Float32Value)
assert.Error(cmd.Parse([]string{"-float32=xxx"}))
// float64 value
assert.NoError(cmd.Parse([]string{"-float64=2.345"}))
assert.Equal(float64(2.345), typesConfig.Float64Value)
assert.Error(cmd.Parse([]string{"-float64=xxx"}))
}
func TestCommandWithSlices(t *testing.T) {
assert := assert.New(t)
conf := test.SlicesConfig{}
cmd := NewCLI("Slice")
assert.NoError(cmd.Init(&conf), "Can't init slice command")
paths := "/var:/home:/log"
debugs := "error;info;debug"
values := "100,200,300"
args := []string{"-paths", paths, "-debugs", debugs, "-values", values}
assert.NoError(cmd.Parse(args))
assert.Equal(3, len(conf.Paths))
assert.Equal("/var", conf.Paths[0])
assert.Equal("/home", conf.Paths[1])
assert.Equal("/log", conf.Paths[2])
assert.Equal(3, len(conf.Debugs))
assert.Equal("error", conf.Debugs[0])
assert.Equal("info", conf.Debugs[1])
assert.Equal("debug", conf.Debugs[2])
assert.Equal(3, len(conf.Values))
assert.Equal(100, conf.Values[0])
assert.Equal(200, conf.Values[1])
assert.Equal(300, conf.Values[2])
}
func TestDuration(t *testing.T) {
assert := assert.New(t)
var conf struct {
interval time.Duration `cli:"interval" usage:"interval"`
}
cmd := NewCLI("Config")
assert.NoError(cmd.Init(&conf), "init config command")
args := []string{"-v", "--interval", "5s", "help"}
assert.ElementsMatch([]string{"-v", "help"}, cmd.Capture(args))
assert.ElementsMatch([]string{"--interval", "5s"}, cmd.Args)
assert.NoError(cmd.Parse(cmd.Args))
assert.Equal(time.Second*5, conf.interval)
}
func TestDurationWithEqual(t *testing.T) {
assert := assert.New(t)
var conf struct {
interval time.Duration `cli:"interval" usage:"interval"`
}
cmd := NewCLI("Config")
assert.NoError(cmd.Init(&conf), "init config command")
args := []string{"-v", "--interval=5s", "help"}
assert.ElementsMatch([]string{"-v", "help"}, cmd.Capture(args))
assert.ElementsMatch([]string{"--interval=5s"}, cmd.Args)
assert.NoError(cmd.Parse(cmd.Args))
assert.Equal(time.Second*5, conf.interval)
}
func TestLogLevel(t *testing.T) {
assert := assert.New(t)
var conf struct {
Level slog.Level `cli:"log-level" default:"INFO"`
}
cmd := NewCLI("Config")
assert.NoError(cmd.Init(&conf), "init config command")
args := []string{"-v", "-log-level", "DEBUG", "help"}
assert.ElementsMatch([]string{"-v", "help"}, cmd.Capture(args))
assert.ElementsMatch([]string{"-log-level", "DEBUG"}, cmd.Args)
assert.NoError(cmd.Parse(cmd.Args))
assert.Equal(slog.LevelDebug, conf.Level)
}