mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-29 13:52:03 -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) {
|
func (ns *Namespace) Index(item any, args ...any) (any, error) {
|
||||||
v := reflect.ValueOf(item)
|
v := reflect.ValueOf(item)
|
||||||
if !v.IsValid() {
|
if !v.IsValid() {
|
||||||
return nil, errors.New("index of untyped nil")
|
// See issue 10489
|
||||||
}
|
// This used to be an error.
|
||||||
|
return nil, nil
|
||||||
lowerm, ok := item.(maps.Params)
|
|
||||||
if ok {
|
|
||||||
return lowerm.Get(cast.ToStringSlice(args)...), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var indices []any
|
var indices []any
|
||||||
|
@ -51,18 +48,25 @@ func (ns *Namespace) Index(item any, args ...any) (any, error) {
|
||||||
for i := 0; i < v.Len(); i++ {
|
for i := 0; i < v.Len(); i++ {
|
||||||
indices = append(indices, v.Index(i).Interface())
|
indices = append(indices, v.Index(i).Interface())
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
indices = append(indices, args[0])
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
indices = args
|
||||||
}
|
}
|
||||||
|
|
||||||
if indices == nil {
|
lowerm, ok := item.(maps.Params)
|
||||||
indices = args
|
if ok {
|
||||||
|
return lowerm.Get(cast.ToStringSlice(indices)...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, i := range indices {
|
for _, i := range indices {
|
||||||
index := reflect.ValueOf(i)
|
index := reflect.ValueOf(i)
|
||||||
var isNil bool
|
var isNil bool
|
||||||
if v, isNil = indirect(v); isNil {
|
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() {
|
switch v.Kind() {
|
||||||
case reflect.Array, reflect.Slice, reflect.String:
|
case reflect.Array, reflect.Slice, reflect.String:
|
||||||
|
|
|
@ -30,6 +30,11 @@ func TestIndex(t *testing.T) {
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
|
var (
|
||||||
|
emptyInterface any
|
||||||
|
nilPointer *int
|
||||||
|
)
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
item any
|
item any
|
||||||
indices []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{"a", "b"}, "c", false},
|
||||||
{[]map[string]map[string]string{{"a": {"b": "c"}}}, []any{0, "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]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": "av"}, []any{"A"}, "av", false},
|
||||||
{maps.Params{"a": map[string]any{"b": "bv"}}, []any{"A", "B"}, "bv", 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
|
// errors
|
||||||
{nil, nil, nil, true},
|
|
||||||
{[]int{0, 1}, []any{"1"}, nil, true},
|
{[]int{0, 1}, []any{"1"}, nil, true},
|
||||||
{[]int{0, 1}, []any{nil}, nil, true},
|
{[]int{0, 1}, []any{nil}, nil, true},
|
||||||
{tstNoStringer{}, []any{0}, 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)
|
errMsg := qt.Commentf("[%d] %v", i, test)
|
||||||
|
|
||||||
result, err := ns.Index(test.item, test.indices...)
|
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(err, qt.IsNil, errMsg)
|
||||||
c.Assert(result, qt.DeepEquals, test.expect, 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