shithub: hugo

Download patch

ref: 74ea81b885adc64d0194df461cbc85667294d16e
parent: 577522bd45078fef46655d38f3e831d1df6b2744
author: Cameron Moore <[email protected]>
date: Thu Feb 23 17:35:20 EST 2017

tplimpl: return an error on unsupported type in isSet

Fixes #3092

--- a/tpl/tplimpl/template_funcs.go
+++ b/tpl/tplimpl/template_funcs.go
@@ -1276,7 +1276,7 @@
 
 // isSet returns whether a given array, channel, slice, or map has a key
 // defined.
-func isSet(a interface{}, key interface{}) bool {
+func isSet(a interface{}, key interface{}) (bool, error) {
 	av := reflect.ValueOf(a)
 	kv := reflect.ValueOf(key)
 
@@ -1283,15 +1283,17 @@
 	switch av.Kind() {
 	case reflect.Array, reflect.Chan, reflect.Slice:
 		if int64(av.Len()) > kv.Int() {
-			return true
+			return true, nil
 		}
 	case reflect.Map:
 		if kv.Type() == av.Type().Key() {
-			return av.MapIndex(kv).IsValid()
+			return av.MapIndex(kv).IsValid(), nil
 		}
+	default:
+		return false, fmt.Errorf("unsupported type %q", av.Kind())
 	}
 
-	return false
+	return false, nil
 }
 
 // returnWhenSet returns a given value if it set.  Otherwise, it returns an
--- a/tpl/tplimpl/template_funcs_test.go
+++ b/tpl/tplimpl/template_funcs_test.go
@@ -1017,13 +1017,31 @@
 
 func TestIsSet(t *testing.T) {
 	t.Parallel()
-	aSlice := []interface{}{1, 2, 3, 5}
-	aMap := map[string]interface{}{"a": 1, "b": 2}
 
-	assert.True(t, isSet(aSlice, 2))
-	assert.True(t, isSet(aMap, "b"))
-	assert.False(t, isSet(aSlice, 22))
-	assert.False(t, isSet(aMap, "bc"))
+	for _, test := range []struct {
+		src    interface{}
+		key    interface{}
+		res    bool
+		isErr  bool
+		errStr string
+	}{
+		{[]interface{}{1, 2, 3, 5}, 2, true, false, ""},
+		{[]interface{}{1, 2, 3, 5}, 22, false, false, ""},
+
+		{map[string]interface{}{"a": 1, "b": 2}, "b", true, false, ""},
+		{map[string]interface{}{"a": 1, "b": 2}, "bc", false, false, ""},
+
+		{time.Now(), 1, false, true, `unsupported type "struct"`},
+	} {
+		res, err := isSet(test.src, test.key)
+		if test.isErr {
+			assert.EqualError(t, err, test.errStr)
+			continue
+		}
+
+		assert.NoError(t, err)
+		assert.Equal(t, test.res, res)
+	}
 }
 
 func (x *TstX) TstRp() string {