add unittests for canParse
This commit is contained in:
parent
5b649de043
commit
87be2d9790
55
parse.go
55
parse.go
|
@ -1,7 +1,6 @@
|
||||||
package arg
|
package arg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding"
|
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -659,60 +658,6 @@ func setSlice(dest reflect.Value, values []string, trunc bool) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// canParse returns true if the type can be parsed from a string
|
|
||||||
func canParse(t reflect.Type) (parseable, boolean, multiple bool) {
|
|
||||||
parseable = scalar.CanParse(t)
|
|
||||||
boolean = isBoolean(t)
|
|
||||||
if parseable {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look inside pointer types
|
|
||||||
if t.Kind() == reflect.Ptr {
|
|
||||||
t = t.Elem()
|
|
||||||
}
|
|
||||||
// Look inside slice types
|
|
||||||
if t.Kind() == reflect.Slice {
|
|
||||||
multiple = true
|
|
||||||
t = t.Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
parseable = scalar.CanParse(t)
|
|
||||||
boolean = isBoolean(t)
|
|
||||||
if parseable {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look inside pointer types (again, in case of []*Type)
|
|
||||||
if t.Kind() == reflect.Ptr {
|
|
||||||
t = t.Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
parseable = scalar.CanParse(t)
|
|
||||||
boolean = isBoolean(t)
|
|
||||||
if parseable {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return false, false, false
|
|
||||||
}
|
|
||||||
|
|
||||||
var textUnmarshalerType = reflect.TypeOf([]encoding.TextUnmarshaler{}).Elem()
|
|
||||||
|
|
||||||
// isBoolean returns true if the type can be parsed from a single string
|
|
||||||
func isBoolean(t reflect.Type) bool {
|
|
||||||
switch {
|
|
||||||
case t.Implements(textUnmarshalerType):
|
|
||||||
return false
|
|
||||||
case t.Kind() == reflect.Bool:
|
|
||||||
return true
|
|
||||||
case t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Bool:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// findOption finds an option from its name, or returns null if no spec is found
|
// findOption finds an option from its name, or returns null if no spec is found
|
||||||
func findOption(specs []*spec, name string) *spec {
|
func findOption(specs []*spec, name string) *spec {
|
||||||
for _, spec := range specs {
|
for _, spec := range specs {
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package arg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
scalar "github.com/alexflint/go-scalar"
|
||||||
|
)
|
||||||
|
|
||||||
|
var textUnmarshalerType = reflect.TypeOf([]encoding.TextUnmarshaler{}).Elem()
|
||||||
|
|
||||||
|
// This file contains miscellaneous reflection utilities
|
||||||
|
|
||||||
|
// canParse returns true if the type can be parsed from a string
|
||||||
|
func canParse(t reflect.Type) (parseable, boolean, multiple bool) {
|
||||||
|
parseable = scalar.CanParse(t)
|
||||||
|
boolean = isBoolean(t)
|
||||||
|
if parseable {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look inside pointer types
|
||||||
|
if t.Kind() == reflect.Ptr {
|
||||||
|
t = t.Elem()
|
||||||
|
}
|
||||||
|
// Look inside slice types
|
||||||
|
if t.Kind() == reflect.Slice {
|
||||||
|
multiple = true
|
||||||
|
t = t.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
parseable = scalar.CanParse(t)
|
||||||
|
boolean = isBoolean(t)
|
||||||
|
if parseable {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look inside pointer types (again, in case of []*Type)
|
||||||
|
if t.Kind() == reflect.Ptr {
|
||||||
|
t = t.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
parseable = scalar.CanParse(t)
|
||||||
|
boolean = isBoolean(t)
|
||||||
|
if parseable {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, false, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// isBoolean returns true if the type can be parsed from a single string
|
||||||
|
func isBoolean(t reflect.Type) bool {
|
||||||
|
switch {
|
||||||
|
case t.Implements(textUnmarshalerType):
|
||||||
|
return false
|
||||||
|
case t.Kind() == reflect.Bool:
|
||||||
|
return true
|
||||||
|
case t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Bool:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package arg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func assertCanParse(t *testing.T, typ reflect.Type, parseable, boolean, multiple bool) {
|
||||||
|
p, b, m := canParse(typ)
|
||||||
|
assert.Equal(t, parseable, p, "expected %v to have parseable=%v but was %v", typ, parseable, p)
|
||||||
|
assert.Equal(t, boolean, b, "expected %v to have boolean=%v but was %v", typ, boolean, b)
|
||||||
|
assert.Equal(t, multiple, m, "expected %v to have multiple=%v but was %v", typ, multiple, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCanParse(t *testing.T) {
|
||||||
|
var b bool
|
||||||
|
var i int
|
||||||
|
var s string
|
||||||
|
var f float64
|
||||||
|
var bs []bool
|
||||||
|
var is []int
|
||||||
|
|
||||||
|
assertCanParse(t, reflect.TypeOf(b), true, true, false)
|
||||||
|
assertCanParse(t, reflect.TypeOf(i), true, false, false)
|
||||||
|
assertCanParse(t, reflect.TypeOf(s), true, false, false)
|
||||||
|
assertCanParse(t, reflect.TypeOf(f), true, false, false)
|
||||||
|
|
||||||
|
assertCanParse(t, reflect.TypeOf(&b), true, true, false)
|
||||||
|
assertCanParse(t, reflect.TypeOf(&s), true, false, false)
|
||||||
|
assertCanParse(t, reflect.TypeOf(&i), true, false, false)
|
||||||
|
assertCanParse(t, reflect.TypeOf(&f), true, false, false)
|
||||||
|
|
||||||
|
assertCanParse(t, reflect.TypeOf(bs), true, true, true)
|
||||||
|
assertCanParse(t, reflect.TypeOf(&bs), true, true, true)
|
||||||
|
|
||||||
|
assertCanParse(t, reflect.TypeOf(is), true, false, true)
|
||||||
|
assertCanParse(t, reflect.TypeOf(&is), true, false, true)
|
||||||
|
}
|
Loading…
Reference in New Issue