func TestStringToSignalFunc(t *testing.T) { f := StringToSignalFunc() strType := reflect.TypeOf("") sigType := reflect.TypeOf((*os.Signal)(nil)).Elem() cases := []struct { f, t reflect.Type data interface{} expected interface{} err bool }{ {strType, sigType, "SIGTERM", syscall.SIGTERM, false}, {strType, sigType, "SIGINT", syscall.SIGINT, false}, // Invalid signal name {strType, sigType, "BACON", nil, true}, } for i, tc := range cases { actual, err := mapstructure.DecodeHookExec(f, tc.f, tc.t, tc.data) if (err != nil) != tc.err { t.Errorf("case %d: %s", i, err) } if !reflect.DeepEqual(actual, tc.expected) { t.Errorf("case %d: expected %#v to be %#v", i, actual, tc.expected) } } }
// customDecodeHook adds the additional functions of parsing durations from strings // as well as parsing strings of the format "[thing1, thing2, thing3]" into string slices // Note that whitespace around slice elements is removed func customDecodeHook() mapstructure.DecodeHookFunc { durationHook := mapstructure.StringToTimeDurationHookFunc() return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { dur, err := mapstructure.DecodeHookExec(durationHook, f, t, data) if err == nil { if _, ok := dur.(time.Duration); ok { return dur, nil } } if f.Kind() != reflect.String { return data, nil } raw := data.(string) l := len(raw) if raw[0] == '[' && raw[l-1] == ']' { slice := strings.Split(raw[1:l-1], ",") for i, v := range slice { slice[i] = strings.TrimSpace(v) } return slice, nil } return data, nil } }
func TestStringToFileModeFunc(t *testing.T) { f := StringToFileModeFunc() strType := reflect.TypeOf("") fmType := reflect.TypeOf(os.FileMode(0)) u32Type := reflect.TypeOf(uint32(0)) cases := []struct { f, t reflect.Type data interface{} expected interface{} err bool }{ {strType, fmType, "0600", os.FileMode(0600), false}, {strType, fmType, "4600", os.FileMode(04600), false}, // Prepends 0 automatically {strType, fmType, "600", os.FileMode(0600), false}, // Invalid file mode {strType, fmType, "12345", "12345", true}, // Invalid syntax {strType, fmType, "abcd", "abcd", true}, // Different type {strType, strType, "0600", "0600", false}, {strType, u32Type, "0600", "0600", false}, } for i, tc := range cases { actual, err := mapstructure.DecodeHookExec(f, tc.f, tc.t, tc.data) if (err != nil) != tc.err { t.Errorf("case %d: %s", i, err) } if !reflect.DeepEqual(actual, tc.expected) { t.Errorf("case %d: expected %#v to be %#v", i, actual, tc.expected) } } }