Recurse into arrays when converting keys to lowercase

Fixes #1386

Signed-off-by: Andrew Richardson <andrew.richardson@kaleido.io>
This commit is contained in:
Andrew Richardson 2022-06-23 17:34:55 -04:00 committed by Márk Sági-Kazár
parent 98c63ede11
commit 5247643f02
2 changed files with 32 additions and 12 deletions

33
util.go
View file

@ -64,18 +64,25 @@ func copyAndInsensitiviseMap(m map[string]interface{}) map[string]interface{} {
return nm return nm
} }
func insensitiviseVal(val interface{}) interface{} {
switch val.(type) {
case map[interface{}]interface{}:
// nested map: cast and recursively insensitivise
val = cast.ToStringMap(val)
insensitiviseMap(val.(map[string]interface{}))
case map[string]interface{}:
// nested map: recursively insensitivise
insensitiviseMap(val.(map[string]interface{}))
case []interface{}:
// nested array: recursively insensitivise
insensitiveArray(val.([]interface{}))
}
return val
}
func insensitiviseMap(m map[string]interface{}) { func insensitiviseMap(m map[string]interface{}) {
for key, val := range m { for key, val := range m {
switch val.(type) { val = insensitiviseVal(val)
case map[interface{}]interface{}:
// nested map: cast and recursively insensitivise
val = cast.ToStringMap(val)
insensitiviseMap(val.(map[string]interface{}))
case map[string]interface{}:
// nested map: recursively insensitivise
insensitiviseMap(val.(map[string]interface{}))
}
lower := strings.ToLower(key) lower := strings.ToLower(key)
if key != lower { if key != lower {
// remove old key (not lower-cased) // remove old key (not lower-cased)
@ -86,6 +93,12 @@ func insensitiviseMap(m map[string]interface{}) {
} }
} }
func insensitiveArray(a []interface{}) {
for i, val := range a {
a[i] = insensitiviseVal(val)
}
}
func absPathify(logger Logger, inPath string) string { func absPathify(logger Logger, inPath string) string {
logger.Info("trying to resolve absolute path", "path", inPath) logger.Info("trying to resolve absolute path", "path", inPath)

View file

@ -2516,7 +2516,10 @@ func TestKeyDelimiter(t *testing.T) {
} }
var yamlDeepNestedSlices = []byte(`TV: var yamlDeepNestedSlices = []byte(`TV:
- title: "The expanse" - title: "The Expanse"
title_i18n:
USA: "The Expanse"
Japan: "エクスパンス -巨獣めざめる-"
seasons: seasons:
- first_released: "December 14, 2015" - first_released: "December 14, 2015"
episodes: episodes:
@ -2546,11 +2549,15 @@ func TestSliceIndexAccess(t *testing.T) {
err := v.unmarshalReader(r, v.config) err := v.unmarshalReader(r, v.config)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, "The expanse", v.GetString("tv.0.title")) assert.Equal(t, "The Expanse", v.GetString("tv.0.title"))
assert.Equal(t, "February 1, 2017", v.GetString("tv.0.seasons.1.first_released")) assert.Equal(t, "February 1, 2017", v.GetString("tv.0.seasons.1.first_released"))
assert.Equal(t, "Static", v.GetString("tv.0.seasons.1.episodes.2.title")) assert.Equal(t, "Static", v.GetString("tv.0.seasons.1.episodes.2.title"))
assert.Equal(t, "December 15, 2015", v.GetString("tv.0.seasons.0.episodes.1.air_date")) assert.Equal(t, "December 15, 2015", v.GetString("tv.0.seasons.0.episodes.1.air_date"))
// Test nested keys with capital letters
assert.Equal(t, "The Expanse", v.GetString("tv.0.title_i18n.USA"))
assert.Equal(t, "エクスパンス -巨獣めざめる-", v.GetString("tv.0.title_i18n.Japan"))
// Test for index out of bounds // Test for index out of bounds
assert.Equal(t, "", v.GetString("tv.0.seasons.2.first_released")) assert.Equal(t, "", v.GetString("tv.0.seasons.2.first_released"))