Skip to content
Snippets Groups Projects
Verified Commit 5004bcd2 authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

feat: initial version

parent b3c2b895
No related branches found
No related tags found
No related merge requests found
package xflags
import "testing"
type PathfindTestStruct1 struct {
A bool
Sub1 struct {
B bool
Bi int
Bs string
Bf float64
Sub2 struct {
C bool
Ci int
Cs string
Cf float64
Sub3 struct {
D bool
Di int
Ds string
Df float64
}
}
}
}
func TestPathFindError(t *testing.T) {
s := PathfindTestStruct1{}
_, err := getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.XX")
if err == nil {
t.Error("err == nil")
}
}
func TestPathFindSetValueString(t *testing.T) {
testData := map[string]string{
"Sub1.B": "true",
"Sub1.Bi": "2",
"Sub1.Bs": "3",
"Sub1.Bf": "4.0",
"Sub1.Sub2.C": "true",
"Sub1.Sub2.Ci": "2",
"Sub1.Sub2.Cs": "3",
"Sub1.Sub2.Cf": "4.0",
"Sub1.Sub2.Sub3.D": "true",
"Sub1.Sub2.Sub3.Di": "2",
"Sub1.Sub2.Sub3.Ds": "3",
"Sub1.Sub2.Sub3.Df": "4.0",
}
for k, v := range testData {
s := &PathfindTestStruct1{}
err := setTheValueOverPath[*PathfindTestStruct1](s, k, v)
if err != nil {
t.Error(err)
}
}
}
func TestPathFindGetValueFrom(t *testing.T) {
s := PathfindTestStruct1{}
s.Sub1.B = true
s.Sub1.Bi = 2
s.Sub1.Bs = "3"
s.Sub1.Bf = 4.0
v, err := getValueFrom[PathfindTestStruct1](s, "Sub1.B")
if err != nil {
t.Error(err)
}
if v != true {
t.Error("v != true")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Bi")
if err != nil {
t.Error(err)
}
if v != 2 {
t.Error("v != 2")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Bs")
if err != nil {
t.Error(err)
}
if v != "3" {
t.Error("v != 3")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Bf")
if err != nil {
t.Error(err)
}
if v != 4.0 {
t.Error("v != 4.0")
}
s.Sub1.Sub2.C = true
s.Sub1.Sub2.Ci = 2
s.Sub1.Sub2.Cs = "3"
s.Sub1.Sub2.Cf = 4.0
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.C")
if err != nil {
t.Error(err)
}
if v != true {
t.Error("v != true")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Ci")
if err != nil {
t.Error(err)
}
if v != 2 {
t.Error("v != 2")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Cs")
if err != nil {
t.Error(err)
}
if v != "3" {
t.Error("v != 3")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Cf")
if err != nil {
t.Error(err)
}
if v != 4.0 {
t.Error("v != 4.0")
}
s.Sub1.Sub2.Sub3.D = true
s.Sub1.Sub2.Sub3.Di = 2
s.Sub1.Sub2.Sub3.Ds = "3"
s.Sub1.Sub2.Sub3.Df = 4.0
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.D")
if err != nil {
t.Error(err)
}
if v != true {
t.Error("v != true")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Di")
if err != nil {
t.Error(err)
}
if v != 2 {
t.Error("v != 2")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Ds")
if err != nil {
t.Error(err)
}
if v != "3" {
t.Error("v != 3")
}
v, err = getValueFrom[PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Df")
if err != nil {
t.Error(err)
}
if v != 4.0 {
t.Error("v != 4.0")
}
}
func TestPathFindSetValueFrom(t *testing.T) {
s := &PathfindTestStruct1{}
setTheValueOverPath[*PathfindTestStruct1](s, "Sub1.B", "true")
setTheValueOverPath[*PathfindTestStruct1](s, "Sub1.Bi", "2")
setTheValueOverPath[*PathfindTestStruct1](s, "Sub1.Bs", "3")
setTheValueOverPath[*PathfindTestStruct1](s, "Sub1.Bf", "4.0")
if s.Sub1.B != true {
t.Error("s.Sub1.B != true")
}
if s.Sub1.Bi != 2 {
t.Error("s.Sub1.Bi != 2")
}
if s.Sub1.Bs != "3" {
t.Error("s.Sub1.Bs != 3")
}
if s.Sub1.Bf != 4.0 {
t.Error("s.Sub1.Bf != 4.0")
}
setTheValueOverPath[*PathfindTestStruct1](s, "Sub1.Sub2.C", "true")
setTheValueOverPath[*PathfindTestStruct1](s, "Sub1.Sub2.Ci", "2")
setTheValueOverPath[*PathfindTestStruct1](s, "Sub1.Sub2.Cs", "3")
setTheValueOverPath[*PathfindTestStruct1](s, "Sub1.Sub2.Cf", "4.0")
if s.Sub1.Sub2.C != true {
t.Error("s.Sub1.Sub2.C != true")
}
if s.Sub1.Sub2.Ci != 2 {
t.Error("s.Sub1.Sub2.Ci != 2")
}
if s.Sub1.Sub2.Cs != "3" {
t.Error("s.Sub1.Sub2.Cs != 3")
}
if s.Sub1.Sub2.Cf != 4.0 {
t.Error("s.Sub1.Sub2.Cf != 4.0")
}
if s.Sub1.Sub2.Sub3.D != false {
t.Error("s.Sub1.Sub2.Sub3.D != false")
}
setTheValueOverPath[*PathfindTestStruct1](s, "Sub1.Sub2.Sub3.D", "true")
setTheValueOverPath[*PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Di", "2")
setTheValueOverPath[*PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Ds", "3")
setTheValueOverPath[*PathfindTestStruct1](s, "Sub1.Sub2.Sub3.Df", "4.0")
if s.Sub1.Sub2.Sub3.D != true {
t.Error("s.Sub1.Sub2.Sub3.D != true")
}
if s.Sub1.Sub2.Sub3.Di != 2 {
t.Error("s.Sub1.Sub2.Sub3.Di != 2")
}
if s.Sub1.Sub2.Sub3.Ds != "3" {
t.Error("s.Sub1.Sub2.Sub3.Ds != 3")
}
if s.Sub1.Sub2.Sub3.Df != 4.0 {
t.Error("s.Sub1.Sub2.Sub3.Df != 4.0")
}
}
package xflags
import (
"github.com/stretchr/testify/assert"
"testing"
)
type Definition struct {
Verbose bool `short:"v" long:"verbose" description:"Show verbose debug information"`
Serve struct {
Host string `short:"h" long:"host" description:"Host to bind to" default:"localhost"`
Port int `short:"p" long:"port" description:"Port to bind to" default:"8080"`
} `command:"serve" description:"Run the HTTP server" call:"DoServe"`
}
func (d *Definition) DoServe(_ *setting[Definition]) {
// do something
}
func TestReadMeInit(t *testing.T) {
setting := New("test", Definition{})
setting.Parse([]string{"test", "-v", "serve", "-h", "localhost", "-p", "8080"})
setting.Execute()
assert.True(t, setting.definitions.Verbose)
assert.False(t, setting.HasErrors())
}
func TestReadMeInit2(t *testing.T) {
cmd := New("test", Definition{})
cmd.Parse([]string{"serve"})
assert.False(t, cmd.definitions.Verbose)
assert.False(t, cmd.HasErrors())
}
package xflags
import (
"flag"
"io"
)
func (s *setting[C]) initCommands(name string) {
s.command = buildCommandStruct[C](s, name, "", s.config.errorHandling, []string{})
s.command.parseStruct(s.definitions)
}
type config struct {
errorHandling flag.ErrorHandling
}
type setting[C any] struct {
definitions C
command *cmd[C]
errors []error
flagOutput io.Writer
args []string
config config
}
func (s *setting[C]) GetValues() C {
return s.definitions
}
package xflags
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestGetValues(t *testing.T) {
s := &setting[CmdTest1]{
definitions: CmdTest1{},
}
assert.Equal(t, CmdTest1{}, s.GetValues())
}
func TestInitCommands(t *testing.T) {
s := &setting[CmdTest1]{
definitions: CmdTest1{},
}
s.initCommands("test")
assert.Equal(t, 0, len(s.errors))
assert.Equal(t, "test", s.command.name)
assert.Equal(t, 1, len(s.command.commands))
assert.Equal(t, 3, len(s.command.mapping))
}
tags.go 0 → 100644
package xflags
import (
"reflect"
"strconv"
)
func getTagMap(field reflect.StructField) (value map[string]string) {
tagValues := map[string]string{}
tag := field.Tag
// code from reflect.StructTag.Lookup
for tag != "" {
// Skip leading space.
i := 0
for i < len(tag) && tag[i] == ' ' {
i++
}
tag = tag[i:]
if tag == "" {
break
}
i = 0
for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f {
i++
}
if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
break
}
name := string(tag[:i])
tag = tag[i+1:]
// Scan quoted string to find value.
i = 1
for i < len(tag) && tag[i] != '"' {
if tag[i] == '\\' {
i++
}
i++
}
if i >= len(tag) {
break
}
qvalue := string(tag[:i+1])
tag = tag[i+1:]
value, err := strconv.Unquote(qvalue)
if err != nil {
break
}
tagValues[name] = value
}
return tagValues
}
package xflags
import (
"github.com/stretchr/testify/assert"
"reflect"
"testing"
)
func TestGetTagMap(t *testing.T) {
type testStruct struct {
Verbose bool `short:"v" long:"verbose" description:"Show verbose debug information"`
}
m := getTagMap(reflect.TypeOf(testStruct{}).Field(0))
assert.Equal(t, "v", m["short"])
assert.Equal(t, "v", m["short"])
assert.Equal(t, "Show verbose debug information", m["description"])
}
func TestGetTagMapWithNoTags(t *testing.T) {
type testStruct struct {
Verbose bool
}
m := getTagMap(reflect.TypeOf(testStruct{}).Field(0))
assert.Empty(t, m)
}
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment