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) 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 Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

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

View file

@ -10,6 +10,7 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"math"
"os" "os"
"path" "path"
"reflect" "reflect"
@ -1169,6 +1170,132 @@ func TestParseNested(t *testing.T) {
assert.Equal(t, 200*time.Millisecond, items[0].Nested.Delay) 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) { func doTestCaseInsensitive(t *testing.T, typ, config string) {
initConfig(typ, config) initConfig(typ, config)
Set("RfD", true) Set("RfD", true)