mirror of
https://github.com/gohugoio/hugo.git
synced 2024-09-20 01:15:13 -04: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:
parent
3e6cb2cb77
commit
e8a716b23a
6 changed files with 72 additions and 23 deletions
2
go.sum
2
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/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 h1:5AzlPKvXBH4qBzmZ09Ua9Gipyruv6uApMcrNZdo96+Q=
|
||||||
github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=
|
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/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 h1:fiKJgB4JDUd43CApkmCeTSQlWjtTtABrU2qsgbuP0BI=
|
||||||
github.com/olekukonko/tablewriter v0.0.0-20180506121414-d4647c9c7a84/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
github.com/olekukonko/tablewriter v0.0.0-20180506121414-d4647c9c7a84/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
|
|
|
@ -15,6 +15,7 @@ package hugolib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -96,3 +97,11 @@ URL: {{ $pag.URL }}
|
||||||
"0: 1/1 true")
|
"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"))
|
||||||
|
}
|
||||||
|
|
|
@ -66,6 +66,12 @@ func ToPages(seq interface{}) (Pages, error) {
|
||||||
return v.Pages(), nil
|
return v.Pages(), nil
|
||||||
case PageGroup:
|
case PageGroup:
|
||||||
return v.Pages, nil
|
return v.Pages, nil
|
||||||
|
case []Page:
|
||||||
|
pages := make(Pages, len(v))
|
||||||
|
for i, vv := range v {
|
||||||
|
pages[i] = vv
|
||||||
|
}
|
||||||
|
return pages, nil
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
pages := make(Pages, len(v))
|
pages := make(Pages, len(v))
|
||||||
success := true
|
success := true
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
@ -31,21 +31,23 @@ func (ns *Namespace) Sort(seq interface{}, args ...interface{}) (interface{}, er
|
||||||
return nil, errors.New("sequence must be provided")
|
return nil, errors.New("sequence must be provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
seqv := reflect.ValueOf(seq)
|
seqv, isNil := indirect(reflect.ValueOf(seq))
|
||||||
seqv, isNil := indirect(seqv)
|
|
||||||
if isNil {
|
if isNil {
|
||||||
return nil, errors.New("can't iterate over a nil value")
|
return nil, errors.New("can't iterate over a nil value")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sliceType reflect.Type
|
||||||
switch seqv.Kind() {
|
switch seqv.Kind() {
|
||||||
case reflect.Array, reflect.Slice, reflect.Map:
|
case reflect.Array, reflect.Slice:
|
||||||
// ok
|
sliceType = seqv.Type()
|
||||||
|
case reflect.Map:
|
||||||
|
sliceType = reflect.SliceOf(seqv.Type().Elem())
|
||||||
default:
|
default:
|
||||||
return nil, errors.New("can't sort " + reflect.ValueOf(seq).Type().String())
|
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
|
// 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())
|
p.Pairs = make([]pair, seqv.Len())
|
||||||
|
|
||||||
var sortByField string
|
var sortByField string
|
||||||
|
|
|
@ -14,12 +14,15 @@
|
||||||
package collections
|
package collections
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/deps"
|
"github.com/gohugoio/hugo/deps"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type stringsSlice []string
|
||||||
|
|
||||||
func TestSort(t *testing.T) {
|
func TestSort(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -42,6 +45,9 @@ func TestSort(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{[]string{"class1", "class2", "class3"}, nil, "asc", []string{"class1", "class2", "class3"}},
|
{[]string{"class1", "class2", "class3"}, nil, "asc", []string{"class1", "class2", "class3"}},
|
||||||
{[]string{"class3", "class1", "class2"}, 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{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}},
|
{[]int{5, 4, 3, 1, 2}, nil, "asc", []int{1, 2, 3, 4, 5}},
|
||||||
// test sort key parameter is focibly set empty
|
// test sort key parameter is focibly set empty
|
||||||
|
@ -212,26 +218,29 @@ func TestSort(t *testing.T) {
|
||||||
},
|
},
|
||||||
{nil, nil, "asc", false},
|
{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 {
|
t.Run(fmt.Sprintf("test%d", i), func(t *testing.T) {
|
||||||
if err == nil {
|
var result interface{}
|
||||||
t.Errorf("[%d] Sort didn't return an expected error", i)
|
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 {
|
if b, ok := test.expect.(bool); ok && !b {
|
||||||
t.Errorf("[%d] failed: %s", i, err)
|
if err == nil {
|
||||||
continue
|
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue