fix(parser): add support for multiple overlapping global options

This commit is contained in:
jguer committed 2020-07-06 01:16:51 +02:00
1 parent 56760e1b7c
commit d507e024bd
2 files changed
+235 -30

No files matched your search

+21 -30
View File
@@ -52,13 +52,13 @@ func MakeArguments() *Arguments {
}
}
func (parser *Arguments) CopyGlobal() (cp *Arguments) {
cp = MakeArguments()
func (parser *Arguments) CopyGlobal() *Arguments {
cp := MakeArguments()
for k, v := range parser.Globals {
cp.Globals[k] = v
}
return
return cp
}
func (parser *Arguments) Copy() (cp *Arguments) {
@@ -143,51 +143,46 @@ func (parser *Arguments) NeedRoot(runtime *Runtime) bool {
}
}
func (parser *Arguments) addOP(op string) (err error) {
func (parser *Arguments) addOP(op string) error {
if parser.Op != "" {
err = errors.New(gotext.Get("only one operation may be used at a time"))
return
return errors.New(gotext.Get("only one operation may be used at a time"))
}
parser.Op = op
return
return nil
}
func (parser *Arguments) addParam(option, arg string) (err error) {
func (parser *Arguments) addParam(option, arg string) error {
if !isArg(option) {
return errors.New(gotext.Get("invalid option '%s'", option))
}
if isOp(option) {
err = parser.addOP(option)
return
return parser.addOP(option)
}
switch {
case isGlobal(option):
if isGlobal(option) {
if parser.Globals[option] == nil {
parser.Globals[option] = &Option{}
}
parser.Globals[option].Add(arg)
default:
} else {
if parser.Options[option] == nil {
parser.Options[option] = &Option{}
}
parser.Options[option].Add(arg)
}
return
return nil
}
func (parser *Arguments) AddArg(options ...string) (err error) {
func (parser *Arguments) AddArg(options ...string) error {
for _, option := range options {
err = parser.addParam(option, "")
err := parser.addParam(option, "")
if err != nil {
return
return err
}
}
return
return nil
}
// Multiple args acts as an OR operator
@@ -210,14 +205,12 @@ func (parser *Arguments) GetArg(options ...string) (arg string, double, exists b
for _, option := range options {
value, exists := parser.Options[option]
if exists {
arg = value.First()
return arg, len(value.Args) >= 2, len(value.Args) >= 1
return value.First(), len(value.Args) >= 2, len(value.Args) >= 1
}
value, exists = parser.Globals[option]
if exists {
arg = value.First()
return arg, len(value.Args) >= 2, len(value.Args) >= 1
return value.First(), len(value.Args) >= 2, len(value.Args) >= 1
}
}
@@ -279,14 +272,12 @@ func (parser *Arguments) FormatArgs() (args []string) {
func (parser *Arguments) FormatGlobals() (args []string) {
for option, arg := range parser.Globals {
formattedOption := formatArg(option)
args = append(args, formattedOption)
if hasParam(option) {
args = append(args, arg.First())
}
if parser.ExistsDouble(option) {
for _, value := range arg.Args {
args = append(args, formattedOption)
if hasParam(option) {
args = append(args, value)
}
}
}
+214
View File
@@ -0,0 +1,214 @@
package settings
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestOption_Add(t *testing.T) {
type fields struct {
Args []string
}
type args struct {
arg string
}
tests := []struct {
name string
fields fields
args args
want []string
}{
{name: "simple add", fields: fields{
Args: []string{"a", "b"},
}, args: args{
arg: "c",
}, want: []string{"a", "b", "c"}},
{name: "null add", fields: fields{
Args: nil,
}, args: args{
arg: "c",
}, want: []string{"c"}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
o := &Option{
Args: tt.fields.Args,
}
o.Add(tt.args.arg)
assert.EqualValues(t, tt.want, o.Args)
})
}
}
func TestOption_Set(t *testing.T) {
type fields struct {
Args []string
}
type args struct {
arg string
}
tests := []struct {
name string
fields fields
args args
want []string
}{
{name: "simple set", fields: fields{
Args: []string{"a", "b"},
}, args: args{
arg: "c",
}, want: []string{"c"}},
{name: "null set", fields: fields{
Args: nil,
}, args: args{
arg: "c",
}, want: []string{"c"}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
o := &Option{
Args: tt.fields.Args,
}
o.Set(tt.args.arg)
assert.EqualValues(t, tt.want, o.Args)
})
}
}
func TestOption_First(t *testing.T) {
type fields struct {
Args []string
}
tests := []struct {
name string
fields fields
want string
}{
{name: "simple first", fields: fields{
Args: []string{"a", "b"},
}, want: "a"},
{name: "null first", fields: fields{
Args: nil,
}, want: ""},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
o := &Option{
Args: tt.fields.Args,
}
assert.Equal(t, tt.want, o.First())
})
}
}
func TestMakeArguments(t *testing.T) {
args := MakeArguments()
assert.NotNil(t, args)
assert.Equal(t, "", args.Op)
assert.Empty(t, args.Globals)
assert.Empty(t, args.Options)
assert.Empty(t, args.Targets)
}
func TestArguments_CopyGlobal(t *testing.T) {
type fields struct {
Op string
Options map[string]*Option
Globals map[string]*Option
Targets []string
}
tests := []struct {
name string
fields fields
want *Arguments
}{
{name: "simple", fields: fields{
Op: "Q",
Options: map[string]*Option{"a": {}},
Globals: map[string]*Option{"arch": {
Args: []string{"x86_x64"},
}, "boo": {Args: []string{"a", "b"}},
},
Targets: []string{"a", "b"},
}, want: &Arguments{
Op: "",
Options: map[string]*Option{},
Globals: map[string]*Option{"arch": {
Args: []string{"x86_x64"},
}, "boo": {Args: []string{"a", "b"}},
},
Targets: []string{},
}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
parser := &Arguments{
Op: tt.fields.Op,
Options: tt.fields.Options,
Globals: tt.fields.Globals,
Targets: tt.fields.Targets,
}
got := parser.CopyGlobal()
assert.NotEqualValues(t, tt.fields.Options, got.Options)
assert.NotEqualValues(t, tt.fields.Targets, got.Targets)
assert.NotEqual(t, tt.fields.Op, got.Op)
assert.EqualValues(t, tt.fields.Globals, got.Globals)
assert.Equal(t, tt.want, got)
})
}
}
func TestArguments_Copy(t *testing.T) {
type fields struct {
Op string
Options map[string]*Option
Globals map[string]*Option
Targets []string
}
tests := []struct {
name string
fields fields
want *Arguments
}{
{name: "simple", fields: fields{
Op: "Q",
Options: map[string]*Option{"a": {}},
Globals: map[string]*Option{"arch": {
Args: []string{"x86_x64"},
}, "boo": {Args: []string{"a", "b"}},
},
Targets: []string{"a", "b"},
}, want: &Arguments{
Op: "Q",
Options: map[string]*Option{"a": {}},
Globals: map[string]*Option{"arch": {
Args: []string{"x86_x64"},
}, "boo": {Args: []string{"a", "b"}},
},
Targets: []string{"a", "b"},
}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
parser := &Arguments{
Op: tt.fields.Op,
Options: tt.fields.Options,
Globals: tt.fields.Globals,
Targets: tt.fields.Targets,
}
got := parser.Copy()
assert.Equal(t, parser, got)
assert.Equal(t, tt.want, got)
})
}
}
func TestArguments_DelArg(t *testing.T) {
args := MakeArguments()
args.addParam("arch", "arg")
args.addParam("ask", "arg")
args.DelArg("arch", "ask")
assert.Empty(t, args.Options)
assert.Empty(t, args.Globals)
}