hugo

Fork of github.com/gohugoio/hugo with reverse pagination support

git clone git://git.shimmy1996.com/hugo.git

merge_test.go (5859B)

    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/config"
   23 	"github.com/gohugoio/hugo/deps"
   24 	"github.com/gohugoio/hugo/langs"
   25 	"github.com/gohugoio/hugo/parser"
   26 	"github.com/gohugoio/hugo/parser/metadecoders"
   27 
   28 	qt "github.com/frankban/quicktest"
   29 )
   30 
   31 func TestMerge(t *testing.T) {
   32 	ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
   33 
   34 	simpleMap := map[string]any{"a": 1, "b": 2}
   35 
   36 	for i, test := range []struct {
   37 		name   string
   38 		params []any
   39 		expect any
   40 		isErr  bool
   41 	}{
   42 		{
   43 			"basic",
   44 			[]any{
   45 				map[string]any{"a": 42, "c": 3},
   46 				map[string]any{"a": 1, "b": 2},
   47 			},
   48 			map[string]any{"a": 1, "b": 2, "c": 3},
   49 			false,
   50 		},
   51 		{
   52 			"multi",
   53 			[]any{
   54 				map[string]any{"a": 42, "c": 3, "e": 11},
   55 				map[string]any{"a": 1, "b": 2},
   56 				map[string]any{"a": 9, "c": 4, "d": 7},
   57 			},
   58 			map[string]any{"a": 9, "b": 2, "c": 4, "d": 7, "e": 11},
   59 			false,
   60 		},
   61 		{
   62 			"basic case insensitive",
   63 			[]any{
   64 				map[string]any{"A": 42, "c": 3},
   65 				map[string]any{"a": 1, "b": 2},
   66 			},
   67 			map[string]any{"a": 1, "b": 2, "c": 3},
   68 			false,
   69 		},
   70 		{
   71 			"nested",
   72 			[]any{
   73 				map[string]any{"a": 42, "c": 3, "b": map[string]any{"d": 55, "e": 66, "f": 3}},
   74 				map[string]any{"a": 1, "b": map[string]any{"d": 1, "e": 2}},
   75 			},
   76 			map[string]any{"a": 1, "b": map[string]any{"d": 1, "e": 2, "f": 3}, "c": 3},
   77 			false,
   78 		},
   79 		{
   80 			// https://github.com/gohugoio/hugo/issues/6633
   81 			"params dst",
   82 			[]any{
   83 				map[string]any{"a": 42, "c": 3},
   84 				maps.Params{"a": 1, "b": 2},
   85 			},
   86 			maps.Params{"a": int(1), "b": int(2), "c": int(3)},
   87 			false,
   88 		},
   89 		{
   90 			"params dst, upper case src",
   91 			[]any{
   92 				map[string]any{"a": 42, "C": 3},
   93 				maps.Params{"a": 1, "b": 2},
   94 			},
   95 			maps.Params{"a": int(1), "b": int(2), "c": int(3)},
   96 			false,
   97 		},
   98 		{
   99 			"params src",
  100 			[]any{
  101 				maps.Params{"a": 42, "c": 3},
  102 				map[string]any{"a": 1, "c": 2},
  103 			},
  104 			map[string]any{"a": int(1), "c": int(2)},
  105 			false,
  106 		},
  107 		{
  108 			"params src, upper case dst",
  109 			[]any{
  110 				maps.Params{"a": 42, "c": 3},
  111 				map[string]any{"a": 1, "C": 2},
  112 			},
  113 			map[string]any{"a": int(1), "C": int(2)},
  114 			false,
  115 		},
  116 		{
  117 			"nested, params dst",
  118 			[]any{
  119 				map[string]any{"a": 42, "c": 3, "b": map[string]any{"d": 55, "e": 66, "f": 3}},
  120 				maps.Params{"a": 1, "b": maps.Params{"d": 1, "e": 2}},
  121 			},
  122 			maps.Params{"a": 1, "b": maps.Params{"d": 1, "e": 2, "f": 3}, "c": 3},
  123 			false,
  124 		},
  125 		{
  126 			// https://github.com/gohugoio/hugo/issues/7899
  127 			"matching keys with non-map src value",
  128 			[]any{
  129 				map[string]any{"k": "v"},
  130 				map[string]any{"k": map[string]any{"k2": "v2"}},
  131 			},
  132 			map[string]any{"k": map[string]any{"k2": "v2"}},
  133 			false,
  134 		},
  135 		{"src nil", []any{nil, simpleMap}, simpleMap, false},
  136 		// Error cases.
  137 		{"dst not a map", []any{nil, "not a map"}, nil, true},
  138 		{"src not a map", []any{"not a map", simpleMap}, nil, true},
  139 		{"different map types", []any{map[int]any{32: "a"}, simpleMap}, nil, true},
  140 		{"all nil", []any{nil, nil}, nil, true},
  141 	} {
  142 
  143 		test := test
  144 
  145 		t.Run(test.name, func(t *testing.T) {
  146 			t.Parallel()
  147 			errMsg := qt.Commentf("[%d] %v", i, test)
  148 
  149 			c := qt.New(t)
  150 
  151 			result, err := ns.Merge(test.params...)
  152 
  153 			if test.isErr {
  154 				c.Assert(err, qt.Not(qt.IsNil), errMsg)
  155 				return
  156 			}
  157 
  158 			c.Assert(err, qt.IsNil)
  159 			c.Assert(result, qt.DeepEquals, test.expect, errMsg)
  160 		})
  161 	}
  162 }
  163 
  164 func TestMergeDataFormats(t *testing.T) {
  165 	c := qt.New(t)
  166 	ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
  167 
  168 	toml1 := `
  169 V1 = "v1_1"
  170 
  171 [V2s]
  172 V21 = "v21_1"
  173 
  174 `
  175 
  176 	toml2 := `
  177 V1 = "v1_2"
  178 V2 = "v2_2"
  179 
  180 [V2s]
  181 V21 = "v21_2"
  182 V22 = "v22_2"
  183 
  184 `
  185 
  186 	meta1, err := metadecoders.Default.UnmarshalToMap([]byte(toml1), metadecoders.TOML)
  187 	c.Assert(err, qt.IsNil)
  188 	meta2, err := metadecoders.Default.UnmarshalToMap([]byte(toml2), metadecoders.TOML)
  189 	c.Assert(err, qt.IsNil)
  190 
  191 	for _, format := range []metadecoders.Format{metadecoders.JSON, metadecoders.YAML, metadecoders.TOML} {
  192 
  193 		var dataStr1, dataStr2 bytes.Buffer
  194 		err = parser.InterfaceToConfig(meta1, format, &dataStr1)
  195 		c.Assert(err, qt.IsNil)
  196 		err = parser.InterfaceToConfig(meta2, format, &dataStr2)
  197 		c.Assert(err, qt.IsNil)
  198 
  199 		dst, err := metadecoders.Default.UnmarshalToMap(dataStr1.Bytes(), format)
  200 		c.Assert(err, qt.IsNil)
  201 		src, err := metadecoders.Default.UnmarshalToMap(dataStr2.Bytes(), format)
  202 		c.Assert(err, qt.IsNil)
  203 
  204 		merged, err := ns.Merge(src, dst)
  205 		c.Assert(err, qt.IsNil)
  206 
  207 		c.Assert(
  208 			merged,
  209 			qt.DeepEquals,
  210 			map[string]any{
  211 				"V1": "v1_1", "V2": "v2_2",
  212 				"V2s": map[string]any{"V21": "v21_1", "V22": "v22_2"},
  213 			})
  214 	}
  215 }
  216 
  217 func TestCaseInsensitiveMapLookup(t *testing.T) {
  218 	c := qt.New(t)
  219 
  220 	m1 := reflect.ValueOf(map[string]any{
  221 		"a": 1,
  222 		"B": 2,
  223 	})
  224 
  225 	m2 := reflect.ValueOf(map[int]any{
  226 		1: 1,
  227 		2: 2,
  228 	})
  229 
  230 	var found bool
  231 
  232 	a, found := caseInsensitiveLookup(m1, reflect.ValueOf("A"))
  233 	c.Assert(found, qt.Equals, true)
  234 	c.Assert(a.Interface(), qt.Equals, 1)
  235 
  236 	b, found := caseInsensitiveLookup(m1, reflect.ValueOf("b"))
  237 	c.Assert(found, qt.Equals, true)
  238 	c.Assert(b.Interface(), qt.Equals, 2)
  239 
  240 	two, found := caseInsensitiveLookup(m2, reflect.ValueOf(2))
  241 	c.Assert(found, qt.Equals, true)
  242 	c.Assert(two.Interface(), qt.Equals, 2)
  243 }