Add list support in Scratch

This commit is contained in:
Bjørn Erik Pedersen 2016-03-06 15:44:17 +01:00
parent 435e996c4f
commit eaba04e82b
3 changed files with 49 additions and 5 deletions

View file

@ -21,7 +21,9 @@ weight: 80
* `SetInMap` takes a `key`, `mapKey` and `value` * `SetInMap` takes a `key`, `mapKey` and `value`
* `GetSortedMapValues` returns array of values from `key` sorted by `mapKey` * `GetSortedMapValues` returns array of values from `key` sorted by `mapKey`
`Set` and `SetInMap` can store values of any type. `Add` accepts values that support Go's `+` operator. `Set` and `SetInMap` can store values of any type.
For single values, `Add` accepts values that support Go's `+` operator. If the first `Add` for a key is an array or slice, the follwing adds will be appended to that list.
The scope of the backing data is global for the given `Node` or `Page`, and spans partial and shortcode includes. The scope of the backing data is global for the given `Node` or `Page`, and spans partial and shortcode includes.

View file

@ -15,6 +15,7 @@ package hugolib
import ( import (
"github.com/spf13/hugo/helpers" "github.com/spf13/hugo/helpers"
"reflect"
"sort" "sort"
) )
@ -23,17 +24,31 @@ type Scratch struct {
values map[string]interface{} values map[string]interface{}
} }
// Add will add (using the + operator) the addend to the existing addend (if found). // For single values, Add will add (using the + operator) the addend to the existing addend (if found).
// Supports numeric values and strings. // Supports numeric values and strings.
//
// If the first add for a key is an array or slice, then the next value(s) will be appended.
func (c *Scratch) Add(key string, newAddend interface{}) (string, error) { func (c *Scratch) Add(key string, newAddend interface{}) (string, error) {
var newVal interface{} var newVal interface{}
existingAddend, found := c.values[key] existingAddend, found := c.values[key]
if found { if found {
var err error var err error
addendV := reflect.ValueOf(existingAddend)
if addendV.Kind() == reflect.Slice || addendV.Kind() == reflect.Array {
nav := reflect.ValueOf(newAddend)
if nav.Kind() == reflect.Slice || nav.Kind() == reflect.Array {
newVal = reflect.AppendSlice(addendV, nav).Interface()
} else {
newVal = reflect.Append(addendV, nav).Interface()
}
} else {
newVal, err = helpers.DoArithmetic(existingAddend, newAddend, '+') newVal, err = helpers.DoArithmetic(existingAddend, newAddend, '+')
if err != nil { if err != nil {
return "", err return "", err
} }
}
} else { } else {
newVal = newAddend newVal = newAddend
} }

View file

@ -15,6 +15,7 @@ package hugolib
import ( import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"reflect"
"testing" "testing"
) )
@ -47,6 +48,32 @@ func TestScratchAdd(t *testing.T) {
} }
func TestScratchAddSlice(t *testing.T) {
scratch := newScratch()
_, err := scratch.Add("intSlice", []int{1, 2})
assert.Nil(t, err)
_, err = scratch.Add("intSlice", 3)
assert.Nil(t, err)
sl := scratch.Get("intSlice")
expected := []int{1, 2, 3}
if !reflect.DeepEqual(expected, sl) {
t.Errorf("Slice difference, go %q expected %q", sl, expected)
}
_, err = scratch.Add("intSlice", []int{4, 5})
sl = scratch.Get("intSlice")
expected = []int{1, 2, 3, 4, 5}
if !reflect.DeepEqual(expected, sl) {
t.Errorf("Slice difference, go %q expected %q", sl, expected)
}
}
func TestScratchSet(t *testing.T) { func TestScratchSet(t *testing.T) {
scratch := newScratch() scratch := newScratch()
scratch.Set("key", "val") scratch.Set("key", "val")