Fix Sub to work with mixed-case subtrees

Viper assumes that the top level of the config is lower case. However it
doesn't have this same restriction for sub trees, so you can get in a
sutation where a Viper instance returned by `Sub` has a config with
upper case keys, but all the accessors lowercase the keys.

Also adds a test for the usecase.
This commit is contained in:
Justin Tulloss 2016-05-08 18:33:56 -07:00
parent d8a428b8a3
commit 442af302ff
2 changed files with 25 additions and 1 deletions

View file

@ -526,7 +526,10 @@ func (v *Viper) Sub(key string) *Viper {
subv := New() subv := New()
data := v.Get(key) data := v.Get(key)
if reflect.TypeOf(data).Kind() == reflect.Map { if reflect.TypeOf(data).Kind() == reflect.Map {
subv.config = cast.ToStringMap(data) m := cast.ToStringMap(data)
for k, v := range m {
subv.config[strings.ToLower(k)] = v
}
return subv return subv
} else { } else {
return nil return nil

View file

@ -41,6 +41,15 @@ var yamlExampleWithExtras = []byte(`Existing: true
Bogus: true Bogus: true
`) `)
var yamlExampleWithSubtreeCaps = []byte(`Hacker: true
name: steve
clothing:
JACKET: leather
TROUSERS: denim
pants:
size: large
`)
type testUnmarshalExtra struct { type testUnmarshalExtra struct {
Existing bool Existing bool
} }
@ -760,6 +769,18 @@ func TestSub(t *testing.T) {
assert.Equal(t, subv, (*Viper)(nil)) assert.Equal(t, subv, (*Viper)(nil))
} }
func TestSubWithCaps(t *testing.T) {
v := New()
v.SetConfigType("yaml")
v.ReadConfig(bytes.NewBuffer(yamlExampleWithSubtreeCaps))
subv := v.Sub("clothing")
assert.Equal(t, v.Get("clothing.JACKET"), subv.Get("jacket"))
subv = v.Sub("clothing.pants.size")
assert.Equal(t, subv, (*Viper)(nil))
}
var yamlMergeExampleTgt = []byte(` var yamlMergeExampleTgt = []byte(`
hello: hello:
pop: 37890 pop: 37890