github.com/kovansky/hugo@v0.92.3-0.20220224232819-63076e4ff19f/resources/page/permalinks_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 "fmt" 18 "regexp" 19 "sync" 20 "testing" 21 "time" 22 23 qt "github.com/frankban/quicktest" 24 ) 25 26 // testdataPermalinks is used by a couple of tests; the expandsTo content is 27 // subject to the data in simplePageJSON. 28 var testdataPermalinks = []struct { 29 spec string 30 valid bool 31 expandsTo string 32 }{ 33 {":title", true, "spf13-vim-3.0-release-and-new-website"}, 34 {"/:year-:month-:title", true, "/2012-04-spf13-vim-3.0-release-and-new-website"}, 35 {"/:year/:yearday/:month/:monthname/:day/:weekday/:weekdayname/", true, "/2012/97/04/April/06/5/Friday/"}, // Dates 36 {"/:section/", true, "/blue/"}, // Section 37 {"/:title/", true, "/spf13-vim-3.0-release-and-new-website/"}, // Title 38 {"/:slug/", true, "/the-slug/"}, // Slug 39 {"/:filename/", true, "/test-page/"}, // Filename 40 {"/:06-:1-:2-:Monday", true, "/12-4-6-Friday"}, // Dates with Go formatting 41 {"/:2006_01_02_15_04_05.000", true, "/2012_04_06_03_01_59.000"}, // Complicated custom date format 42 {"/:sections/", true, "/a/b/c/"}, // Sections 43 {"/:sections[last]/", true, "/c/"}, // Sections 44 45 // Failures 46 {"/blog/:fred", false, ""}, 47 {"/:year//:title", false, ""}, 48 {"/:TITLE", false, ""}, // case is not normalized 49 {"/:2017", false, ""}, // invalid date format 50 {"/:2006-01-02", false, ""}, // valid date format but invalid attribute name 51 } 52 53 func TestPermalinkExpansion(t *testing.T) { 54 t.Parallel() 55 56 c := qt.New(t) 57 58 page := newTestPageWithFile("/test-page/index.md") 59 page.title = "Spf13 Vim 3.0 Release and new website" 60 d, _ := time.Parse("2006-01-02 15:04:05", "2012-04-06 03:01:59") 61 page.date = d 62 page.section = "blue" 63 page.slug = "The Slug" 64 65 for _, item := range testdataPermalinks { 66 if !item.valid { 67 continue 68 } 69 70 specNameCleaner := regexp.MustCompile(`[\:\/\[\]]`) 71 name := specNameCleaner.ReplaceAllString(item.spec, "") 72 73 c.Run(name, func(c *qt.C) { 74 75 permalinksConfig := map[string]string{ 76 "posts": item.spec, 77 } 78 79 ps := newTestPathSpec() 80 ps.Cfg.Set("permalinks", permalinksConfig) 81 82 expander, err := NewPermalinkExpander(ps) 83 c.Assert(err, qt.IsNil) 84 85 expanded, err := expander.Expand("posts", page) 86 c.Assert(err, qt.IsNil) 87 c.Assert(expanded, qt.Equals, item.expandsTo) 88 }) 89 90 } 91 } 92 93 func TestPermalinkExpansionMultiSection(t *testing.T) { 94 t.Parallel() 95 96 c := qt.New(t) 97 98 page := newTestPage() 99 page.title = "Page Title" 100 d, _ := time.Parse("2006-01-02", "2012-04-06") 101 page.date = d 102 page.section = "blue" 103 page.slug = "The Slug" 104 105 permalinksConfig := map[string]string{ 106 "posts": "/:slug", 107 "blog": "/:section/:year", 108 } 109 110 ps := newTestPathSpec() 111 ps.Cfg.Set("permalinks", permalinksConfig) 112 113 expander, err := NewPermalinkExpander(ps) 114 c.Assert(err, qt.IsNil) 115 116 expanded, err := expander.Expand("posts", page) 117 c.Assert(err, qt.IsNil) 118 c.Assert(expanded, qt.Equals, "/the-slug") 119 120 expanded, err = expander.Expand("blog", page) 121 c.Assert(err, qt.IsNil) 122 c.Assert(expanded, qt.Equals, "/blue/2012") 123 } 124 125 func TestPermalinkExpansionConcurrent(t *testing.T) { 126 t.Parallel() 127 128 c := qt.New(t) 129 130 permalinksConfig := map[string]string{ 131 "posts": "/:slug/", 132 } 133 134 ps := newTestPathSpec() 135 ps.Cfg.Set("permalinks", permalinksConfig) 136 137 expander, err := NewPermalinkExpander(ps) 138 c.Assert(err, qt.IsNil) 139 140 var wg sync.WaitGroup 141 142 for i := 1; i < 20; i++ { 143 wg.Add(1) 144 go func(i int) { 145 defer wg.Done() 146 page := newTestPage() 147 for j := 1; j < 20; j++ { 148 page.slug = fmt.Sprintf("slug%d", i+j) 149 expanded, err := expander.Expand("posts", page) 150 c.Assert(err, qt.IsNil) 151 c.Assert(expanded, qt.Equals, fmt.Sprintf("/%s/", page.slug)) 152 } 153 }(i) 154 } 155 156 wg.Wait() 157 } 158 159 func TestPermalinkExpansionSliceSyntax(t *testing.T) { 160 t.Parallel() 161 162 c := qt.New(t) 163 exp, _ := NewPermalinkExpander(newTestPathSpec()) 164 slice := []string{"a", "b", "c", "d"} 165 fn := func(s string) []string { 166 return exp.toSliceFunc(s)(slice) 167 } 168 169 c.Run("Basic", func(c *qt.C) { 170 c.Assert(fn("[1:3]"), qt.DeepEquals, []string{"b", "c"}) 171 c.Assert(fn("[1:]"), qt.DeepEquals, []string{"b", "c", "d"}) 172 c.Assert(fn("[:2]"), qt.DeepEquals, []string{"a", "b"}) 173 c.Assert(fn("[0:2]"), qt.DeepEquals, []string{"a", "b"}) 174 c.Assert(fn("[:]"), qt.DeepEquals, []string{"a", "b", "c", "d"}) 175 c.Assert(fn(""), qt.DeepEquals, []string{"a", "b", "c", "d"}) 176 c.Assert(fn("[last]"), qt.DeepEquals, []string{"d"}) 177 c.Assert(fn("[:last]"), qt.DeepEquals, []string{"a", "b", "c"}) 178 179 }) 180 181 c.Run("Out of bounds", func(c *qt.C) { 182 c.Assert(fn("[1:5]"), qt.DeepEquals, []string{"b", "c", "d"}) 183 c.Assert(fn("[-1:5]"), qt.DeepEquals, []string{"a", "b", "c", "d"}) 184 c.Assert(fn("[5:]"), qt.DeepEquals, []string{}) 185 c.Assert(fn("[5:]"), qt.DeepEquals, []string{}) 186 c.Assert(fn("[5:32]"), qt.DeepEquals, []string{}) 187 c.Assert(exp.toSliceFunc("[:1]")(nil), qt.DeepEquals, []string(nil)) 188 c.Assert(exp.toSliceFunc("[:1]")([]string{}), qt.DeepEquals, []string(nil)) 189 190 // These all return nil 191 c.Assert(fn("[]"), qt.IsNil) 192 c.Assert(fn("[1:}"), qt.IsNil) 193 c.Assert(fn("foo"), qt.IsNil) 194 195 }) 196 197 } 198 199 func BenchmarkPermalinkExpand(b *testing.B) { 200 page := newTestPage() 201 page.title = "Hugo Rocks" 202 d, _ := time.Parse("2006-01-02", "2019-02-28") 203 page.date = d 204 205 permalinksConfig := map[string]string{ 206 "posts": "/:year-:month-:title", 207 } 208 209 ps := newTestPathSpec() 210 ps.Cfg.Set("permalinks", permalinksConfig) 211 212 expander, err := NewPermalinkExpander(ps) 213 if err != nil { 214 b.Fatal(err) 215 } 216 217 b.ResetTimer() 218 for i := 0; i < b.N; i++ { 219 s, err := expander.Expand("posts", page) 220 if err != nil { 221 b.Fatal(err) 222 } 223 if s != "/2019-02-hugo-rocks" { 224 b.Fatal(s) 225 } 226 227 } 228 }