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