mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
tpl/collections: Fix some index cases where the indices given is a slice and be more lenient with nil inputs
See adjusted tests for detail. Fixes #10489
This commit is contained in:
parent
7d5e3ab8a8
commit
d373774cbe
2 changed files with 41 additions and 12 deletions
|
@ -35,12 +35,9 @@ import (
|
|||
func (ns *Namespace) Index(item any, args ...any) (any, error) {
|
||||
v := reflect.ValueOf(item)
|
||||
if !v.IsValid() {
|
||||
return nil, errors.New("index of untyped nil")
|
||||
}
|
||||
|
||||
lowerm, ok := item.(maps.Params)
|
||||
if ok {
|
||||
return lowerm.Get(cast.ToStringSlice(args)...), nil
|
||||
// See issue 10489
|
||||
// This used to be an error.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var indices []any
|
||||
|
@ -51,18 +48,25 @@ func (ns *Namespace) Index(item any, args ...any) (any, error) {
|
|||
for i := 0; i < v.Len(); i++ {
|
||||
indices = append(indices, v.Index(i).Interface())
|
||||
}
|
||||
} else {
|
||||
indices = append(indices, args[0])
|
||||
}
|
||||
} else {
|
||||
indices = args
|
||||
}
|
||||
|
||||
if indices == nil {
|
||||
indices = args
|
||||
lowerm, ok := item.(maps.Params)
|
||||
if ok {
|
||||
return lowerm.Get(cast.ToStringSlice(indices)...), nil
|
||||
}
|
||||
|
||||
for _, i := range indices {
|
||||
index := reflect.ValueOf(i)
|
||||
var isNil bool
|
||||
if v, isNil = indirect(v); isNil {
|
||||
return nil, errors.New("index of nil pointer")
|
||||
// See issue 10489
|
||||
// This used to be an error.
|
||||
return nil, nil
|
||||
}
|
||||
switch v.Kind() {
|
||||
case reflect.Array, reflect.Slice, reflect.String:
|
||||
|
|
|
@ -30,6 +30,11 @@ func TestIndex(t *testing.T) {
|
|||
c := qt.New(t)
|
||||
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||
|
||||
var (
|
||||
emptyInterface any
|
||||
nilPointer *int
|
||||
)
|
||||
|
||||
for i, test := range []struct {
|
||||
item any
|
||||
indices []any
|
||||
|
@ -45,16 +50,23 @@ func TestIndex(t *testing.T) {
|
|||
{map[string]map[string]string{"a": {"b": "c"}}, []any{"a", "b"}, "c", false},
|
||||
{[]map[string]map[string]string{{"a": {"b": "c"}}}, []any{0, "a", "b"}, "c", false},
|
||||
{map[string]map[string]any{"a": {"b": []string{"c", "d"}}}, []any{"a", "b", 1}, "d", false},
|
||||
{map[string]map[string]string{"a": {"b": "c"}}, []any{[]string{"a", "b"}}, "c", false},
|
||||
{maps.Params{"a": "av"}, []any{"A"}, "av", false},
|
||||
{maps.Params{"a": map[string]any{"b": "bv"}}, []any{"A", "B"}, "bv", false},
|
||||
|
||||
// These used to be errors.
|
||||
// See issue 10489.
|
||||
{nil, nil, nil, false},
|
||||
{nil, []any{0}, nil, false},
|
||||
{emptyInterface, []any{0}, nil, false},
|
||||
{nilPointer, []any{0}, nil, false},
|
||||
|
||||
// errors
|
||||
{nil, nil, nil, true},
|
||||
{[]int{0, 1}, []any{"1"}, nil, true},
|
||||
{[]int{0, 1}, []any{nil}, nil, true},
|
||||
{tstNoStringer{}, []any{0}, nil, true},
|
||||
} {
|
||||
c.Run(fmt.Sprint(i), func(c *qt.C) {
|
||||
|
||||
c.Run(fmt.Sprintf("vararg %d", i), func(c *qt.C) {
|
||||
errMsg := qt.Commentf("[%d] %v", i, test)
|
||||
|
||||
result, err := ns.Index(test.item, test.indices...)
|
||||
|
@ -66,5 +78,18 @@ func TestIndex(t *testing.T) {
|
|||
c.Assert(err, qt.IsNil, errMsg)
|
||||
c.Assert(result, qt.DeepEquals, test.expect, errMsg)
|
||||
})
|
||||
|
||||
c.Run(fmt.Sprintf("slice %d", i), func(c *qt.C) {
|
||||
errMsg := qt.Commentf("[%d] %v", i, test)
|
||||
|
||||
result, err := ns.Index(test.item, test.indices)
|
||||
|
||||
if test.isErr {
|
||||
c.Assert(err, qt.Not(qt.IsNil), errMsg)
|
||||
return
|
||||
}
|
||||
c.Assert(err, qt.IsNil, errMsg)
|
||||
c.Assert(result, qt.DeepEquals, test.expect, errMsg)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue