shithub: hugo

Download patch

ref: ccb1bf1abb7341fa1be23a90b66c14ae89790f49
parent: a67d95fe1a033ca4934957b5a98b12ecc8a9edbd
author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
date: Thu Dec 19 15:50:30 EST 2019

tpl/collections: Some more params merge adjustments

* 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

--- a/tpl/collections/merge.go
+++ b/tpl/collections/merge.go
@@ -17,6 +17,8 @@
 	"reflect"
 	"strings"
 
+	"github.com/gohugoio/hugo/common/maps"
+
 	"github.com/gohugoio/hugo/common/hreflect"
 
 	"github.com/pkg/errors"
@@ -68,6 +70,9 @@
 
 	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 @@
 		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)
 		}
 	}
--- a/tpl/collections/merge_test.go
+++ b/tpl/collections/merge_test.go
@@ -66,11 +66,25 @@
 			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},