tpl/collections: Fix slice type handling in sort
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sun, 9 Jun 2019 10:50:53 +0000 (12:50 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 10 Jun 2019 06:32:44 +0000 (08:32 +0200)
The `sort` template func was producing a `[]page.Page` which did not work in `.Paginate`.

Fixes #6023

go.sum
hugolib/paginator_test.go
resources/page/pages.go
resources/page/pages_test.go
tpl/collections/sort.go
tpl/collections/sort_test.go

diff --git a/go.sum b/go.sum
index c0e2fcbdbdda55a0db42084d79fa438c7d7dfac8..4ecca85f132efba9ad2cb2e9041f5fe3aa42111f 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -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=
index d98ec30e9cc19eb52bc7ad7895902e423f80be1b..a97a59d04c853c5349807ed0cbe26169d6fa528a 100644 (file)
@@ -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"))
+}
index ccfecdf2bc0950ad748327608d2c5b43cd2e6d52..ac69a8079f27cf22cf7e109abdb6f0d22b4d9617 100644 (file)
@@ -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
index 5220a6d33006785b65ad2030d0b79af96d419962..c90d9f5d43e187986a961f76e73697d90a967fa3 100644 (file)
@@ -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)
+}
index 206a19cb5ea43e06407fe56ea09078d8142cd168..1ab4409b6bc0bec113fe1a558b65788f270c464b 100644 (file)
@@ -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
index 8db928f2d9bfa67f8a5ed2591a9c9b5ca0042ab2..f5f291f0b94a2bc6249b6e37d84d9ce534c7218b 100644 (file)
 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)
+                               }
                        }
-               }
+               })
+
        }
 }