From fa673d63c12d88d0369a99b1511bd93cca2c5ae6 Mon Sep 17 00:00:00 2001 From: Chih-Hung Yeh Date: Tue, 20 Sep 2016 04:24:24 +0800 Subject: [PATCH] Fixe `ToDurationE()` It used to return zero valeus in some cases. The details are described in [this issue](https://github.com/spf13/viper/issues/203). More cases were also added in the unit test `TestToDuration()` --- cast_test.go | 31 +++++++++++++++++++++++++------ caste.go | 14 +++++++++----- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/cast_test.go b/cast_test.go index fa246fa..fa1ea23 100644 --- a/cast_test.go +++ b/cast_test.go @@ -174,10 +174,29 @@ func TestIndirectPointers(t *testing.T) { } func TestToDuration(t *testing.T) { - a := time.Second * 5 - ai := int64(a) - b := time.Second * 5 - bf := float64(b) - assert.Equal(t, ToDuration(ai), a) - assert.Equal(t, ToDuration(bf), b) + var td time.Duration = 5 + tests := []struct { + input interface{} + expected time.Duration + }{ + {time.Duration(5), td}, + {int64(5), td}, + {int32(5), td}, + {int16(5), td}, + {int8(5), td}, + {int(5), td}, + {float64(5), td}, + {float32(5), td}, + {string("5"), td}, + {string("5ns"), td}, + {string("5us"), time.Microsecond * td}, + {string("5µs"), time.Microsecond * td}, + {string("5ms"), time.Millisecond * td}, + {string("5s"), time.Second * td}, + {string("5m"), time.Minute * td}, + {string("5h"), time.Hour * td}, + } + for _, v := range tests { + assert.Equal(t, v.expected, ToDuration(v.input)) + } } diff --git a/caste.go b/caste.go index 56a2694..9475ca7 100644 --- a/caste.go +++ b/caste.go @@ -43,14 +43,18 @@ func ToDurationE(i interface{}) (d time.Duration, err error) { switch s := i.(type) { case time.Duration: return s, nil - case int64: - d = time.Duration(s) + case int64, int32, int16, int8, int: + d = time.Duration(ToInt64(s)) return - case float64: - d = time.Duration(s) + case float32, float64: + d = time.Duration(ToFloat64(s)) return case string: - d, err = time.ParseDuration(s) + if strings.ContainsAny(s, "nsuµmh") { + d, err = time.ParseDuration(s) + } else { + d, err = time.ParseDuration(s + "ns") + } return default: err = fmt.Errorf("Unable to Cast %#v to Duration\n", i)