tpl/collections: Make index work with slice as the last arg
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 11 Nov 2019 12:54:57 +0000 (13:54 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 11 Nov 2019 12:54:57 +0000 (13:54 +0100)
Fixes #6496

tpl/collections/index.go
tpl/collections/index_test.go

index b081511885ec5e98440b5b2bd62c9f5fffefde88..d2989e22fc5f7366f1d1aa22d5edee13d0fa17f6 100644 (file)
@@ -28,11 +28,27 @@ import (
 // We deviate from the stdlib due to https://github.com/golang/go/issues/14751.
 //
 // TODO(moorereason): merge upstream changes.
-func (ns *Namespace) Index(item interface{}, indices ...interface{}) (interface{}, error) {
+func (ns *Namespace) Index(item interface{}, args ...interface{}) (interface{}, error) {
        v := reflect.ValueOf(item)
        if !v.IsValid() {
                return nil, errors.New("index of untyped nil")
        }
+
+       var indices []interface{}
+
+       if len(args) == 1 {
+               v := reflect.ValueOf(args[0])
+               if v.Kind() == reflect.Slice {
+                       for i := 0; i < v.Len(); i++ {
+                               indices = append(indices, v.Index(i).Interface())
+                       }
+               }
+       }
+
+       if indices == nil {
+               indices = args
+       }
+
        for _, i := range indices {
                index := reflect.ValueOf(i)
                var isNil bool
index 6e9071abac7c404a69801b3cf3a4d8485c09eed6..c4cded47cf60f1893e6620498cacda1712448658 100644 (file)
@@ -14,6 +14,7 @@
 package collections
 
 import (
+       "fmt"
        "testing"
 
        qt "github.com/frankban/quicktest"
@@ -40,22 +41,26 @@ func TestIndex(t *testing.T) {
                {map[string]map[string]string{"a": {"b": "c"}}, []interface{}{"a", "b"}, "c", false},
                {[]map[string]map[string]string{{"a": {"b": "c"}}}, []interface{}{0, "a", "b"}, "c", false},
                {map[string]map[string]interface{}{"a": {"b": []string{"c", "d"}}}, []interface{}{"a", "b", 1}, "d", false},
+               {map[string]map[string]string{"a": {"b": "c"}}, []interface{}{[]string{"a", "b"}}, "c", false},
+
                // errors
                {nil, nil, nil, true},
                {[]int{0, 1}, []interface{}{"1"}, nil, true},
                {[]int{0, 1}, []interface{}{nil}, nil, true},
                {tstNoStringer{}, []interface{}{0}, nil, true},
        } {
-               errMsg := qt.Commentf("[%d] %v", i, test)
 
-               result, err := ns.Index(test.item, test.indices...)
+               c.Run(fmt.Sprint(i), func(c *qt.C) {
+                       errMsg := qt.Commentf("[%d] %v", i, test)
 
-               if test.isErr {
-                       c.Assert(err, qt.Not(qt.IsNil), errMsg)
-                       continue
-               }
+                       result, err := ns.Index(test.item, test.indices...)
 
-               c.Assert(err, qt.IsNil, errMsg)
-               c.Assert(result, qt.DeepEquals, test.expect, errMsg)
+                       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)
+               })
        }
 }