diff options
author | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2019-06-09 12:50:53 +0200 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2019-06-10 08:32:44 +0200 |
commit | e8a716b23a1ca78cf29460daacd4ba49bbc05ad1 (patch) | |
tree | a55a3ade6ca19306b3ebbae6cbafd2aefaa4c880 | |
parent | 3e6cb2cb77e16be5b6ddd4ae55d5fc6bfba2d226 (diff) |
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
-rw-r--r-- | go.sum | 2 | ||||
-rw-r--r-- | hugolib/paginator_test.go | 9 | ||||
-rw-r--r-- | resources/page/pages.go | 6 | ||||
-rw-r--r-- | resources/page/pages_test.go | 21 | ||||
-rw-r--r-- | tpl/collections/sort.go | 12 | ||||
-rw-r--r-- | tpl/collections/sort_test.go | 45 |
6 files changed, 72 insertions, 23 deletions
@@ -220,6 +220,8 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/nicksnyder/go-i18n v1.10.0 h1:5AzlPKvXBH4qBzmZ09Ua9Gipyruv6uApMcrNZdo96+Q= github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q= +github.com/niklasfasching/go-org v0.0.0-20190112190817-da99094e202f h1:XQqYaaEslPrQl81puWcHVAlt1l16dIQaWXYeEDbw9uI= +github.com/niklasfasching/go-org v0.0.0-20190112190817-da99094e202f/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20180506121414-d4647c9c7a84 h1:fiKJgB4JDUd43CApkmCeTSQlWjtTtABrU2qsgbuP0BI= github.com/olekukonko/tablewriter v0.0.0-20180506121414-d4647c9c7a84/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= diff --git a/hugolib/paginator_test.go b/hugolib/paginator_test.go index d98ec30e9..a97a59d04 100644 --- a/hugolib/paginator_test.go +++ b/hugolib/paginator_test.go @@ -15,6 +15,7 @@ package hugolib import ( "fmt" + "path/filepath" "testing" ) @@ -96,3 +97,11 @@ URL: {{ $pag.URL }} "0: 1/1 true") } + +// Issue 6023 +func TestPaginateWithSort(t *testing.T) { + b := newTestSitesBuilder(t).WithSimpleConfigFile() + b.WithTemplatesAdded("index.html", `{{ range (.Paginate (sort .Site.RegularPages ".File.Filename" "desc")).Pages }}|{{ .File.Filename }}{{ end }}`) + b.Build(BuildCfg{}).AssertFileContent("public/index.html", + filepath.FromSlash("|content/sect/doc1.nn.md|content/sect/doc1.nb.md|content/sect/doc1.fr.md|content/sect/doc1.en.md")) +} diff --git a/resources/page/pages.go b/resources/page/pages.go index ccfecdf2b..ac69a8079 100644 --- a/resources/page/pages.go +++ b/resources/page/pages.go @@ -66,6 +66,12 @@ func ToPages(seq interface{}) (Pages, error) { return v.Pages(), nil case PageGroup: return v.Pages, nil + case []Page: + pages := make(Pages, len(v)) + for i, vv := range v { + pages[i] = vv + } + return pages, nil case []interface{}: pages := make(Pages, len(v)) success := true diff --git a/resources/page/pages_test.go b/resources/page/pages_test.go index 5220a6d33..c90d9f5d4 100644 --- a/resources/page/pages_test.go +++ b/resources/page/pages_test.go @@ -53,3 +53,24 @@ func TestProbablyEq(t *testing.T) { }) } + +func TestToPages(t *testing.T) { + assert := require.New(t) + + p1, p2 := &testPage{title: "p1"}, &testPage{title: "p2"} + pages12 := Pages{p1, p2} + + mustToPages := func(in interface{}) Pages { + p, err := ToPages(in) + assert.NoError(err) + return p + } + + assert.Equal(Pages{}, mustToPages(nil)) + assert.Equal(pages12, mustToPages(pages12)) + assert.Equal(pages12, mustToPages([]Page{p1, p2})) + assert.Equal(pages12, mustToPages([]interface{}{p1, p2})) + + _, err := ToPages("not a page") + assert.Error(err) +} 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) + } } - } + }) + } } |