hugo_sites_build_test.go - hugo - [fork] hugo port for 9front
(HTM) git clone https://git.drkhsh.at/hugo.git
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
hugo_sites_build_test.go (9253B)
---
1 package hugolib
2
3 import (
4 "fmt"
5 "path/filepath"
6 "strings"
7 "testing"
8
9 qt "github.com/frankban/quicktest"
10 "github.com/gohugoio/hugo/common/loggers"
11 "github.com/gohugoio/hugo/htesting"
12 "github.com/gohugoio/hugo/resources/kinds"
13
14 "github.com/gohugoio/hugo/helpers"
15 "github.com/gohugoio/hugo/hugofs"
16 "github.com/spf13/afero"
17 )
18
19 func TestMultiSitesMainLangInRoot(t *testing.T) {
20 files := `
21 -- hugo.toml --
22 defaultContentLanguage = "fr"
23 defaultContentLanguageInSubdir = false
24 disableKinds = ["taxonomy", "term"]
25 [languages]
26 [languages.en]
27 weight = 1
28 [languages.fr]
29 weight = 2
30 -- content/sect/doc1.en.md --
31 ---
32 title: doc1 en
33 ---
34 -- content/sect/doc1.fr.md --
35 ---
36 title: doc1 fr
37 slug: doc1-fr
38 ---
39 -- layouts/_default/single.html --
40 Single: {{ .Title }}|{{ .Lang }}|{{ .RelPermalink }}|
41
42 `
43 b := Test(t, files)
44 b.AssertFileContent("public/sect/doc1-fr/index.html", "Single: doc1 fr|fr|/sect/doc1-fr/|")
45 b.AssertFileContent("public/en/sect/doc1/index.html", "Single: doc1 en|en|/en/sect/doc1/|")
46 }
47
48 func TestMultiSitesWithTwoLanguages(t *testing.T) {
49 t.Parallel()
50
51 c := qt.New(t)
52 b := newTestSitesBuilder(t).WithConfigFile("toml", `
53
54 defaultContentLanguage = "nn"
55
56 [languages]
57 [languages.nn]
58 languageName = "Nynorsk"
59 weight = 1
60 title = "Tittel på Nynorsk"
61 [languages.nn.params]
62 p1 = "p1nn"
63
64 [languages.en]
65 title = "Title in English"
66 languageName = "English"
67 weight = 2
68 [languages.en.params]
69 p1 = "p1en"
70 `)
71
72 b.CreateSites()
73 b.Build(BuildCfg{SkipRender: true})
74 sites := b.H.Sites
75
76 c.Assert(len(sites), qt.Equals, 2)
77
78 nnSite := sites[0]
79 nnHome := nnSite.getPageOldVersion(kinds.KindHome)
80 c.Assert(len(nnHome.AllTranslations()), qt.Equals, 2)
81 c.Assert(len(nnHome.Translations()), qt.Equals, 1)
82 c.Assert(nnHome.IsTranslated(), qt.Equals, true)
83
84 enHome := sites[1].getPageOldVersion(kinds.KindHome)
85
86 p1, err := enHome.Param("p1")
87 c.Assert(err, qt.IsNil)
88 c.Assert(p1, qt.Equals, "p1en")
89
90 p1, err = nnHome.Param("p1")
91 c.Assert(err, qt.IsNil)
92 c.Assert(p1, qt.Equals, "p1nn")
93 }
94
95 // https://github.com/gohugoio/hugo/issues/4706
96 func TestContentStressTest(t *testing.T) {
97 b := newTestSitesBuilder(t)
98
99 numPages := 500
100
101 contentTempl := `
102 ---
103 %s
104 title: %q
105 weight: %d
106 multioutput: %t
107 ---
108
109 # Header
110
111 CONTENT
112
113 The End.
114 `
115
116 contentTempl = strings.Replace(contentTempl, "CONTENT", strings.Repeat(`
117
118 ## Another header
119
120 Some text. Some more text.
121
122 `, 100), -1)
123
124 var content []string
125 defaultOutputs := `outputs: ["html", "json", "rss" ]`
126
127 for i := 1; i <= numPages; i++ {
128 outputs := defaultOutputs
129 multioutput := true
130 if i%3 == 0 {
131 outputs = `outputs: ["json"]`
132 multioutput = false
133 }
134 section := "s1"
135 if i%10 == 0 {
136 section = "s2"
137 }
138 content = append(content, []string{fmt.Sprintf("%s/page%d.md", section, i), fmt.Sprintf(contentTempl, outputs, fmt.Sprintf("Title %d", i), i, multioutput)}...)
139 }
140
141 content = append(content, []string{"_index.md", fmt.Sprintf(contentTempl, defaultOutputs, fmt.Sprintf("Home %d", 0), 0, true)}...)
142 content = append(content, []string{"s1/_index.md", fmt.Sprintf(contentTempl, defaultOutputs, fmt.Sprintf("S %d", 1), 1, true)}...)
143 content = append(content, []string{"s2/_index.md", fmt.Sprintf(contentTempl, defaultOutputs, fmt.Sprintf("S %d", 2), 2, true)}...)
144
145 b.WithSimpleConfigFile()
146 b.WithTemplates("layouts/_default/single.html", `Single: {{ .Content }}|RelPermalink: {{ .RelPermalink }}|Permalink: {{ .Permalink }}`)
147 b.WithTemplates("layouts/_default/myview.html", `View: {{ len .Content }}`)
148 b.WithTemplates("layouts/_default/single.json", `Single JSON: {{ .Content }}|RelPermalink: {{ .RelPermalink }}|Permalink: {{ .Permalink }}`)
149 b.WithTemplates("layouts/_default/list.html", `
150 Page: {{ .Paginator.PageNumber }}
151 P: {{ with .File }}{{ path.Join .Path }}{{ end }}
152 List: {{ len .Paginator.Pages }}|List Content: {{ len .Content }}
153 {{ $shuffled := where .Site.RegularPages "Params.multioutput" true | shuffle }}
154 {{ $first5 := $shuffled | first 5 }}
155 L1: {{ len .Site.RegularPages }} L2: {{ len $first5 }}
156 {{ range $i, $e := $first5 }}
157 Render {{ $i }}: {{ .Render "myview" }}
158 {{ end }}
159 END
160 `)
161
162 b.WithContent(content...)
163
164 b.CreateSites().Build(BuildCfg{})
165
166 contentMatchers := []string{"<h2 id=\"another-header\">Another header</h2>", "<h2 id=\"another-header-99\">Another header</h2>", "<p>The End.</p>"}
167
168 for i := 1; i <= numPages; i++ {
169 if i%3 != 0 {
170 section := "s1"
171 if i%10 == 0 {
172 section = "s2"
173 }
174 checkContent(b, fmt.Sprintf("public/%s/page%d/index.html", section, i), contentMatchers...)
175 }
176 }
177
178 for i := 1; i <= numPages; i++ {
179 section := "s1"
180 if i%10 == 0 {
181 section = "s2"
182 }
183 checkContent(b, fmt.Sprintf("public/%s/page%d/index.json", section, i), contentMatchers...)
184 }
185
186 checkContent(b, "public/s1/index.html", "P: s1/_index.md\nList: 10|List Content: 8132\n\n\nL1: 500 L2: 5\n\nRender 0: View: 8132\n\nRender 1: View: 8132\n\nRender 2: View: 8132\n\nRender 3: View: 8132\n\nRender 4: View: 8132\n\nEND\n")
187 checkContent(b, "public/s2/index.html", "P: s2/_index.md\nList: 10|List Content: 8132", "Render 4: View: 8132\n\nEND")
188 checkContent(b, "public/index.html", "P: _index.md\nList: 10|List Content: 8132", "4: View: 8132\n\nEND")
189
190 // Check paginated pages
191 for i := 2; i <= 9; i++ {
192 checkContent(b, fmt.Sprintf("public/page/%d/index.html", i), fmt.Sprintf("Page: %d", i), "Content: 8132\n\n\nL1: 500 L2: 5\n\nRender 0: View: 8132", "Render 4: View: 8132\n\nEND")
193 }
194 }
195
196 func checkContent(s *sitesBuilder, filename string, matches ...string) {
197 s.T.Helper()
198 content := readWorkingDir(s.T, s.Fs, filename)
199 for _, match := range matches {
200 if !strings.Contains(content, match) {
201 s.Fatalf("No match for\n%q\nin content for %s\n%q\nDiff:\n%s", match, filename, content, htesting.DiffStrings(content, match))
202 }
203 }
204 }
205
206 func TestTranslationsFromContentToNonContent(t *testing.T) {
207 b := newTestSitesBuilder(t)
208 b.WithConfigFile("toml", `
209
210 baseURL = "http://example.com/"
211
212 defaultContentLanguage = "en"
213
214 [languages]
215 [languages.en]
216 weight = 10
217 contentDir = "content/en"
218 [languages.nn]
219 weight = 20
220 contentDir = "content/nn"
221
222
223 `)
224
225 b.WithContent("en/mysection/_index.md", `
226 ---
227 Title: My Section
228 ---
229
230 `)
231
232 b.WithContent("en/_index.md", `
233 ---
234 Title: My Home
235 ---
236
237 `)
238
239 b.WithContent("en/categories/mycat/_index.md", `
240 ---
241 Title: My MyCat
242 ---
243
244 `)
245
246 b.WithContent("en/categories/_index.md", `
247 ---
248 Title: My categories
249 ---
250
251 `)
252
253 for _, lang := range []string{"en", "nn"} {
254 b.WithContent(lang+"/mysection/page.md", `
255 ---
256 Title: My Page
257 categories: ["mycat"]
258 ---
259
260 `)
261 }
262
263 b.Build(BuildCfg{})
264
265 for _, path := range []string{
266 "/",
267 "/mysection",
268 "/categories",
269 "/categories/mycat",
270 } {
271 t.Run(path, func(t *testing.T) {
272 c := qt.New(t)
273
274 s1, _ := b.H.Sites[0].getPage(nil, path)
275 s2, _ := b.H.Sites[1].getPage(nil, path)
276
277 c.Assert(s1, qt.Not(qt.IsNil))
278 c.Assert(s2, qt.Not(qt.IsNil))
279
280 c.Assert(len(s1.Translations()), qt.Equals, 1)
281 c.Assert(len(s2.Translations()), qt.Equals, 1)
282 c.Assert(s1.Translations()[0], qt.Equals, s2)
283 c.Assert(s2.Translations()[0], qt.Equals, s1)
284
285 m1 := s1.Translations().MergeByLanguage(s2.Translations())
286 m2 := s2.Translations().MergeByLanguage(s1.Translations())
287
288 c.Assert(len(m1), qt.Equals, 1)
289 c.Assert(len(m2), qt.Equals, 1)
290 })
291 }
292 }
293
294 func writeSource(t testing.TB, fs *hugofs.Fs, filename, content string) {
295 t.Helper()
296 writeToFs(t, fs.Source, filename, content)
297 }
298
299 func writeToFs(t testing.TB, fs afero.Fs, filename, content string) {
300 t.Helper()
301 if err := afero.WriteFile(fs, filepath.FromSlash(filename), []byte(content), 0o755); err != nil {
302 t.Fatalf("Failed to write file: %s", err)
303 }
304 }
305
306 func readWorkingDir(t testing.TB, fs *hugofs.Fs, filename string) string {
307 t.Helper()
308 return readFileFromFs(t, fs.WorkingDirReadOnly, filename)
309 }
310
311 func workingDirExists(fs *hugofs.Fs, filename string) bool {
312 b, err := helpers.Exists(filename, fs.WorkingDirReadOnly)
313 if err != nil {
314 panic(err)
315 }
316 return b
317 }
318
319 func readFileFromFs(t testing.TB, fs afero.Fs, filename string) string {
320 t.Helper()
321 filename = filepath.Clean(filename)
322 b, err := afero.ReadFile(fs, filename)
323 if err != nil {
324 // Print some debug info
325 hadSlash := strings.HasPrefix(filename, helpers.FilePathSeparator)
326 start := 0
327 if hadSlash {
328 start = 1
329 }
330 end := start + 1
331
332 parts := strings.Split(filename, helpers.FilePathSeparator)
333 if parts[start] == "work" {
334 end++
335 }
336
337 /*
338 root := filepath.Join(parts[start:end]...)
339 if hadSlash {
340 root = helpers.FilePathSeparator + root
341 }
342
343 helpers.PrintFs(fs, root, os.Stdout)
344 */
345
346 t.Fatalf("Failed to read file: %s", err)
347 }
348 return string(b)
349 }
350
351 const testPageTemplate = `---
352 title: "%s"
353 publishdate: "%s"
354 weight: %d
355 ---
356 # Doc %s
357 `
358
359 func newTestPage(title, date string, weight int) string {
360 return fmt.Sprintf(testPageTemplate, title, date, weight, title)
361 }
362
363 func TestRebuildOnAssetChange(t *testing.T) {
364 b := newTestSitesBuilder(t).Running().WithLogger(loggers.NewDefault())
365 b.WithTemplatesAdded("index.html", `
366 {{ (resources.Get "data.json").Content }}
367 `)
368 b.WithSourceFile("assets/data.json", "orig data")
369
370 b.Build(BuildCfg{})
371 b.AssertFileContent("public/index.html", `orig data`)
372
373 b.EditFiles("assets/data.json", "changed data")
374
375 b.Build(BuildCfg{})
376 b.AssertFileContent("public/index.html", `changed data`)
377 }