tpl/collections: Some more params merge adjustments
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Thu, 19 Dec 2019 19:50:30 +0000 (20:50 +0100)
committerGitHub <noreply@github.com>
Thu, 19 Dec 2019 19:50:30 +0000 (20:50 +0100)
* If the end result is maps.Params, we need to lower the keys
* Also make sure to handle nested maps of different type

Update #6633

tpl/collections/merge.go
tpl/collections/merge_test.go

index 39ef932ca0887ee024dd1f70d0def03b67c6cc67..c65e9dd90853ee6d3f76d5431ba0dd58abdfa6d6 100644 (file)
@@ -17,6 +17,8 @@ import (
        "reflect"
        "strings"
 
+       "github.com/gohugoio/hugo/common/maps"
+
        "github.com/gohugoio/hugo/common/hreflect"
 
        "github.com/pkg/errors"
@@ -68,6 +70,9 @@ func mergeMap(dst, src reflect.Value) reflect.Value {
 
        out := reflect.MakeMap(dst.Type())
 
+       // If the destination is Params, we must lower case all keys.
+       _, lowerCase := dst.Interface().(maps.Params)
+
        // Copy the destination map.
        for _, key := range dst.MapKeys() {
                v := dst.MapIndex(key)
@@ -81,15 +86,18 @@ func mergeMap(dst, src reflect.Value) reflect.Value {
                dv, found := caseInsensitiveLookup(dst, key)
 
                if found {
-                       // If both are the same map type, merge.
+                       // If both are the same map key type, merge.
                        dve := dv.Elem()
                        if dve.Kind() == reflect.Map {
                                sve := sv.Elem()
-                               if dve.Type() == sve.Type() {
+                               if dve.Type().Key() == sve.Type().Key() {
                                        out.SetMapIndex(key, mergeMap(dve, sve))
                                }
                        }
                } else {
+                       if lowerCase && key.Kind() == reflect.String {
+                               key = reflect.ValueOf(strings.ToLower(key.String()))
+                       }
                        out.SetMapIndex(key, sv)
                }
        }
index 57163a0d5adcf835d1309a4153d012589c2d51c5..c18664e25cdb9949d3f5d1e744d550e55281a748 100644 (file)
@@ -66,11 +66,25 @@ func TestMerge(t *testing.T) {
                        map[string]interface{}{"a": 42, "c": 3},
                        maps.Params{"a": int(1), "b": int(2), "c": int(3)}, false},
                {
-                       // https://github.com/gohugoio/hugo/issues/6633
+                       "params dst, upper case src",
+                       maps.Params{"a": 1, "b": 2},
+                       map[string]interface{}{"a": 42, "C": 3},
+                       maps.Params{"a": int(1), "b": int(2), "c": int(3)}, false},
+               {
                        "params src",
                        map[string]interface{}{"a": 1, "c": 2},
                        maps.Params{"a": 42, "c": 3},
                        map[string]interface{}{"a": int(1), "c": int(2)}, false},
+               {
+                       "params src, upper case dst",
+                       map[string]interface{}{"a": 1, "C": 2},
+                       maps.Params{"a": 42, "c": 3},
+                       map[string]interface{}{"a": int(1), "C": int(2)}, false},
+               {
+                       "nested, params dst",
+                       maps.Params{"a": 1, "b": maps.Params{"d": 1, "e": 2}},
+                       map[string]interface{}{"a": 42, "c": 3, "b": map[string]interface{}{"d": 55, "e": 66, "f": 3}},
+                       maps.Params{"a": 1, "b": maps.Params{"d": 1, "e": 2, "f": 3}, "c": 3}, false},
                {"src nil", simpleMap, nil, simpleMap, false},
                // Error cases.
                {"dst not a map", "not a map", nil, nil, true},