mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-29 22:29:56 +02:00
tpl/collections: Fix slice type handling in sort
The `sort` template func was producing a `[]page.Page` which did not work in `.Paginate`. Fixes #6023
This commit is contained in:
@@ -31,21 +31,23 @@ func (ns *Namespace) Sort(seq interface{}, args ...interface{}) (interface{}, er
|
||||
return nil, errors.New("sequence must be provided")
|
||||
}
|
||||
|
||||
seqv := reflect.ValueOf(seq)
|
||||
seqv, isNil := indirect(seqv)
|
||||
seqv, isNil := indirect(reflect.ValueOf(seq))
|
||||
if isNil {
|
||||
return nil, errors.New("can't iterate over a nil value")
|
||||
}
|
||||
|
||||
var sliceType reflect.Type
|
||||
switch seqv.Kind() {
|
||||
case reflect.Array, reflect.Slice, reflect.Map:
|
||||
// ok
|
||||
case reflect.Array, reflect.Slice:
|
||||
sliceType = seqv.Type()
|
||||
case reflect.Map:
|
||||
sliceType = reflect.SliceOf(seqv.Type().Elem())
|
||||
default:
|
||||
return nil, errors.New("can't sort " + reflect.ValueOf(seq).Type().String())
|
||||
}
|
||||
|
||||
// Create a list of pairs that will be used to do the sort
|
||||
p := pairList{SortAsc: true, SliceType: reflect.SliceOf(seqv.Type().Elem())}
|
||||
p := pairList{SortAsc: true, SliceType: sliceType}
|
||||
p.Pairs = make([]pair, seqv.Len())
|
||||
|
||||
var sortByField string
|
||||
|
@@ -14,12 +14,15 @@
|
||||
package collections
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/gohugoio/hugo/deps"
|
||||
)
|
||||
|
||||
type stringsSlice []string
|
||||
|
||||
func TestSort(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -42,6 +45,9 @@ func TestSort(t *testing.T) {
|
||||
}{
|
||||
{[]string{"class1", "class2", "class3"}, nil, "asc", []string{"class1", "class2", "class3"}},
|
||||
{[]string{"class3", "class1", "class2"}, nil, "asc", []string{"class1", "class2", "class3"}},
|
||||
// Issue 6023
|
||||
{stringsSlice{"class3", "class1", "class2"}, nil, "asc", stringsSlice{"class1", "class2", "class3"}},
|
||||
|
||||
{[]int{1, 2, 3, 4, 5}, nil, "asc", []int{1, 2, 3, 4, 5}},
|
||||
{[]int{5, 4, 3, 1, 2}, nil, "asc", []int{1, 2, 3, 4, 5}},
|
||||
// test sort key parameter is focibly set empty
|
||||
@@ -212,26 +218,29 @@ func TestSort(t *testing.T) {
|
||||
},
|
||||
{nil, nil, "asc", false},
|
||||
} {
|
||||
var result interface{}
|
||||
var err error
|
||||
if test.sortByField == nil {
|
||||
result, err = ns.Sort(test.seq)
|
||||
} else {
|
||||
result, err = ns.Sort(test.seq, test.sortByField, test.sortAsc)
|
||||
}
|
||||
|
||||
if b, ok := test.expect.(bool); ok && !b {
|
||||
if err == nil {
|
||||
t.Errorf("[%d] Sort didn't return an expected error", i)
|
||||
t.Run(fmt.Sprintf("test%d", i), func(t *testing.T) {
|
||||
var result interface{}
|
||||
var err error
|
||||
if test.sortByField == nil {
|
||||
result, err = ns.Sort(test.seq)
|
||||
} else {
|
||||
result, err = ns.Sort(test.seq, test.sortByField, test.sortAsc)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("[%d] failed: %s", i, err)
|
||||
continue
|
||||
|
||||
if b, ok := test.expect.(bool); ok && !b {
|
||||
if err == nil {
|
||||
t.Fatal("Sort didn't return an expected error")
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Fatalf("failed: %s", err)
|
||||
}
|
||||
if !reflect.DeepEqual(result, test.expect) {
|
||||
t.Fatalf("Sort called on sequence: %#v | sortByField: `%v` | got\n%#v but expected\n%#v", test.seq, test.sortByField, result, test.expect)
|
||||
}
|
||||
}
|
||||
if !reflect.DeepEqual(result, test.expect) {
|
||||
t.Errorf("[%d] Sort called on sequence: %v | sortByField: `%v` | got %v but expected %v", i, test.seq, test.sortByField, result, test.expect)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user