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