hugo

Fork of github.com/gohugoio/hugo with reverse pagination support

git clone git://git.shimmy1996.com/hugo.git

pages_sort_test.go (7833B)

    1 // Copyright 2019 The Hugo Authors. All rights reserved.
    2 //
    3 // Licensed under the Apache License, Version 2.0 (the "License");
    4 // you may not use this file except in compliance with the License.
    5 // You may obtain a copy of the License at
    6 // http://www.apache.org/licenses/LICENSE-2.0
    7 //
    8 // Unless required by applicable law or agreed to in writing, software
    9 // distributed under the License is distributed on an "AS IS" BASIS,
   10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   11 // See the License for the specific language governing permissions and
   12 // limitations under the License.
   13 
   14 package page
   15 
   16 import (
   17 	"fmt"
   18 	"testing"
   19 	"time"
   20 
   21 	"github.com/gohugoio/hugo/resources/resource"
   22 	"github.com/google/go-cmp/cmp"
   23 
   24 	qt "github.com/frankban/quicktest"
   25 )
   26 
   27 var eq = qt.CmpEquals(
   28 	cmp.Comparer(func(p1, p2 testPage) bool {
   29 		return p1.path == p2.path && p1.weight == p2.weight
   30 	}),
   31 )
   32 
   33 func TestDefaultSort(t *testing.T) {
   34 	t.Parallel()
   35 	c := qt.New(t)
   36 	d1 := time.Now()
   37 	d2 := d1.Add(-1 * time.Hour)
   38 	d3 := d1.Add(-2 * time.Hour)
   39 	d4 := d1.Add(-3 * time.Hour)
   40 
   41 	p := createSortTestPages(4)
   42 
   43 	// first by weight
   44 	setSortVals([4]time.Time{d1, d2, d3, d4}, [4]string{"b", "a", "c", "d"}, [4]int{4, 3, 2, 1}, p)
   45 	SortByDefault(p)
   46 
   47 	c.Assert(p[0].Weight(), qt.Equals, 1)
   48 
   49 	// Consider zero weight, issue #2673
   50 	setSortVals([4]time.Time{d1, d2, d3, d4}, [4]string{"b", "a", "d", "c"}, [4]int{0, 0, 0, 1}, p)
   51 	SortByDefault(p)
   52 
   53 	c.Assert(p[0].Weight(), qt.Equals, 1)
   54 
   55 	// next by date
   56 	setSortVals([4]time.Time{d3, d4, d1, d2}, [4]string{"a", "b", "c", "d"}, [4]int{1, 1, 1, 1}, p)
   57 	SortByDefault(p)
   58 	c.Assert(p[0].Date(), qt.Equals, d1)
   59 
   60 	// finally by link title
   61 	setSortVals([4]time.Time{d3, d3, d3, d3}, [4]string{"b", "c", "a", "d"}, [4]int{1, 1, 1, 1}, p)
   62 	SortByDefault(p)
   63 	c.Assert(p[0].LinkTitle(), qt.Equals, "al")
   64 	c.Assert(p[1].LinkTitle(), qt.Equals, "bl")
   65 	c.Assert(p[2].LinkTitle(), qt.Equals, "cl")
   66 }
   67 
   68 // https://github.com/gohugoio/hugo/issues/4953
   69 func TestSortByLinkTitle(t *testing.T) {
   70 	t.Parallel()
   71 	c := qt.New(t)
   72 	pages := createSortTestPages(6)
   73 
   74 	for i, p := range pages {
   75 		pp := p.(*testPage)
   76 		if i < 5 {
   77 			pp.title = fmt.Sprintf("title%d", i)
   78 		}
   79 
   80 		if i > 2 {
   81 			pp.linkTitle = fmt.Sprintf("linkTitle%d", i)
   82 		}
   83 
   84 	}
   85 
   86 	pages.shuffle()
   87 
   88 	bylt := pages.ByLinkTitle()
   89 
   90 	for i, p := range bylt {
   91 		if i < 3 {
   92 			c.Assert(p.LinkTitle(), qt.Equals, fmt.Sprintf("linkTitle%d", i+3))
   93 		} else {
   94 			c.Assert(p.LinkTitle(), qt.Equals, fmt.Sprintf("title%d", i-3))
   95 		}
   96 	}
   97 }
   98 
   99 func TestSortByN(t *testing.T) {
  100 	t.Parallel()
  101 	d1 := time.Now()
  102 	d2 := d1.Add(-2 * time.Hour)
  103 	d3 := d1.Add(-10 * time.Hour)
  104 	d4 := d1.Add(-20 * time.Hour)
  105 
  106 	p := createSortTestPages(4)
  107 
  108 	for i, this := range []struct {
  109 		sortFunc   func(p Pages) Pages
  110 		assertFunc func(p Pages) bool
  111 	}{
  112 		{(Pages).ByWeight, func(p Pages) bool { return p[0].Weight() == 1 }},
  113 		{(Pages).ByTitle, func(p Pages) bool { return p[0].Title() == "ab" }},
  114 		{(Pages).ByLinkTitle, func(p Pages) bool { return p[0].LinkTitle() == "abl" }},
  115 		{(Pages).ByDate, func(p Pages) bool { return p[0].Date() == d4 }},
  116 		{(Pages).ByPublishDate, func(p Pages) bool { return p[0].PublishDate() == d4 }},
  117 		{(Pages).ByExpiryDate, func(p Pages) bool { return p[0].ExpiryDate() == d4 }},
  118 		{(Pages).ByLastmod, func(p Pages) bool { return p[1].Lastmod() == d3 }},
  119 		{(Pages).ByLength, func(p Pages) bool { return p[0].(resource.LengthProvider).Len() == len(p[0].(*testPage).content) }},
  120 	} {
  121 		setSortVals([4]time.Time{d1, d2, d3, d4}, [4]string{"b", "ab", "cde", "fg"}, [4]int{0, 3, 2, 1}, p)
  122 
  123 		sorted := this.sortFunc(p)
  124 		if !this.assertFunc(sorted) {
  125 			t.Errorf("[%d] sort error", i)
  126 		}
  127 	}
  128 }
  129 
  130 func TestLimit(t *testing.T) {
  131 	t.Parallel()
  132 	c := qt.New(t)
  133 	p := createSortTestPages(10)
  134 	firstFive := p.Limit(5)
  135 	c.Assert(len(firstFive), qt.Equals, 5)
  136 	for i := 0; i < 5; i++ {
  137 		c.Assert(firstFive[i], qt.Equals, p[i])
  138 	}
  139 	c.Assert(p.Limit(10), eq, p)
  140 	c.Assert(p.Limit(11), eq, p)
  141 }
  142 
  143 func TestPageSortReverse(t *testing.T) {
  144 	t.Parallel()
  145 	c := qt.New(t)
  146 	p1 := createSortTestPages(10)
  147 	c.Assert(p1[0].(*testPage).fuzzyWordCount, qt.Equals, 0)
  148 	c.Assert(p1[9].(*testPage).fuzzyWordCount, qt.Equals, 9)
  149 	p2 := p1.Reverse()
  150 	c.Assert(p2[0].(*testPage).fuzzyWordCount, qt.Equals, 9)
  151 	c.Assert(p2[9].(*testPage).fuzzyWordCount, qt.Equals, 0)
  152 	// cached
  153 	c.Assert(pagesEqual(p2, p1.Reverse()), qt.Equals, true)
  154 }
  155 
  156 func TestPageSortByParam(t *testing.T) {
  157 	t.Parallel()
  158 	c := qt.New(t)
  159 	var k any = "arbitrarily.nested"
  160 
  161 	unsorted := createSortTestPages(10)
  162 	delete(unsorted[9].Params(), "arbitrarily")
  163 
  164 	firstSetValue, _ := unsorted[0].Param(k)
  165 	secondSetValue, _ := unsorted[1].Param(k)
  166 	lastSetValue, _ := unsorted[8].Param(k)
  167 	unsetValue, _ := unsorted[9].Param(k)
  168 
  169 	c.Assert(firstSetValue, qt.Equals, "xyz100")
  170 	c.Assert(secondSetValue, qt.Equals, "xyz99")
  171 	c.Assert(lastSetValue, qt.Equals, "xyz92")
  172 	c.Assert(unsetValue, qt.Equals, nil)
  173 
  174 	sorted := unsorted.ByParam("arbitrarily.nested")
  175 	firstSetSortedValue, _ := sorted[0].Param(k)
  176 	secondSetSortedValue, _ := sorted[1].Param(k)
  177 	lastSetSortedValue, _ := sorted[8].Param(k)
  178 	unsetSortedValue, _ := sorted[9].Param(k)
  179 
  180 	c.Assert(firstSetSortedValue, qt.Equals, firstSetValue)
  181 	c.Assert(lastSetSortedValue, qt.Equals, secondSetValue)
  182 	c.Assert(secondSetSortedValue, qt.Equals, lastSetValue)
  183 	c.Assert(unsetSortedValue, qt.Equals, unsetValue)
  184 }
  185 
  186 func TestPageSortByParamNumeric(t *testing.T) {
  187 	t.Parallel()
  188 	c := qt.New(t)
  189 
  190 	var k any = "arbitrarily.nested"
  191 
  192 	n := 10
  193 	unsorted := createSortTestPages(n)
  194 	for i := 0; i < n; i++ {
  195 		v := 100 - i
  196 		if i%2 == 0 {
  197 			v = 100.0 - i
  198 		}
  199 
  200 		unsorted[i].(*testPage).params = map[string]any{
  201 			"arbitrarily": map[string]any{
  202 				"nested": v,
  203 			},
  204 		}
  205 	}
  206 	delete(unsorted[9].Params(), "arbitrarily")
  207 
  208 	firstSetValue, _ := unsorted[0].Param(k)
  209 	secondSetValue, _ := unsorted[1].Param(k)
  210 	lastSetValue, _ := unsorted[8].Param(k)
  211 	unsetValue, _ := unsorted[9].Param(k)
  212 
  213 	c.Assert(firstSetValue, qt.Equals, 100)
  214 	c.Assert(secondSetValue, qt.Equals, 99)
  215 	c.Assert(lastSetValue, qt.Equals, 92)
  216 	c.Assert(unsetValue, qt.Equals, nil)
  217 
  218 	sorted := unsorted.ByParam("arbitrarily.nested")
  219 	firstSetSortedValue, _ := sorted[0].Param(k)
  220 	secondSetSortedValue, _ := sorted[1].Param(k)
  221 	lastSetSortedValue, _ := sorted[8].Param(k)
  222 	unsetSortedValue, _ := sorted[9].Param(k)
  223 
  224 	c.Assert(firstSetSortedValue, qt.Equals, 92)
  225 	c.Assert(secondSetSortedValue, qt.Equals, 93)
  226 	c.Assert(lastSetSortedValue, qt.Equals, 100)
  227 	c.Assert(unsetSortedValue, qt.Equals, unsetValue)
  228 }
  229 
  230 func BenchmarkSortByWeightAndReverse(b *testing.B) {
  231 	p := createSortTestPages(300)
  232 
  233 	b.ResetTimer()
  234 	for i := 0; i < b.N; i++ {
  235 		p = p.ByWeight().Reverse()
  236 	}
  237 }
  238 
  239 func setSortVals(dates [4]time.Time, titles [4]string, weights [4]int, pages Pages) {
  240 	for i := range dates {
  241 		this := pages[i].(*testPage)
  242 		other := pages[len(dates)-1-i].(*testPage)
  243 
  244 		this.date = dates[i]
  245 		this.lastMod = dates[i]
  246 		this.weight = weights[i]
  247 		this.title = titles[i]
  248 		// make sure we compare apples and ... apples ...
  249 		other.linkTitle = this.Title() + "l"
  250 		other.pubDate = dates[i]
  251 		other.expiryDate = dates[i]
  252 		other.content = titles[i] + "_content"
  253 	}
  254 	lastLastMod := pages[2].Lastmod()
  255 	pages[2].(*testPage).lastMod = pages[1].Lastmod()
  256 	pages[1].(*testPage).lastMod = lastLastMod
  257 
  258 	for _, p := range pages {
  259 		p.(*testPage).content = ""
  260 	}
  261 }
  262 
  263 func createSortTestPages(num int) Pages {
  264 	pages := make(Pages, num)
  265 
  266 	for i := 0; i < num; i++ {
  267 		p := newTestPage()
  268 		p.path = fmt.Sprintf("/x/y/p%d.md", i)
  269 		p.title = fmt.Sprintf("Title %d", i%(num+1/2))
  270 		p.params = map[string]any{
  271 			"arbitrarily": map[string]any{
  272 				"nested": ("xyz" + fmt.Sprintf("%v", 100-i)),
  273 			},
  274 		}
  275 
  276 		w := 5
  277 
  278 		if i%2 == 0 {
  279 			w = 10
  280 		}
  281 		p.fuzzyWordCount = i
  282 		p.weight = w
  283 		p.description = "initial"
  284 
  285 		pages[i] = p
  286 	}
  287 
  288 	return pages
  289 }