github.com/anakojm/hugo-katex@v0.0.0-20231023141351-42d6f5de9c0b/tpl/collections/merge_test.go (about)

     1  // Copyright 2019 The Hugo Authors. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package collections
    15  
    16  import (
    17  	"bytes"
    18  	"reflect"
    19  	"testing"
    20  
    21  	"github.com/gohugoio/hugo/common/maps"
    22  	"github.com/gohugoio/hugo/parser"
    23  	"github.com/gohugoio/hugo/parser/metadecoders"
    24  
    25  	qt "github.com/frankban/quicktest"
    26  )
    27  
    28  func TestMerge(t *testing.T) {
    29  	ns := newNs()
    30  
    31  	simpleMap := map[string]any{"a": 1, "b": 2}
    32  
    33  	for i, test := range []struct {
    34  		name   string
    35  		params []any
    36  		expect any
    37  		isErr  bool
    38  	}{
    39  		{
    40  			"basic",
    41  			[]any{
    42  				map[string]any{"a": 42, "c": 3},
    43  				map[string]any{"a": 1, "b": 2},
    44  			},
    45  			map[string]any{"a": 1, "b": 2, "c": 3},
    46  			false,
    47  		},
    48  		{
    49  			"multi",
    50  			[]any{
    51  				map[string]any{"a": 42, "c": 3, "e": 11},
    52  				map[string]any{"a": 1, "b": 2},
    53  				map[string]any{"a": 9, "c": 4, "d": 7},
    54  			},
    55  			map[string]any{"a": 9, "b": 2, "c": 4, "d": 7, "e": 11},
    56  			false,
    57  		},
    58  		{
    59  			"basic case insensitive",
    60  			[]any{
    61  				map[string]any{"A": 42, "c": 3},
    62  				map[string]any{"a": 1, "b": 2},
    63  			},
    64  			map[string]any{"a": 1, "b": 2, "c": 3},
    65  			false,
    66  		},
    67  		{
    68  			"nested",
    69  			[]any{
    70  				map[string]any{"a": 42, "c": 3, "b": map[string]any{"d": 55, "e": 66, "f": 3}},
    71  				map[string]any{"a": 1, "b": map[string]any{"d": 1, "e": 2}},
    72  			},
    73  			map[string]any{"a": 1, "b": map[string]any{"d": 1, "e": 2, "f": 3}, "c": 3},
    74  			false,
    75  		},
    76  		{
    77  			// https://github.com/gohugoio/hugo/issues/6633
    78  			"params dst",
    79  			[]any{
    80  				map[string]any{"a": 42, "c": 3},
    81  				maps.Params{"a": 1, "b": 2},
    82  			},
    83  			maps.Params{"a": int(1), "b": int(2), "c": int(3)},
    84  			false,
    85  		},
    86  		{
    87  			"params dst, upper case src",
    88  			[]any{
    89  				map[string]any{"a": 42, "C": 3},
    90  				maps.Params{"a": 1, "b": 2},
    91  			},
    92  			maps.Params{"a": int(1), "b": int(2), "c": int(3)},
    93  			false,
    94  		},
    95  		{
    96  			"params src",
    97  			[]any{
    98  				maps.Params{"a": 42, "c": 3},
    99  				map[string]any{"a": 1, "c": 2},
   100  			},
   101  			map[string]any{"a": int(1), "c": int(2)},
   102  			false,
   103  		},
   104  		{
   105  			"params src, upper case dst",
   106  			[]any{
   107  				maps.Params{"a": 42, "c": 3},
   108  				map[string]any{"a": 1, "C": 2},
   109  			},
   110  			map[string]any{"a": int(1), "C": int(2)},
   111  			false,
   112  		},
   113  		{
   114  			"nested, params dst",
   115  			[]any{
   116  				map[string]any{"a": 42, "c": 3, "b": map[string]any{"d": 55, "e": 66, "f": 3}},
   117  				maps.Params{"a": 1, "b": maps.Params{"d": 1, "e": 2}},
   118  			},
   119  			maps.Params{"a": 1, "b": maps.Params{"d": 1, "e": 2, "f": 3}, "c": 3},
   120  			false,
   121  		},
   122  		{
   123  			// https://github.com/gohugoio/hugo/issues/7899
   124  			"matching keys with non-map src value",
   125  			[]any{
   126  				map[string]any{"k": "v"},
   127  				map[string]any{"k": map[string]any{"k2": "v2"}},
   128  			},
   129  			map[string]any{"k": map[string]any{"k2": "v2"}},
   130  			false,
   131  		},
   132  		{"src nil", []any{nil, simpleMap}, simpleMap, false},
   133  		// Error cases.
   134  		{"dst not a map", []any{nil, "not a map"}, nil, true},
   135  		{"src not a map", []any{"not a map", simpleMap}, nil, true},
   136  		{"different map types", []any{map[int]any{32: "a"}, simpleMap}, nil, true},
   137  		{"all nil", []any{nil, nil}, nil, true},
   138  	} {
   139  
   140  		test := test
   141  		i := i
   142  
   143  		t.Run(test.name, func(t *testing.T) {
   144  			t.Parallel()
   145  			errMsg := qt.Commentf("[%d] %v", i, test)
   146  
   147  			c := qt.New(t)
   148  
   149  			result, err := ns.Merge(test.params...)
   150  
   151  			if test.isErr {
   152  				c.Assert(err, qt.Not(qt.IsNil), errMsg)
   153  				return
   154  			}
   155  
   156  			c.Assert(err, qt.IsNil)
   157  			c.Assert(result, qt.DeepEquals, test.expect, errMsg)
   158  		})
   159  	}
   160  }
   161  
   162  func TestMergeDataFormats(t *testing.T) {
   163  	c := qt.New(t)
   164  	ns := newNs()
   165  
   166  	toml1 := `
   167  V1 = "v1_1"
   168  
   169  [V2s]
   170  V21 = "v21_1"
   171  
   172  `
   173  
   174  	toml2 := `
   175  V1 = "v1_2"
   176  V2 = "v2_2"
   177  
   178  [V2s]
   179  V21 = "v21_2"
   180  V22 = "v22_2"
   181  
   182  `
   183  
   184  	meta1, err := metadecoders.Default.UnmarshalToMap([]byte(toml1), metadecoders.TOML)
   185  	c.Assert(err, qt.IsNil)
   186  	meta2, err := metadecoders.Default.UnmarshalToMap([]byte(toml2), metadecoders.TOML)
   187  	c.Assert(err, qt.IsNil)
   188  
   189  	for _, format := range []metadecoders.Format{metadecoders.JSON, metadecoders.YAML, metadecoders.TOML} {
   190  
   191  		var dataStr1, dataStr2 bytes.Buffer
   192  		err = parser.InterfaceToConfig(meta1, format, &dataStr1)
   193  		c.Assert(err, qt.IsNil)
   194  		err = parser.InterfaceToConfig(meta2, format, &dataStr2)
   195  		c.Assert(err, qt.IsNil)
   196  
   197  		dst, err := metadecoders.Default.UnmarshalToMap(dataStr1.Bytes(), format)
   198  		c.Assert(err, qt.IsNil)
   199  		src, err := metadecoders.Default.UnmarshalToMap(dataStr2.Bytes(), format)
   200  		c.Assert(err, qt.IsNil)
   201  
   202  		merged, err := ns.Merge(src, dst)
   203  		c.Assert(err, qt.IsNil)
   204  
   205  		c.Assert(
   206  			merged,
   207  			qt.DeepEquals,
   208  			map[string]any{
   209  				"V1": "v1_1", "V2": "v2_2",
   210  				"V2s": map[string]any{"V21": "v21_1", "V22": "v22_2"},
   211  			})
   212  	}
   213  }
   214  
   215  func TestCaseInsensitiveMapLookup(t *testing.T) {
   216  	c := qt.New(t)
   217  
   218  	m1 := reflect.ValueOf(map[string]any{
   219  		"a": 1,
   220  		"B": 2,
   221  	})
   222  
   223  	m2 := reflect.ValueOf(map[int]any{
   224  		1: 1,
   225  		2: 2,
   226  	})
   227  
   228  	var found bool
   229  
   230  	a, found := caseInsensitiveLookup(m1, reflect.ValueOf("A"))
   231  	c.Assert(found, qt.Equals, true)
   232  	c.Assert(a.Interface(), qt.Equals, 1)
   233  
   234  	b, found := caseInsensitiveLookup(m1, reflect.ValueOf("b"))
   235  	c.Assert(found, qt.Equals, true)
   236  	c.Assert(b.Interface(), qt.Equals, 2)
   237  
   238  	two, found := caseInsensitiveLookup(m2, reflect.ValueOf(2))
   239  	c.Assert(found, qt.Equals, true)
   240  	c.Assert(two.Interface(), qt.Equals, 2)
   241  }