Merge pull request #36 from DataDog/dustin.long/search-urlkey-override

When a key has a url in it, v.Get should return v.override values, instead of only v.config
This commit is contained in:
Dustin Long 2024-05-28 09:42:54 -04:00 committed by GitHub
commit c4cf4fd691
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 49 additions and 2 deletions

View file

@ -1026,8 +1026,8 @@ func (v *Viper) find(lcaseKey string, skipDefault bool) interface{} {
path = strings.Split(lcaseKey, v.keyDelim)
nested = len(path) > 1
// Set() override first
val = v.searchMap(v.override, path)
// Set() writes to override, so check override first
val = v.searchMapWithPathPrefixes(v.override, path)
if val != nil {
return val
}

View file

@ -49,6 +49,24 @@ eyes : brown
beard: true
`)
var yamlExampleWithURLKey = []byte(`Hacker: true
name: steve
hobbies:
- skateboarding
- snowboarding
- go
clothing:
jacket: leather
trousers: denim
pants:
size: large
http://example.com:
review
age: 35
eyes : brown
beard: true
`)
var yamlExampleWithExtras = []byte(`Existing: true
Bogus: true
`)
@ -154,6 +172,10 @@ func initYAML(v *Viper) {
initConfig(v, "yaml", string(yamlExample))
}
func initYAMLWithURLKey(v *Viper) {
initConfig(v, "yaml", string(yamlExampleWithURLKey))
}
func initJSON(v *Viper) {
v.SetConfigType("json")
r := bytes.NewReader(jsonExample)
@ -1894,3 +1916,28 @@ func TestIsKnown(t *testing.T) {
assert.False(t, v.IsKnown("unknown"))
}
func copyMap(m map[string]interface{}) map[string]interface{} {
res := make(map[string]interface{})
for k, v := range m {
res[k] = v
}
return res
}
func TestAssignToMapThenGet(t *testing.T) {
v := New()
initYAMLWithURLKey(v)
// NOTE: copyMap is necessary here for the test to demonstrate the actual issue
// Without copying this map, this block of code will modify the v.defaults layer
// which hides the bug that v.Get should return the v.override value
clothingElem := copyMap(v.Get("clothing").(map[string]interface{}))
clothingElem["http://example.com"] = "recommendation"
v.Set("clothing", clothingElem)
// demonstart that v.Get returns the overriden value, despite having a url in the
// key path, and the key not being set directly, but rather being set as a map key
expected := `recommendation`
require.Equal(t, expected, v.Get("clothing.http://example.com"))
}