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)
		}
	}
}
Exemple #2
0
// 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)
		}
	}
}