230 lines
4.1 KiB
Go
230 lines
4.1 KiB
Go
|
package mapstructure
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"reflect"
|
||
|
"testing"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
func TestComposeDecodeHookFunc(t *testing.T) {
|
||
|
f1 := func(
|
||
|
f reflect.Kind,
|
||
|
t reflect.Kind,
|
||
|
data interface{}) (interface{}, error) {
|
||
|
return data.(string) + "foo", nil
|
||
|
}
|
||
|
|
||
|
f2 := func(
|
||
|
f reflect.Kind,
|
||
|
t reflect.Kind,
|
||
|
data interface{}) (interface{}, error) {
|
||
|
return data.(string) + "bar", nil
|
||
|
}
|
||
|
|
||
|
f := ComposeDecodeHookFunc(f1, f2)
|
||
|
|
||
|
result, err := DecodeHookExec(
|
||
|
f, reflect.TypeOf(""), reflect.TypeOf([]byte("")), "")
|
||
|
if err != nil {
|
||
|
t.Fatalf("bad: %s", err)
|
||
|
}
|
||
|
if result.(string) != "foobar" {
|
||
|
t.Fatalf("bad: %#v", result)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestComposeDecodeHookFunc_err(t *testing.T) {
|
||
|
f1 := func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error) {
|
||
|
return nil, errors.New("foo")
|
||
|
}
|
||
|
|
||
|
f2 := func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error) {
|
||
|
panic("NOPE")
|
||
|
}
|
||
|
|
||
|
f := ComposeDecodeHookFunc(f1, f2)
|
||
|
|
||
|
_, err := DecodeHookExec(
|
||
|
f, reflect.TypeOf(""), reflect.TypeOf([]byte("")), 42)
|
||
|
if err.Error() != "foo" {
|
||
|
t.Fatalf("bad: %s", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestComposeDecodeHookFunc_kinds(t *testing.T) {
|
||
|
var f2From reflect.Kind
|
||
|
|
||
|
f1 := func(
|
||
|
f reflect.Kind,
|
||
|
t reflect.Kind,
|
||
|
data interface{}) (interface{}, error) {
|
||
|
return int(42), nil
|
||
|
}
|
||
|
|
||
|
f2 := func(
|
||
|
f reflect.Kind,
|
||
|
t reflect.Kind,
|
||
|
data interface{}) (interface{}, error) {
|
||
|
f2From = f
|
||
|
return data, nil
|
||
|
}
|
||
|
|
||
|
f := ComposeDecodeHookFunc(f1, f2)
|
||
|
|
||
|
_, err := DecodeHookExec(
|
||
|
f, reflect.TypeOf(""), reflect.TypeOf([]byte("")), "")
|
||
|
if err != nil {
|
||
|
t.Fatalf("bad: %s", err)
|
||
|
}
|
||
|
if f2From != reflect.Int {
|
||
|
t.Fatalf("bad: %#v", f2From)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestStringToSliceHookFunc(t *testing.T) {
|
||
|
f := StringToSliceHookFunc(",")
|
||
|
|
||
|
strType := reflect.TypeOf("")
|
||
|
sliceType := reflect.TypeOf([]byte(""))
|
||
|
cases := []struct {
|
||
|
f, t reflect.Type
|
||
|
data interface{}
|
||
|
result interface{}
|
||
|
err bool
|
||
|
}{
|
||
|
{sliceType, sliceType, 42, 42, false},
|
||
|
{strType, strType, 42, 42, false},
|
||
|
{
|
||
|
strType,
|
||
|
sliceType,
|
||
|
"foo,bar,baz",
|
||
|
[]string{"foo", "bar", "baz"},
|
||
|
false,
|
||
|
},
|
||
|
{
|
||
|
strType,
|
||
|
sliceType,
|
||
|
"",
|
||
|
[]string{},
|
||
|
false,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for i, tc := range cases {
|
||
|
actual, err := DecodeHookExec(f, tc.f, tc.t, tc.data)
|
||
|
if tc.err != (err != nil) {
|
||
|
t.Fatalf("case %d: expected err %#v", i, tc.err)
|
||
|
}
|
||
|
if !reflect.DeepEqual(actual, tc.result) {
|
||
|
t.Fatalf(
|
||
|
"case %d: expected %#v, got %#v",
|
||
|
i, tc.result, actual)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestStringToTimeDurationHookFunc(t *testing.T) {
|
||
|
f := StringToTimeDurationHookFunc()
|
||
|
|
||
|
strType := reflect.TypeOf("")
|
||
|
timeType := reflect.TypeOf(time.Duration(5))
|
||
|
cases := []struct {
|
||
|
f, t reflect.Type
|
||
|
data interface{}
|
||
|
result interface{}
|
||
|
err bool
|
||
|
}{
|
||
|
{strType, timeType, "5s", 5 * time.Second, false},
|
||
|
{strType, timeType, "5", time.Duration(0), true},
|
||
|
{strType, strType, "5", "5", false},
|
||
|
}
|
||
|
|
||
|
for i, tc := range cases {
|
||
|
actual, err := DecodeHookExec(f, tc.f, tc.t, tc.data)
|
||
|
if tc.err != (err != nil) {
|
||
|
t.Fatalf("case %d: expected err %#v", i, tc.err)
|
||
|
}
|
||
|
if !reflect.DeepEqual(actual, tc.result) {
|
||
|
t.Fatalf(
|
||
|
"case %d: expected %#v, got %#v",
|
||
|
i, tc.result, actual)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestWeaklyTypedHook(t *testing.T) {
|
||
|
var f DecodeHookFunc = WeaklyTypedHook
|
||
|
|
||
|
boolType := reflect.TypeOf(true)
|
||
|
strType := reflect.TypeOf("")
|
||
|
sliceType := reflect.TypeOf([]byte(""))
|
||
|
cases := []struct {
|
||
|
f, t reflect.Type
|
||
|
data interface{}
|
||
|
result interface{}
|
||
|
err bool
|
||
|
}{
|
||
|
// TO STRING
|
||
|
{
|
||
|
boolType,
|
||
|
strType,
|
||
|
false,
|
||
|
"0",
|
||
|
false,
|
||
|
},
|
||
|
|
||
|
{
|
||
|
boolType,
|
||
|
strType,
|
||
|
true,
|
||
|
"1",
|
||
|
false,
|
||
|
},
|
||
|
|
||
|
{
|
||
|
reflect.TypeOf(float32(1)),
|
||
|
strType,
|
||
|
float32(7),
|
||
|
"7",
|
||
|
false,
|
||
|
},
|
||
|
|
||
|
{
|
||
|
reflect.TypeOf(int(1)),
|
||
|
strType,
|
||
|
int(7),
|
||
|
"7",
|
||
|
false,
|
||
|
},
|
||
|
|
||
|
{
|
||
|
sliceType,
|
||
|
strType,
|
||
|
[]uint8("foo"),
|
||
|
"foo",
|
||
|
false,
|
||
|
},
|
||
|
|
||
|
{
|
||
|
reflect.TypeOf(uint(1)),
|
||
|
strType,
|
||
|
uint(7),
|
||
|
"7",
|
||
|
false,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for i, tc := range cases {
|
||
|
actual, err := DecodeHookExec(f, tc.f, tc.t, tc.data)
|
||
|
if tc.err != (err != nil) {
|
||
|
t.Fatalf("case %d: expected err %#v", i, tc.err)
|
||
|
}
|
||
|
if !reflect.DeepEqual(actual, tc.result) {
|
||
|
t.Fatalf(
|
||
|
"case %d: expected %#v, got %#v",
|
||
|
i, tc.result, actual)
|
||
|
}
|
||
|
}
|
||
|
}
|