Added testing for Get when typeByDefValue is set.

- viper_test.go: Added test for specifically testing type
casts in Get when `typeByDefValue` is set.

- viper.go: Removed (now stale) TODO for @bep.

- LICENSE: Updated copyright to "The Viper Authors" as @spf13 requested.
Also added Google as @google requested.
This commit is contained in:
Leo Rudberg 2017-10-02 15:43:02 -04:00
parent d9cca5ef33
commit 9ce37a02f1
3 changed files with 129 additions and 3 deletions

View file

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2014 Steve Francia
Copyright (c) 2014 The Viper Authors: Steve Francia, Google Inc., et al.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.

View file

@ -597,7 +597,6 @@ func (v *Viper) Get(key string) interface{} {
}
if v.typeByDefValue {
// TODO(bep) this branch isn't covered by a single test.
valType := val
path := strings.Split(lcaseKey, v.keyDelim)
defVal := v.searchMap(v.defaults, path)

View file

@ -10,6 +10,7 @@ import (
"fmt"
"io"
"io/ioutil"
"math"
"os"
"path"
"reflect"
@ -1169,6 +1170,132 @@ func TestParseNested(t *testing.T) {
assert.Equal(t, 200*time.Millisecond, items[0].Nested.Delay)
}
func TestGetTypeByDefValue(t *testing.T) {
const dobString = "1979-05-27T07:32:00Z"
dob, _ := time.Parse(time.RFC3339, dobString)
for _, tc := range []struct {
name string // name of the test case
key string // key for the value
// First test that Getting the default value is what we expect it to be.
defaultProvide interface{} // the given default value
defaultWant interface{} // what we expect Getting that default will return
// Then set the OS environment to a different value with its type
// inferred from the default value.
envProvide string // the given string representation of the env value
envWant interface{} // what we expect Getting that env will return
}{{
name: "casting to bool",
key: "bool_key",
defaultProvide: true,
defaultWant: true,
envProvide: "false",
envWant: false,
}, {
name: "casting to string",
key: "string_key",
defaultProvide: "reticulating splines",
defaultWant: "reticulating splines",
envProvide: "gophers!",
envWant: "gophers!",
}, {
name: "casting to int64",
key: "int64_key",
defaultProvide: int64(0xCAFE),
defaultWant: int(0xCAFE),
envProvide: "0xF00D",
envWant: int(0xF00D),
}, {
name: "casting to int32",
key: "int32_key",
defaultProvide: int32(0xD00D),
defaultWant: int(0xD00D),
envProvide: "0xBABE",
envWant: int(0xBABE),
}, {
name: "casting to int16",
key: "int16_key",
defaultProvide: int16(0xA),
defaultWant: int(0xA),
envProvide: "0xB",
envWant: int(0xB),
}, {
name: "casting to int8",
key: "int8_key",
defaultProvide: int8(4),
defaultWant: int(4),
envProvide: "3",
envWant: int(3),
}, {
name: "casting to int",
key: "int_key",
defaultProvide: int(0xCAFEF00D),
defaultWant: int(0xCAFEF00D),
envProvide: "5678",
envWant: int(5678),
}, {
name: "casting to float64",
key: "float64_key",
defaultProvide: float64(math.Pi),
defaultWant: float64(math.Pi),
envProvide: "98.7650",
envWant: float64(98.7650),
}, {
name: "casting to float32",
key: "float32_key",
// First truncate, then cast to 64 bits to get proper equality.
defaultProvide: float32(math.Phi),
defaultWant: float64(float32(math.Phi)),
envProvide: "1.23450",
envWant: float64(1.23450),
}, {
name: "casting to time",
key: "time_key",
defaultProvide: time.Unix(1234567890, 314159),
defaultWant: time.Unix(1234567890, 314159),
envProvide: dobString,
envWant: dob,
}, {
name: "casting to duration",
key: "duration_key",
defaultProvide: time.Duration(42 * time.Minute),
defaultWant: time.Duration(42 * time.Minute),
envProvide: "3h4m5s",
envWant: time.Duration(3*time.Hour + 4*time.Minute + 5*time.Second),
}, {
name: "casting to string slice",
key: "string_slice_key",
defaultProvide: []string{"hello", "world"},
defaultWant: []string{"hello", "world"},
envProvide: "aloha mars",
envWant: []string{"aloha", "mars"},
}} {
t.Run(tc.name, func(t *testing.T) {
// Setup.
viper := New()
viper.SetTypeByDefaultValue(true)
viper.SetDefault(tc.key, tc.defaultProvide)
viper.AutomaticEnv()
// Test default.
gotDefaultValue := viper.Get(tc.key)
assert.IsType(t, tc.defaultWant, gotDefaultValue, "when setting a default value")
assert.Equal(t, tc.defaultWant, gotDefaultValue, "when setting a default value")
// Test env (supercedes default, exemplifies type cast).
if err := os.Setenv(strings.ToUpper(tc.key), tc.envProvide); err != nil {
t.Fatalf("Setenv unexpectedly failed: %v", err)
}
viper.BindEnv(tc.key)
gotEnvValue := viper.Get(tc.key)
assert.IsType(t, tc.envWant, gotEnvValue, "when setting a env value")
assert.Equal(t, tc.envWant, gotEnvValue, "when setting an env value")
assert.IsType(t, gotDefaultValue, gotEnvValue) // sanity check
})
}
}
func doTestCaseInsensitive(t *testing.T, typ, config string) {
initConfig(typ, config)
Set("RfD", true)