add first version
This commit is contained in:
commit
791dd222c5
18
.drone.yml
Normal file
18
.drone.yml
Normal 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
168
argparse.go
Normal 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(©Arg)
|
||||||
|
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
541
argparse_test.go
Normal 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
174
argument.go
Normal 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
700
argument_test.go
Normal 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
37
example/main.go
Normal 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)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user