mirror of
https://github.com/spf13/viper
synced 2024-11-04 20:27:02 +00:00
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:
parent
d9cca5ef33
commit
9ce37a02f1
3 changed files with 129 additions and 3 deletions
4
LICENSE
4
LICENSE
|
@ -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
|
||||||
|
@ -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
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
|
|
1
viper.go
1
viper.go
|
@ -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)
|
||||||
|
|
127
viper_test.go
127
viper_test.go
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue