add first version

This commit is contained in:
Jay 2020-02-12 09:39:46 +00:00
commit 791dd222c5
8 changed files with 1641 additions and 0 deletions

18
.drone.yml Normal file
View File

@ -0,0 +1,18 @@
kind: pipeline
name: test-stable-version
steps:
- name: test
image: golang:1
commands:
- go test
---
kind: pipeline
name: test-rc-version
steps:
- name: test
image: golang:rc
commands:
- go test

168
argparse.go Normal file
View File

@ -0,0 +1,168 @@
package argparse
import (
"errors"
"fmt"
"reflect"
)
type Parser struct {
args []*arg
parsed bool
}
type arg struct {
sname string
lname string
// value number count
size int
value interface{}
unique bool
parsed bool
}
func New() *Parser {
return &Parser{
args: make([]*arg, 0),
}
}
func (p *Parser) addArg(a *arg) error {
for _, v := range p.args {
if (v.sname == a.sname || v.lname == a.lname) && (a.unique || v.unique) {
return errors.New("option name dup")
}
}
p.args = append(p.args, a)
return nil
}
func (p *Parser) typeVar(i interface{}, short, long string, size int, unique bool) {
t := reflect.ValueOf(i)
if t.Kind() != reflect.Ptr {
panic(errors.New("var type not ptr"))
}
a := &arg{
sname: short,
lname: long,
value: i,
size: size,
unique: unique,
}
if err := p.addArg(a); err != nil {
panic(fmt.Errorf("unable to add String: %s\n", err))
}
}
func (p *Parser) Parse(a []string) error {
copyArg := make([]string, len(a))
copy(copyArg, a)
err := p.parse(&copyArg)
if err != nil {
return err
}
return nil
}
// in loop func
func (p *Parser) parse(args *[]string) error {
if p.parsed {
return nil
}
if len(*args) < 1 {
return nil
}
err := p.parseArguemtns(args)
if err != nil {
return err
}
p.parsed = true
return nil
}
func (p *Parser) parseArguemtns(args *[]string) error {
n := len(p.args)
for i := 0; i < n; i++ {
nn := len(*args)
oarg := p.args[i]
for j := 0; j < nn; j++ {
s := (*args)[j]
if s == "" {
continue
}
ct, err := oarg.check(s)
if err != nil {
return err
}
if ct > 0 {
valpos := j + 1
if len(*args) < valpos+oarg.size {
return fmt.Errorf("no enough arguments for %s", oarg.name())
}
err := oarg.parse((*args)[valpos : valpos+oarg.size])
if err != nil {
return err
}
oarg.reduce(j, args)
continue
}
}
}
return nil
}
func (p *Parser) String(short, long string) *string {
var result string
p.typeVar(&result, short, long, 1, true)
return &result
}
func (p *Parser) StringVar(i *string, short, long string) {
p.typeVar(i, short, long, 1, true)
}
func (p *Parser) Int(short, long string) *int {
var result int
p.typeVar(&result, short, long, 1, true)
return &result
}
func (p *Parser) IntVar(i *int, short, long string) {
p.typeVar(i, short, long, 1, true)
}
func (p *Parser) Bool(short, long string) *bool {
var result bool
p.typeVar(&result, short, long, 0, true)
return &result
}
func (p *Parser) BoolVar(i *bool, short, long string) {
p.typeVar(i, short, long, 0, true)
}
func (p *Parser) Float(short, long string) *float64 {
var result float64
p.typeVar(&result, short, long, 1, true)
return &result
}
func (p *Parser) FloatVar(i *float64, short, long string) {
p.typeVar(i, short, long, 1, true)
}

541
argparse_test.go Normal file
View File

@ -0,0 +1,541 @@
package argparse
import (
"reflect"
"testing"
)
func TestNew(t *testing.T) {
tests := []struct {
name string
want *Parser
}{
{
name: "test new parser",
want: &Parser{args: make([]*arg, 0)},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := New(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("New() = %v, want %v", got, tt.want)
}
})
}
}
func TestParser_addArg(t *testing.T) {
type fields struct {
args []*arg
parsed bool
}
type args struct {
a *arg
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
{
name: "test addArg to parser",
fields: fields{
args: nil,
parsed: false,
},
args: args{
a: &arg{sname: "a"},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &Parser{
args: tt.fields.args,
parsed: tt.fields.parsed,
}
if err := p.addArg(tt.args.a); (err != nil) != tt.wantErr {
t.Errorf("Parser.addArg() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestParser_typeVar(t *testing.T) {
var s string
type fields struct {
args []*arg
parsed bool
}
type args struct {
i interface{}
short string
long string
size int
unique bool
}
tests := []struct {
name string
fields fields
args args
}{
{
name: "test parser typeVar func",
fields: fields{},
args: args{
i: &s,
short: "s",
long: "string",
size: 1,
unique: true,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &Parser{
args: tt.fields.args,
parsed: tt.fields.parsed,
}
p.typeVar(tt.args.i, tt.args.short, tt.args.long, tt.args.size, tt.args.unique)
})
}
}
func TestParser_Parse(t *testing.T) {
var conf string
var port int
type fields struct {
args []*arg
parsed bool
}
type args struct {
a []string
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
{
name: "test parser run Parse",
fields: fields{
args: []*arg{
&arg{
sname: "c",
size: 1,
unique: true,
value: &conf,
},
&arg{
sname: "p",
size: 1,
unique: true,
value: &port,
},
},
},
args: args{
a: []string{
"-c", "/root/config.ini",
"-p", "3000",
},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &Parser{
args: tt.fields.args,
parsed: tt.fields.parsed,
}
if err := p.Parse(tt.args.a); (err != nil) != tt.wantErr {
t.Errorf("Parser.Parse() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestParser_parse(t *testing.T) {
var conf string
type fields struct {
args []*arg
parsed bool
}
type args struct {
args *[]string
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
{
name: "test parser parse func",
fields: fields{
args: []*arg{
&arg{
sname: "c",
size: 1,
unique: true,
value: &conf,
},
},
},
args: args{args: &[]string{"-c", "/config.yml"}},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &Parser{
args: tt.fields.args,
parsed: tt.fields.parsed,
}
if err := p.parse(tt.args.args); (err != nil) != tt.wantErr {
t.Errorf("Parser.parse() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestParser_parseArguemtns(t *testing.T) {
var conf string
type fields struct {
args []*arg
parsed bool
}
type args struct {
args *[]string
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
{
name: "test parser parseArguments",
fields: fields{
args: []*arg{
&arg{
sname: "c",
size: 1,
unique: true,
value: &conf,
},
},
},
args: args{args: &[]string{"-vv"}},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &Parser{
args: tt.fields.args,
parsed: tt.fields.parsed,
}
if err := p.parseArguemtns(tt.args.args); (err != nil) != tt.wantErr {
t.Errorf("Parser.parseArguemtns() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestParser_String(t *testing.T) {
type fields struct {
args []*arg
parsed bool
}
type args struct {
short string
long string
}
tests := []struct {
name string
fields fields
args args
}{
{
name: "test add string flag to parser",
fields: fields{},
args: args{
short: "c",
long: "",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &Parser{
args: tt.fields.args,
parsed: tt.fields.parsed,
}
if got := p.String(tt.args.short, tt.args.long); got == nil {
t.Errorf("Parser.String() = %v", got)
}
})
}
}
func TestParser_StringVar(t *testing.T) {
var s string
type fields struct {
args []*arg
parsed bool
}
type args struct {
i *string
short string
long string
}
tests := []struct {
name string
fields fields
args args
}{
{
name: "test add string flag to parser with ptr",
fields: fields{},
args: args{
i: &s,
short: "s",
long: "",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &Parser{
args: tt.fields.args,
parsed: tt.fields.parsed,
}
p.StringVar(tt.args.i, tt.args.short, tt.args.long)
})
}
}
func TestParser_Int(t *testing.T) {
type fields struct {
args []*arg
parsed bool
}
type args struct {
short string
long string
}
tests := []struct {
name string
fields fields
args args
}{
{
name: "test add int flag to parser",
fields: fields{},
args: args{
short: "i",
long: "",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &Parser{
args: tt.fields.args,
parsed: tt.fields.parsed,
}
if got := p.Int(tt.args.short, tt.args.long); got == nil {
t.Errorf("Parser.Int() = %v", got)
}
})
}
}
func TestParser_IntVar(t *testing.T) {
var i int
type fields struct {
args []*arg
parsed bool
}
type args struct {
i *int
short string
long string
}
tests := []struct {
name string
fields fields
args args
}{
{
name: "test add int flag to parser (ptr)",
fields: fields{},
args: args{
i: &i,
short: "i",
long: "",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &Parser{
args: tt.fields.args,
parsed: tt.fields.parsed,
}
p.IntVar(tt.args.i, tt.args.short, tt.args.long)
})
}
}
func TestParser_Bool(t *testing.T) {
type fields struct {
args []*arg
parsed bool
}
type args struct {
short string
long string
}
tests := []struct {
name string
fields fields
args args
}{
{
name: "test add bool flag to parser",
fields: fields{},
args: args{
short: "b",
long: "",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &Parser{
args: tt.fields.args,
parsed: tt.fields.parsed,
}
if got := p.Bool(tt.args.short, tt.args.long); got == nil {
t.Errorf("Parser.Bool() = %v", got)
}
})
}
}
func TestParser_BoolVar(t *testing.T) {
var b bool
type fields struct {
args []*arg
parsed bool
}
type args struct {
i *bool
short string
long string
}
tests := []struct {
name string
fields fields
args args
}{
{
name: "test add bool flag to parser (ptr)",
fields: fields{},
args: args{
i: &b,
short: "b",
long: "",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &Parser{
args: tt.fields.args,
parsed: tt.fields.parsed,
}
p.BoolVar(tt.args.i, tt.args.short, tt.args.long)
})
}
}
func TestParser_Float(t *testing.T) {
type fields struct {
args []*arg
parsed bool
}
type args struct {
short string
long string
}
tests := []struct {
name string
fields fields
args args
}{
{
name: "test add float flag to parser",
fields: fields{},
args: args{
short: "f",
long: "",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &Parser{
args: tt.fields.args,
parsed: tt.fields.parsed,
}
if got := p.Float(tt.args.short, tt.args.long); got == nil {
t.Errorf("Parser.Float() = %v", got)
}
})
}
}
func TestParser_FloatVar(t *testing.T) {
var f float64
type fields struct {
args []*arg
parsed bool
}
type args struct {
i *float64
short string
long string
}
tests := []struct {
name string
fields fields
args args
}{
{
name: "test add float flag to parser (ptr)",
fields: fields{},
args: args{
i: &f,
short: "f",
long: "",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &Parser{
args: tt.fields.args,
parsed: tt.fields.parsed,
}
p.FloatVar(tt.args.i, tt.args.short, tt.args.long)
})
}
}

174
argument.go Normal file
View File

@ -0,0 +1,174 @@
package argparse
import (
"errors"
"fmt"
"strconv"
"strings"
)
var (
ErrArgTooMany = errors.New("arg too manu")
ErrNoArg = errors.New("no arg")
)
func (a *arg) check(s string) (count int, err error) {
res := a.checkLongName(s)
if res > 0 {
return res, nil
}
return a.checkShortName(s)
}
func (a *arg) checkLongName(s string) int {
if a.lname != "" {
if len(s) > 2 && strings.HasPrefix(s, "--") && s[2] != '-' {
if s[2:] == a.lname {
return 1
}
}
}
return 0
}
func (a *arg) checkShortName(s string) (int, error) {
if a.sname != "" {
if len(s) > 1 && strings.HasPrefix(s, "-") && s[1] != '-' {
if s[1:] == a.sname {
return 1, nil
}
}
}
return 0, nil
}
func (a *arg) reduce(pos int, args *[]string) {
a.reduceLongName(pos, args)
a.reduceShortName(pos, args)
}
func (a *arg) reduceLongName(pos int, args *[]string) {
s := (*args)[pos]
if a.lname == "" {
return
}
if res := a.checkLongName(s); res == 0 {
return
}
for i := pos; i <= pos+a.size; i++ {
(*args)[i] = ""
}
}
func (a *arg) reduceShortName(pos int, args *[]string) {
s := (*args)[pos]
if a.sname == "" {
return
}
if res, err := a.checkShortName(s); res == 0 || err != nil {
return
}
for i := pos; i <= pos+a.size; i++ {
(*args)[i] = ""
}
}
func (a *arg) name() string {
if a.sname == "" {
return fmt.Sprintf("--%s", a.lname)
} else if a.lname == "" {
return fmt.Sprintf("-%s", a.sname)
} else {
return fmt.Sprintf("-%s|--%s", a.sname, a.lname)
}
}
func (a *arg) parse(args []string) error {
if a.unique && a.parsed {
return fmt.Errorf("[%s] can only parsent once\n", a.name())
}
return a.parseType(args)
}
func (a *arg) parseType(args []string) error {
var err error
switch a.value.(type) {
case *string:
return a.parseString(args)
case *int:
return a.parseInt(args)
case *bool:
return a.parseBool(args)
case *float64:
return a.parseFloat(args)
case *[]string:
case *[]int:
case *[]float64:
default:
err = fmt.Errorf("unsupport type [%t]", a.value)
}
return err
}
func (a *arg) parseString(args []string) error {
var err error
if len(args) > 1 {
return ErrArgTooMany
}
if len(args) == 0 {
return ErrNoArg
}
*((a.value).(*string)) = args[0]
a.parsed = true
return err
}
func (a *arg) parseInt(args []string) error {
var err error
if len(args) > 1 {
return ErrArgTooMany
}
if len(args) == 0 {
return ErrNoArg
}
if i, err := strconv.Atoi(args[0]); err == nil {
*((a.value).(*int)) = i
a.parsed = true
} else {
return fmt.Errorf("[%s] bad int value", a.name())
}
return err
}
func (a *arg) parseBool(args []string) error {
*a.value.(*bool) = true
a.parsed = true
return nil
}
func (a *arg) parseFloat(args []string) (err error) {
if len(args) > 1 {
return ErrArgTooMany
}
if len(args) == 0 {
return ErrNoArg
}
if f, err := strconv.ParseFloat(args[0], 64); err == nil {
*a.value.(*float64) = f
a.parsed = true
} else {
return fmt.Errorf("[%s] bad float value", a.name())
}
return
}

700
argument_test.go Normal file
View File

@ -0,0 +1,700 @@
package argparse
import "testing"
func Test_arg_check(t *testing.T) {
type fields struct {
sname string
lname string
size int
value interface{}
unique bool
parsed bool
}
type args struct {
s string
}
tests := []struct {
name string
fields fields
args args
wantCount int
wantErr bool
}{
{
name: "test argument check arg with short name",
fields: fields{sname: "d", size: 1},
args: args{s: "-d"},
wantCount: 1,
wantErr: false,
},
{
name: "test argument check arg with long name",
fields: fields{lname: "dir", size: 1},
args: args{s: "--dir"},
wantCount: 1,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &arg{
sname: tt.fields.sname,
lname: tt.fields.lname,
size: tt.fields.size,
value: tt.fields.value,
unique: tt.fields.unique,
parsed: tt.fields.parsed,
}
gotCount, err := a.check(tt.args.s)
if (err != nil) != tt.wantErr {
t.Errorf("arg.check() error = %v, wantErr %v", err, tt.wantErr)
return
}
if gotCount != tt.wantCount {
t.Errorf("arg.check() = %v, want %v", gotCount, tt.wantCount)
}
})
}
}
func Test_arg_checkLongName(t *testing.T) {
type fields struct {
sname string
lname string
size int
value interface{}
unique bool
parsed bool
}
type args struct {
s string
}
tests := []struct {
name string
fields fields
args args
want int
}{
{
name: "test argument check long name",
fields: fields{
lname: "dir",
size: 1,
},
args: args{
s: "--dir",
},
want: 1,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &arg{
sname: tt.fields.sname,
lname: tt.fields.lname,
size: tt.fields.size,
value: tt.fields.value,
unique: tt.fields.unique,
parsed: tt.fields.parsed,
}
if got := a.checkLongName(tt.args.s); got != tt.want {
t.Errorf("arg.checkLongName() = %v, want %v", got, tt.want)
}
})
}
}
func Test_arg_checkShortName(t *testing.T) {
type fields struct {
sname string
lname string
size int
value interface{}
unique bool
parsed bool
}
type args struct {
s string
}
tests := []struct {
name string
fields fields
args args
want int
wantErr bool
}{
{
name: "test argument check short name",
fields: fields{
sname: "d",
size: 1,
},
args: args{s: "-d"},
want: 1,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &arg{
sname: tt.fields.sname,
lname: tt.fields.lname,
size: tt.fields.size,
value: tt.fields.value,
unique: tt.fields.unique,
parsed: tt.fields.parsed,
}
got, err := a.checkShortName(tt.args.s)
if (err != nil) != tt.wantErr {
t.Errorf("arg.checkShortName() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("arg.checkShortName() = %v, want %v", got, tt.want)
}
})
}
}
func Test_arg_reduce(t *testing.T) {
a0 := []string{"-d"}
a1 := []string{"--dir"}
type fields struct {
sname string
lname string
size int
value interface{}
unique bool
parsed bool
}
type args struct {
pos int
args *[]string
}
tests := []struct {
name string
fields fields
args args
}{
{
name: "test argument reduce with short name",
fields: fields{
sname: "d",
size: 0,
unique: true,
},
args: args{
pos: 0,
args: &a0,
},
},
{
name: "test argument reduce with long name",
fields: fields{
lname: "dir",
size: 0,
unique: true,
},
args: args{
pos: 0,
args: &a1,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &arg{
sname: tt.fields.sname,
lname: tt.fields.lname,
size: tt.fields.size,
value: tt.fields.value,
unique: tt.fields.unique,
parsed: tt.fields.parsed,
}
a.reduce(tt.args.pos, tt.args.args)
if (*tt.args.args)[0] != "" {
t.Errorf("arg reduce failed")
}
})
}
}
func Test_arg_reduceLongName(t *testing.T) {
a0 := []string{"--dir"}
a1 := []string{"--file", "/config.yml"}
type fields struct {
sname string
lname string
size int
value interface{}
unique bool
parsed bool
}
type args struct {
pos int
args *[]string
}
tests := []struct {
name string
fields fields
args args
}{
{
name: "test argument reduce long name 1",
fields: fields{
lname: "dir",
size: 0,
},
args: args{
pos: 0,
args: &a0,
},
},
{
name: "test argument redue long name 2",
fields: fields{
lname: "file",
size: 1,
},
args: args{
pos: 0,
args: &a1,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &arg{
sname: tt.fields.sname,
lname: tt.fields.lname,
size: tt.fields.size,
value: tt.fields.value,
unique: tt.fields.unique,
parsed: tt.fields.parsed,
}
a.reduceLongName(tt.args.pos, tt.args.args)
for i := tt.args.pos; i < tt.args.pos+tt.fields.size; i++ {
if (*tt.args.args)[i] != "" {
t.Errorf("arg reduce fail")
}
}
})
}
}
func Test_arg_reduceShortName(t *testing.T) {
a0 := []string{"-d"}
a1 := []string{"-f", "/config.yml"}
type fields struct {
sname string
lname string
size int
value interface{}
unique bool
parsed bool
}
type args struct {
pos int
args *[]string
}
tests := []struct {
name string
fields fields
args args
}{
{
name: "test argument reduce short name 1",
fields: fields{
sname: "d",
size: 0,
},
args: args{
pos: 0,
args: &a0,
},
},
{
name: "test argument reduce short name 2",
fields: fields{
sname: "f",
size: 1,
},
args: args{
pos: 0,
args: &a1,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &arg{
sname: tt.fields.sname,
lname: tt.fields.lname,
size: tt.fields.size,
value: tt.fields.value,
unique: tt.fields.unique,
parsed: tt.fields.parsed,
}
a.reduceShortName(tt.args.pos, tt.args.args)
for i := tt.args.pos; i < tt.args.pos+tt.fields.size; i++ {
if (*tt.args.args)[i] != "" {
t.Errorf("arg reduce fail")
}
}
})
}
}
func Test_arg_name(t *testing.T) {
type fields struct {
sname string
lname string
size int
value interface{}
unique bool
parsed bool
}
tests := []struct {
name string
fields fields
want string
}{
{
name: "test argument get name 1",
fields: fields{
sname: "d",
},
want: "-d",
},
{
name: "test argument get name 2",
fields: fields{
lname: "dir",
},
want: "--dir",
},
{
name: "test argument get name 3",
fields: fields{
sname: "d",
lname: "dir",
},
want: "-d|--dir",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &arg{
sname: tt.fields.sname,
lname: tt.fields.lname,
size: tt.fields.size,
value: tt.fields.value,
unique: tt.fields.unique,
parsed: tt.fields.parsed,
}
if got := a.name(); got != tt.want {
t.Errorf("arg.name() = %v, want %v", got, tt.want)
}
})
}
}
func Test_arg_parse(t *testing.T) {
var b bool
var s string
type fields struct {
sname string
lname string
size int
value interface{}
unique bool
parsed bool
}
type args struct {
args []string
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
{
name: "test argument parse 1",
fields: fields{
sname: "d",
size: 0,
value: &b,
unique: true,
},
args: args{
args: []string{},
},
wantErr: false,
},
{
name: "test argument parse 2",
fields: fields{
sname: "f",
size: 1,
unique: true,
value: &s,
},
args: args{args: []string{"/config.yml"}},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &arg{
sname: tt.fields.sname,
lname: tt.fields.lname,
size: tt.fields.size,
value: tt.fields.value,
unique: tt.fields.unique,
parsed: tt.fields.parsed,
}
if err := a.parse(tt.args.args); (err != nil) != tt.wantErr {
t.Errorf("arg.parse() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func Test_arg_parseType(t *testing.T) {
var s string
type fields struct {
sname string
lname string
size int
value interface{}
unique bool
parsed bool
}
type args struct {
args []string
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
{
name: "test argument parseType 1",
fields: fields{
sname: "f",
value: &s,
size: 1,
unique: true,
},
args: args{args: []string{"/config.yml"}},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &arg{
sname: tt.fields.sname,
lname: tt.fields.lname,
size: tt.fields.size,
value: tt.fields.value,
unique: tt.fields.unique,
parsed: tt.fields.parsed,
}
if err := a.parseType(tt.args.args); (err != nil) != tt.wantErr {
t.Errorf("arg.parseType() error = %v, wantErr %v", err, tt.wantErr)
}
if s != (tt.args.args)[0] {
t.Errorf("arg.parseType() string = %s, wantErr %s", s, (tt.args.args)[0])
}
})
}
}
func Test_arg_parseString(t *testing.T) {
var s string
type fields struct {
sname string
lname string
size int
value interface{}
unique bool
parsed bool
}
type args struct {
args []string
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
{
name: "test argument parseString",
fields: fields{
value: &s,
unique: true,
size: 1,
},
args: args{args: []string{"value"}},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &arg{
sname: tt.fields.sname,
lname: tt.fields.lname,
size: tt.fields.size,
value: tt.fields.value,
unique: tt.fields.unique,
parsed: tt.fields.parsed,
}
if err := a.parseString(tt.args.args); (err != nil) != tt.wantErr {
t.Errorf("arg.parseString() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func Test_arg_parseInt(t *testing.T) {
var i int
type fields struct {
sname string
lname string
size int
value interface{}
unique bool
parsed bool
}
type args struct {
args []string
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
{
name: "test argument parseInt",
fields: fields{
value: &i,
size: 1,
unique: true,
},
args: args{args: []string{"123"}},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &arg{
sname: tt.fields.sname,
lname: tt.fields.lname,
size: tt.fields.size,
value: tt.fields.value,
unique: tt.fields.unique,
parsed: tt.fields.parsed,
}
if err := a.parseInt(tt.args.args); (err != nil) != tt.wantErr {
t.Errorf("arg.parseInt() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func Test_arg_parseBool(t *testing.T) {
var b bool
type fields struct {
sname string
lname string
size int
value interface{}
unique bool
parsed bool
}
type args struct {
args []string
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
{
name: "test argument parseBool",
fields: fields{
value: &b,
unique: true,
},
args: args{},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &arg{
sname: tt.fields.sname,
lname: tt.fields.lname,
size: tt.fields.size,
value: tt.fields.value,
unique: tt.fields.unique,
parsed: tt.fields.parsed,
}
if err := a.parseBool(tt.args.args); (err != nil) != tt.wantErr {
t.Errorf("arg.parseBool() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func Test_arg_parseFloat(t *testing.T) {
var f float64
type fields struct {
sname string
lname string
size int
value interface{}
unique bool
parsed bool
}
type args struct {
args []string
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
{
name: "test argument parseFloat",
fields: fields{
value: &f,
unique: true,
},
args: args{args: []string{"1.23"}},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &arg{
sname: tt.fields.sname,
lname: tt.fields.lname,
size: tt.fields.size,
value: tt.fields.value,
unique: tt.fields.unique,
parsed: tt.fields.parsed,
}
if err := a.parseFloat(tt.args.args); (err != nil) != tt.wantErr {
t.Errorf("arg.parseFloat() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

37
example/main.go Normal file
View File

@ -0,0 +1,37 @@
package main
import (
"fmt"
"git.trj.tw/golang/argparse"
)
func main() {
fmt.Println("argparse example")
opts := []string{
"-f", "/config.yml",
"-v",
"--port", "3000",
"--float", "1.23",
"-n", "name!!",
}
p := argparse.New()
var configPath string
var versionFlag bool
var port int
var floatVal float64
var name *string
p.BoolVar(&versionFlag, "v", "version")
p.StringVar(&configPath, "f", "config")
p.IntVar(&port, "p", "port")
p.FloatVar(&floatVal, "ff", "float")
name = p.String("n", "name")
p.Parse(opts)
fmt.Printf("Config: %s\nVersionFlag: %v\nPort: %d\nFloatVal: %f\nName: %s\n", configPath, versionFlag, port, floatVal, *name)
}

3
go.mod Normal file
View File

@ -0,0 +1,3 @@
module git.trj.tw/golang/argparse
go 1.13

0
go.sum Normal file
View File