From e8a716b23a1ca78cf29460daacd4ba49bbc05ad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Sun, 9 Jun 2019 12:50:53 +0200 Subject: 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 --- tpl/collections/sort.go | 12 +++++++----- tpl/collections/sort_test.go | 45 ++++++++++++++++++++++++++------------------ 2 files changed, 34 insertions(+), 23 deletions(-) (limited to 'tpl/collections') diff --git a/tpl/collections/sort.go b/tpl/collections/sort.go index 206a19cb5..1ab4409b6 100644 --- a/tpl/collections/sort.go +++ b/tpl/collections/sort.go @@ -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 diff --git a/tpl/collections/sort_test.go b/tpl/collections/sort_test.go index 8db928f2d..f5f291f0b 100644 --- a/tpl/collections/sort_test.go +++ b/tpl/collections/sort_test.go @@ -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) - } - } else { - if err != nil { - t.Errorf("[%d] failed: %s", i, err) - continue + 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) } - 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) + + 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) + } } - } + }) + } } -- cgit v1.2.3