add unittests for canParse

This commit is contained in:
Alex Flint 2019-05-02 09:28:17 -07:00
parent 5b649de043
commit 87be2d9790
3 changed files with 104 additions and 55 deletions

View File

@ -1,7 +1,6 @@
package arg
import (
"encoding"
"encoding/csv"
"errors"
"fmt"
@ -659,60 +658,6 @@ func setSlice(dest reflect.Value, values []string, trunc bool) error {
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
func findOption(specs []*spec, name string) *spec {
for _, spec := range specs {

64
reflect.go Normal file
View File

@ -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
}
}

40
reflect_test.go Normal file
View File

@ -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)
}