templatestore_integration_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
       ---
       templatestore_integration_test.go (37291B)
       ---
            1 package tplimpl_test
            2 
            3 import (
            4         "context"
            5         "io"
            6         "strings"
            7         "testing"
            8 
            9         qt "github.com/frankban/quicktest"
           10         "github.com/gohugoio/hugo/hugolib"
           11         "github.com/gohugoio/hugo/resources/kinds"
           12         "github.com/gohugoio/hugo/resources/page"
           13         "github.com/gohugoio/hugo/tpl/tplimpl"
           14 )
           15 
           16 // Old as in before Hugo v0.146.0.
           17 func TestLayoutsOldSetup(t *testing.T) {
           18         t.Parallel()
           19 
           20         files := `
           21 -- hugo.toml --
           22 defaultContentLanguage = "en"
           23 defaultContentLanguageInSubdir = true
           24 [languages]
           25 [languages.en]
           26 title = "Title in English"
           27 weight = 1
           28 [languages.nn]
           29 title = "Tittel på nynorsk"
           30 weight = 2
           31 -- layouts/index.html --
           32 Home.
           33 {{ template "_internal/twitter_cards.html" . }}
           34 -- layouts/_default/single.html --
           35 Single.
           36 -- layouts/_default/single.nn.html --
           37 Single NN.
           38 -- layouts/_default/list.html --
           39 List HTML.
           40 -- layouts/docs/list-baseof.html --
           41 Docs Baseof List HTML.
           42 {{ block "main" . }}Docs Baseof List HTML main block.{{ end }}
           43 -- layouts/docs/list.section.html --
           44 {{ define "main" }}
           45 Docs List HTML.
           46 {{ end }}
           47 -- layouts/_default/list.json --
           48 List JSON.
           49 -- layouts/_default/list.rss.xml --
           50 List RSS.
           51 -- layouts/_default/list.nn.rss.xml --
           52 List NN RSS.
           53 -- layouts/_default/baseof.html --
           54 Base.
           55 -- layouts/partials/mypartial.html --
           56 Partial.
           57 -- layouts/shortcodes/myshortcode.html --
           58 Shortcode.
           59 -- content/docs/p1.md --
           60 ---
           61 title: "P1"
           62 ---
           63 
           64         `
           65 
           66         b := hugolib.Test(t, files)
           67 
           68         //        b.DebugPrint("", tplimpl.CategoryBaseof)
           69 
           70         b.AssertFileContent("public/en/docs/index.html", "Docs Baseof List HTML.\n\nDocs List HTML.")
           71 }
           72 
           73 func TestLayoutsOldSetupBaseofPrefix(t *testing.T) {
           74         t.Parallel()
           75 
           76         files := `
           77 -- hugo.toml --
           78 -- layouts/_default/layout1-baseof.html --
           79 Baseof layout1. {{ block "main" . }}{{ end }}
           80 -- layouts/_default/layout2-baseof.html --
           81 Baseof layout2. {{ block "main" . }}{{ end }}
           82 -- layouts/_default/layout1.html --
           83 {{ define "main" }}Layout1. {{ .Title }}{{ end }}
           84 -- layouts/_default/layout2.html --
           85 {{ define "main" }}Layout2. {{ .Title }}{{ end }}
           86 -- content/p1.md --
           87 ---
           88 title: "P1"
           89 layout: "layout1"
           90 ---
           91 -- content/p2.md --
           92 ---
           93 title: "P2"
           94 layout: "layout2"
           95 ---
           96 `
           97 
           98         b := hugolib.Test(t, files)
           99 
          100         b.AssertFileContent("public/p1/index.html", "Baseof layout1. Layout1. P1")
          101         b.AssertFileContent("public/p2/index.html", "Baseof layout2. Layout2. P2")
          102 }
          103 
          104 func TestLayoutsOldSetupTaxonomyAndTerm(t *testing.T) {
          105         t.Parallel()
          106 
          107         files := `
          108 -- hugo.toml --
          109 [taxonomies]
          110 cat = 'cats'
          111 dog = 'dogs'
          112 # Templates for term taxonomy, old setup.
          113 -- layouts/dogs/terms.html --
          114 Dogs Terms. Most specific taxonomy template.
          115 -- layouts/taxonomy/terms.html --
          116 Taxonomy Terms. Down the list.
          117 # Templates for term term, old setup.
          118 -- layouts/dogs/term.html --
          119 Dogs Term. Most specific term template.
          120 -- layouts/term/term.html --
          121 Term Term. Down the list.
          122 -- layouts/dogs/max/list.html --
          123 max: {{ .Title }}
          124 -- layouts/_default/list.html --
          125 Default list.
          126 -- layouts/_default/single.html --
          127 Default single.
          128 -- content/p1.md --
          129 ---
          130 title: "P1"
          131 dogs: ["luna", "daisy", "max"]
          132 ---
          133 
          134 `
          135         b := hugolib.Test(t, files, hugolib.TestOptWarn())
          136 
          137         b.AssertLogContains("! WARN")
          138 
          139         b.AssertFileContent("public/dogs/index.html", "Dogs Terms. Most specific taxonomy template.")
          140         b.AssertFileContent("public/dogs/luna/index.html", "Dogs Term. Most specific term template.")
          141         b.AssertFileContent("public/dogs/max/index.html", "max: Max") // layouts/dogs/max/list.html wins over layouts/term/term.html because of distance.
          142 }
          143 
          144 func TestLayoutsOldSetupCustomRSS(t *testing.T) {
          145         t.Parallel()
          146 
          147         files := `
          148 -- hugo.toml --
          149 disableKinds = ["taxonomy", "term", "page"]
          150 [outputs]
          151 home = ["rss"]
          152 -- layouts/_default/list.rss.xml --
          153 List RSS.
          154 `
          155         b := hugolib.Test(t, files)
          156         b.AssertFileContent("public/index.xml", "List RSS.")
          157 }
          158 
          159 var newSetupTestSites = `
          160 -- hugo.toml --
          161 defaultContentLanguage = "en"
          162 defaultContentLanguageInSubdir = true
          163 [languages]
          164 [languages.en]
          165 title = "Title in English"
          166 weight = 1
          167 [languages.nn]
          168 title = "Tittel på nynorsk"
          169 weight = 2
          170 [languages.fr]
          171 title = "Titre en français"
          172 weight = 3
          173 
          174 [outputs]
          175 home     = ["html", "rss", "redir"]
          176 
          177 [outputFormats]
          178 [outputFormats.redir]
          179 mediatype   = "text/plain"
          180 baseName    = "_redirects"
          181 isPlainText = true
          182 -- layouts/404.html --
          183 {{ define "main" }}
          184 404.
          185 {{ end }}
          186 -- layouts/home.html --
          187 {{ define "main" }}
          188 Home: {{ .Title }}|{{ .Content }}|
          189 Inline Partial: {{ partial "my-inline-partial.html" . }}
          190 {{ end }}
          191 {{ define "hero" }}
          192 Home hero.
          193 {{ end }}
          194 {{ define "partials/my-inline-partial.html" }}
          195 {{ $value := 32 }}
          196 {{ return $value }}
          197 {{ end }}
          198 -- layouts/index.redir --
          199 Redir.
          200 -- layouts/single.html --
          201 {{ define "main" }}
          202 Single needs base.
          203 {{ end }}
          204 -- layouts/foo/bar/single.html --
          205 {{ define "main" }}
          206 Single sub path.
          207 {{ end }}
          208 -- layouts/_markup/render-codeblock.html --
          209 Render codeblock.
          210 -- layouts/_markup/render-blockquote.html --
          211 Render blockquote.
          212 -- layouts/_markup/render-codeblock-go.html --
          213  Render codeblock go.
          214 -- layouts/_markup/render-link.html --
          215 Link: {{ .Destination | safeURL }}
          216 -- layouts/foo/baseof.html --
          217 Base sub path.{{ block "main" . }}{{ end }}
          218 -- layouts/foo/bar/baseof.page.html --
          219 Base sub path.{{ block "main" . }}{{ end }}
          220 -- layouts/list.html --
          221 {{ define "main" }}
          222 List needs base.
          223 {{ end }}
          224 -- layouts/section.html --
          225 Section.
          226 -- layouts/mysectionlayout.section.fr.amp.html --
          227 Section with layout.
          228 -- layouts/baseof.html --
          229 Base.{{ block "main" . }}{{ end }}
          230 Hero:{{ block "hero" . }}{{ end }}:
          231 {{ with (templates.Defer (dict "key" "global")) }}
          232 Defer Block.
          233 {{ end }}
          234 -- layouts/baseof.fr.html --
          235 Base fr.{{ block "main" . }}{{ end }}
          236 -- layouts/baseof.term.html --
          237 Base term.
          238 -- layouts/baseof.section.fr.amp.html --
          239 Base with identifiers.{{ block "main" . }}{{ end }}
          240 -- layouts/partials/mypartial.html --
          241 Partial. {{ partial "_inline/my-inline-partial-in-partial-with-no-ext" . }}
          242 {{ define "partials/_inline/my-inline-partial-in-partial-with-no-ext" }}
          243 Partial in partial.
          244 {{ end }}
          245 -- layouts/partials/returnfoo.html --
          246 {{ $v := "foo" }}
          247 {{ return $v }}
          248 -- layouts/shortcodes/myshortcode.html --
          249 Shortcode. {{ partial "mypartial.html" . }}|return:{{ partial "returnfoo.html" . }}|
          250 -- content/_index.md --
          251 ---
          252 title: Home sweet home!
          253 ---
          254 
          255 {{< myshortcode >}}
          256 
          257 > My blockquote.
          258 
          259 
          260 Markdown link: [Foo](/foo)
          261 -- content/p1.md --
          262 ---
          263 title: "P1"
          264 ---
          265 -- content/foo/bar/index.md --
          266 ---
          267 title: "Foo Bar"
          268 ---
          269 
          270 {{< myshortcode >}}
          271 
          272 -- content/single-list.md --
          273 ---
          274 title: "Single List"
          275 layout: "list"
          276 ---
          277 
          278 `
          279 
          280 func TestLayoutsType(t *testing.T) {
          281         files := `
          282 -- hugo.toml --
          283 disableKinds = ["taxonomy", "term"]
          284 -- layouts/list.html --
          285 List.
          286 -- layouts/mysection/single.html --
          287 mysection/single|{{ .Title }}
          288 -- layouts/mytype/single.html --
          289 mytype/single|{{ .Title }}
          290 -- content/mysection/_index.md --
          291 -- content/mysection/mysubsection/_index.md --
          292 -- content/mysection/mysubsection/p1.md --
          293 ---
          294 title: "P1"
          295 ---
          296 -- content/mysection/mysubsection/p2.md --
          297 ---
          298 title: "P2"
          299 type: "mytype"
          300 ---
          301 
          302 `
          303 
          304         b := hugolib.Test(t, files, hugolib.TestOptWarn())
          305 
          306         b.AssertLogContains("! WARN")
          307 
          308         b.AssertFileContent("public/mysection/mysubsection/p1/index.html", "mysection/single|P1")
          309         b.AssertFileContent("public/mysection/mysubsection/p2/index.html", "mytype/single|P2")
          310 }
          311 
          312 // New, as in from Hugo v0.146.0.
          313 func TestLayoutsNewSetup(t *testing.T) {
          314         const numIterations = 1
          315         for range numIterations {
          316 
          317                 b := hugolib.Test(t, newSetupTestSites, hugolib.TestOptWarn())
          318 
          319                 b.AssertLogContains("! WARN")
          320 
          321                 b.AssertFileContent("public/en/index.html",
          322                         "Base.\nHome: Home sweet home!|",
          323                         "|Shortcode.\n|",
          324                         "<p>Markdown link: Link: /foo</p>",
          325                         "|return:foo|",
          326                         "Defer Block.",
          327                         "Home hero.",
          328                         "Render blockquote.",
          329                 )
          330 
          331                 b.AssertFileContent("public/en/p1/index.html", "Base.\nSingle needs base.\n\nHero::\n\nDefer Block.")
          332                 b.AssertFileContent("public/en/404.html", "404.")
          333                 b.AssertFileContent("public/nn/404.html", "404.")
          334                 b.AssertFileContent("public/fr/404.html", "404.")
          335 
          336         }
          337 }
          338 
          339 func TestHomeRSSAndHTMLWithHTMLOnlyShortcode(t *testing.T) {
          340         t.Parallel()
          341 
          342         files := `
          343 -- hugo.toml --
          344 disableKinds = ["taxonomy", "term"]
          345 [outputs]
          346 home = ["html", "rss"]
          347 -- layouts/home.html --
          348 Home: {{ .Title }}|{{ .Content }}|
          349 -- layouts/single.html --
          350 Single: {{ .Title }}|{{ .Content }}|
          351 -- layouts/shortcodes/myshortcode.html --
          352 Myshortcode: Count: {{ math.Counter }}|
          353 -- content/p1.md --
          354 ---
          355 title: "P1"
          356 ---
          357 
          358 {{< myshortcode >}}
          359 `
          360 
          361         b := hugolib.Test(t, files)
          362 
          363         b.AssertFileContent("public/p1/index.html", "Single: P1|Myshortcode: Count: 1|")
          364         b.AssertFileContent("public/index.xml", "Myshortcode: Count: 1")
          365 }
          366 
          367 func TestHomeRSSAndHTMLWithHTMLOnlyRenderHook(t *testing.T) {
          368         t.Parallel()
          369 
          370         files := `
          371 -- hugo.toml --
          372 disableKinds = ["taxonomy", "term"]
          373 [outputs]
          374 home = ["html", "rss"]
          375 -- layouts/home.html --
          376 Home: {{ .Title }}|{{ .Content }}|
          377 -- layouts/single.html --
          378 Single: {{ .Title }}|{{ .Content }}|
          379 -- layouts/_markup/render-link.html --
          380 Render Link: {{ math.Counter }}|
          381 -- content/p1.md --
          382 ---
          383 title: "P1"
          384 ---
          385 
          386 Link: [Foo](/foo)
          387 `
          388 
          389         for range 2 {
          390                 b := hugolib.Test(t, files)
          391                 b.AssertFileContent("public/index.xml", "Link: Render Link: 1|")
          392                 b.AssertFileContent("public/p1/index.html", "Single: P1|<p>Link: Render Link: 1|<")
          393         }
          394 }
          395 
          396 func TestCodeblockIssue13864(t *testing.T) {
          397         t.Parallel()
          398 
          399         files := `
          400 -- hugo.toml --
          401 disableKinds = ['page','rss','section','sitemap','taxonomy','term']
          402 -- content/_index.md --
          403 ---
          404 title: home
          405 ---
          406 
          407 ~~~
          408 LANG: none
          409 ~~~
          410 
          411 ~~~go
          412 LANG: go
          413 ~~~
          414 
          415 ~~~go-html-template
          416 LANG: go-html-template
          417 ~~~
          418 
          419 ~~~xy
          420 LANG: xy
          421 ~~~
          422 
          423 ~~~x-y
          424 LANG: x-y
          425 ~~~
          426 -- layouts/home.html --
          427 {{ .Content }}
          428 -- layouts/_markup/render-codeblock.html --
          429 {{ .Inner }} LAYOUT: render-codeblock.html|
          430 -- layouts/_markup/render-codeblock-go.html --
          431 {{ .Inner }} LAYOUT: render-codeblock-go.html|
          432 -- layouts/_markup/render-codeblock-go-html-template.html --
          433 {{ .Inner }} LAYOUT: render-codeblock-go-html-template.html|
          434 -- layouts/_markup/render-codeblock-xy.html --
          435 {{ .Inner }} LAYOUT: render-codeblock-xy.html|
          436 -- layouts/_markup/render-codeblock-x-y.html.html --
          437 {{ .Inner }} LAYOUT: render-codeblock-x-y.html|
          438 `
          439 
          440         b := hugolib.Test(t, files)
          441 
          442         b.AssertFileContent("public/index.html",
          443                 "LANG: none LAYOUT: render-codeblock.html|",                              // pass
          444                 "LANG: go LAYOUT: render-codeblock-go.html|",                             // fail: uses render-codeblock-go-html-template.html
          445                 "LANG: go-html-template LAYOUT: render-codeblock-go-html-template.html|", // fail: uses render-codeblock.html
          446                 "LANG: xy LAYOUT: render-codeblock-xy.html|",                             // pass
          447                 "LANG: x-y LAYOUT: render-codeblock-x-y.html|",                           // fail: uses render-codeblock.html
          448         )
          449 }
          450 
          451 func TestRenderCodeblockSpecificity(t *testing.T) {
          452         files := `
          453 -- hugo.toml --
          454 -- layouts/_markup/render-codeblock.html --
          455 Render codeblock.|{{ .Inner }}|
          456 -- layouts/_markup/render-codeblock-go.html --
          457 Render codeblock go.|{{ .Inner }}|
          458 -- layouts/single.html --
          459 {{ .Title }}|{{ .Content }}|
          460 -- content/p1.md --
          461 ---
          462 title: "P1"
          463 ---
          464 
          465 §§§
          466 Basic
          467 §§§
          468 
          469 §§§ go
          470 Go
          471 §§§
          472 
          473 `
          474 
          475         b := hugolib.Test(t, files)
          476 
          477         b.AssertFileContent("public/p1/index.html", "P1|Render codeblock.|Basic|Render codeblock go.|Go|")
          478 }
          479 
          480 func TestPrintUnusedTemplates(t *testing.T) {
          481         t.Parallel()
          482 
          483         files := `
          484 -- config.toml --
          485 baseURL = 'http://example.com/'
          486 printUnusedTemplates=true
          487 -- content/p1.md --
          488 ---
          489 title: "P1"
          490 ---
          491 {{< usedshortcode >}}
          492 -- layouts/baseof.html --
          493 {{ block "main" . }}{{ end }}
          494 -- layouts/baseof.json --
          495 {{ block "main" . }}{{ end }}
          496 -- layouts/index.html --
          497 {{ define "main" }}FOO{{ end }}
          498 -- layouts/_default/single.json --
          499 -- layouts/_default/single.html --
          500 {{ define "main" }}MAIN /_default/single.html{{ end }}
          501 -- layouts/post/single.html --
          502 {{ define "main" }}MAIN{{ end }}
          503 -- layouts/_partials/usedpartial.html --
          504 -- layouts/_partials/unusedpartial.html --
          505 -- layouts/_shortcodes/usedshortcode.html --
          506 {{ partial "usedpartial.html" }}
          507 -- layouts/shortcodes/unusedshortcode.html --
          508 
          509         `
          510 
          511         b := hugolib.NewIntegrationTestBuilder(
          512                 hugolib.IntegrationTestConfig{
          513                         T:           t,
          514                         TxtarString: files,
          515                         NeedsOsFS:   true,
          516                 },
          517         )
          518         b.Build()
          519 
          520         b.AssertFileContent("public/p1/index.html", "MAIN /_default/single.html")
          521 
          522         unused := b.H.GetTemplateStore().UnusedTemplates()
          523         var names []string
          524         for _, tmpl := range unused {
          525                 if fi := tmpl.Fi; fi != nil {
          526                         names = append(names, fi.Meta().PathInfo.PathNoLeadingSlash())
          527                 }
          528         }
          529 
          530         b.Assert(names, qt.DeepEquals, []string{"_partials/unusedpartial.html", "shortcodes/unusedshortcode.html", "baseof.json", "post/single.html", "_default/single.json"})
          531         b.Assert(len(unused), qt.Equals, 5, qt.Commentf("%#v", names))
          532 }
          533 
          534 func TestCreateManyTemplateStores(t *testing.T) {
          535         t.Parallel()
          536         b := hugolib.Test(t, newSetupTestSites)
          537         store := b.H.TemplateStore
          538 
          539         for range 70 {
          540                 newStore, err := store.NewFromOpts()
          541                 b.Assert(err, qt.IsNil)
          542                 b.Assert(newStore, qt.Not(qt.IsNil))
          543         }
          544 }
          545 
          546 func BenchmarkLookupPagesLayout(b *testing.B) {
          547         files := `
          548 -- hugo.toml --
          549 -- layouts/single.html --
          550 {{ define "main" }}
          551  Main.
          552 {{ end }}
          553 -- layouts/baseof.html --
          554 baseof: {{ block "main" . }}{{ end }}
          555 -- layouts/foo/bar/single.html --
          556 {{ define "main" }}
          557  Main.
          558 {{ end }}
          559 
          560 `
          561         bb := hugolib.Test(b, files)
          562         store := bb.H.TemplateStore
          563 
          564         b.ResetTimer()
          565         b.Run("Single root", func(b *testing.B) {
          566                 q := tplimpl.TemplateQuery{
          567                         Path:     "/baz",
          568                         Category: tplimpl.CategoryLayout,
          569                         Desc:     tplimpl.TemplateDescriptor{Kind: kinds.KindPage, LayoutFromTemplate: "single", OutputFormat: "html"},
          570                 }
          571                 for i := 0; i < b.N; i++ {
          572                         store.LookupPagesLayout(q)
          573                 }
          574         })
          575 
          576         b.Run("Single sub folder", func(b *testing.B) {
          577                 q := tplimpl.TemplateQuery{
          578                         Path:     "/foo/bar",
          579                         Category: tplimpl.CategoryLayout,
          580                         Desc:     tplimpl.TemplateDescriptor{Kind: kinds.KindPage, LayoutFromTemplate: "single", OutputFormat: "html"},
          581                 }
          582                 for i := 0; i < b.N; i++ {
          583                         store.LookupPagesLayout(q)
          584                 }
          585         })
          586 }
          587 
          588 func BenchmarkNewTemplateStore(b *testing.B) {
          589         bb := hugolib.Test(b, newSetupTestSites)
          590         store := bb.H.TemplateStore
          591 
          592         b.ResetTimer()
          593         for i := 0; i < b.N; i++ {
          594                 newStore, err := store.NewFromOpts()
          595                 if err != nil {
          596                         b.Fatal(err)
          597                 }
          598                 if newStore == nil {
          599                         b.Fatal("newStore is nil")
          600                 }
          601         }
          602 }
          603 
          604 func TestLayoutsLookupVariants(t *testing.T) {
          605         t.Parallel()
          606 
          607         files := `
          608 -- hugo.toml --
          609 defaultContentLanguage = "en"
          610 defaultContentLanguageInSubdir = true
          611 [outputs]
          612 home = ["html", "rss"]
          613 page = ["html", "rss",  "amp"]
          614 section = ["html", "rss"]
          615 
          616 [languages]
          617 [languages.en]
          618 title = "Title in English"
          619 weight = 1
          620 [languages.nn]
          621 title = "Tittel på nynorsk"
          622 weight = 2
          623 -- layouts/list.xml --
          624 layouts/list.xml
          625 -- layouts/_shortcodes/myshortcode.html --
          626 layouts/shortcodes/myshortcode.html
          627 -- layouts/foo/bar/_shortcodes/myshortcode.html --
          628 layouts/foo/bar/_shortcodes/myshortcode.html
          629 -- layouts/_markup/render-codeblock.html --
          630 layouts/_markup/render-codeblock.html|{{ .Type }}|
          631 -- layouts/_markup/render-codeblock-go.html --
          632 layouts/_markup/render-codeblock-go.html|{{ .Type }}|
          633 -- layouts/single.xml --
          634 layouts/single.xml
          635 -- layouts/single.rss.xml --
          636 layouts/single.rss.xml
          637 -- layouts/single.nn.rss.xml --
          638 layouts/single.nn.rss.xml
          639 -- layouts/list.html --
          640 layouts/list.html
          641 -- layouts/single.html --
          642 layouts/single.html
          643 {{ .Content }}
          644 -- layouts/mylayout.html --
          645 layouts/mylayout.html
          646 -- layouts/mylayout.nn.html --
          647 layouts/mylayout.nn.html
          648 -- layouts/foo/single.rss.xml --
          649 layouts/foo/single.rss.xml
          650 -- layouts/foo/single.amp.html --
          651 layouts/foo/single.amp.html
          652 -- layouts/foo/bar/page.html --
          653 layouts/foo/bar/page.html
          654 -- layouts/foo/bar/baz/single.html --
          655 layouts/foo/bar/baz/single.html
          656 {{ .Content }}
          657 -- layouts/qux/mylayout.html --
          658 layouts/qux/mylayout.html
          659 -- layouts/qux/single.xml --
          660 layouts/qux/single.xml
          661 -- layouts/qux/mylayout.section.html --
          662 layouts/qux/mylayout.section.html
          663 -- content/p.md --
          664 ---
          665 ---
          666 §§§
          667 code
          668 §§§
          669 
          670 §§§ go
          671 code
          672 §§§
          673 
          674 {{< myshortcode >}}
          675 -- content/foo/p.md --
          676 -- content/foo/p.nn.md --
          677 -- content/foo/bar/p.md --
          678 -- content/foo/bar/withmylayout.md --
          679 ---
          680 layout: mylayout
          681 ---
          682 -- content/foo/bar/_index.md --
          683 -- content/foo/bar/baz/p.md --
          684 ---
          685 ---
          686 {{< myshortcode >}}
          687 -- content/qux/p.md --
          688 -- content/qux/_index.md --
          689 ---
          690 layout: mylayout
          691 ---
          692 -- content/qux/quux/p.md --
          693 -- content/qux/quux/withmylayout.md --
          694 ---
          695 layout: mylayout
          696 ---
          697 -- content/qux/quux/withmylayout.nn.md --
          698 ---
          699 layout: mylayout
          700 ---
          701 
          702 
          703 `
          704 
          705         b := hugolib.Test(t, files, hugolib.TestOptWarn())
          706 
          707         b.AssertLogContains("! WARN")
          708 
          709         // Single pages.
          710         // output format: html.
          711         b.AssertFileContent("public/en/p/index.html", "layouts/single.html",
          712                 "layouts/_markup/render-codeblock.html|",
          713                 "layouts/_markup/render-codeblock-go.html|go|",
          714                 "layouts/shortcodes/myshortcode.html",
          715         )
          716         b.AssertFileContent("public/en/foo/p/index.html", "layouts/single.html")
          717         b.AssertFileContent("public/en/foo/bar/p/index.html", "layouts/foo/bar/page.html")
          718         b.AssertFileContent("public/en/foo/bar/withmylayout/index.html", "layouts/mylayout.html")
          719         b.AssertFileContent("public/en/foo/bar/baz/p/index.html", "layouts/foo/bar/baz/single.html", "layouts/foo/bar/_shortcodes/myshortcode.html")
          720         b.AssertFileContent("public/en/qux/quux/withmylayout/index.html", "layouts/qux/mylayout.html")
          721         // output format: amp.
          722         b.AssertFileContent("public/en/amp/p/index.html", "layouts/single.html")
          723         b.AssertFileContent("public/en/amp/foo/p/index.html", "layouts/foo/single.amp.html")
          724         // output format: rss.
          725         b.AssertFileContent("public/en/p/index.xml", "layouts/single.rss.xml")
          726         b.AssertFileContent("public/en/foo/p/index.xml", "layouts/foo/single.rss.xml")
          727         b.AssertFileContent("public/nn/foo/p/index.xml", "layouts/single.nn.rss.xml")
          728 
          729         // Note: There is qux/single.xml that's closer, but the one in the root is used becaulse of the output format match.
          730         b.AssertFileContent("public/en/qux/p/index.xml", "layouts/single.rss.xml")
          731 
          732         // Note.
          733         b.AssertFileContent("public/nn/qux/quux/withmylayout/index.html", "layouts/mylayout.nn.html")
          734 
          735         // Section pages.
          736         // output format: html.
          737         b.AssertFileContent("public/en/foo/index.html", "layouts/list.html")
          738         b.AssertFileContent("public/en/qux/index.html", "layouts/qux/mylayout.section.html")
          739         // output format: rss.
          740         b.AssertFileContent("public/en/foo/index.xml", "layouts/list.xml")
          741 }
          742 
          743 func TestLookupOrderIssue13636(t *testing.T) {
          744         t.Parallel()
          745 
          746         filesTemplate := `
          747 -- hugo.toml --
          748 defaultContentLanguage = "en"
          749 defaultContentLanguageInSubdir = true
          750 [languages]
          751 [languages.en]
          752 weight = 1
          753 [languages.nn]
          754 weight = 2
          755 -- content/s1/p1.en.md --
          756 ---
          757 outputs: ["html", "amp", "json"]
          758 ---
          759 -- content/s1/p1.nn.md --
          760 ---
          761 outputs: ["html", "amp", "json"]
          762 ---
          763 -- layouts/L1 --
          764 L1
          765 -- layouts/L2 --
          766 L2
          767 -- layouts/L3 --
          768 L3
          769 
          770 `
          771 
          772         tests := []struct {
          773                 Lang       string
          774                 L1         string
          775                 L2         string
          776                 L3         string
          777                 ExpectHTML string
          778                 ExpectAmp  string
          779                 ExpectJSON string
          780         }{
          781                 {"en", "all.en.html", "all.html", "single.html", "single.html", "single.html", ""},
          782                 {"en", "all.amp.html", "all.html", "page.html", "page.html", "all.amp.html", ""},
          783                 {"en", "all.amp.html", "all.html", "list.html", "all.html", "all.amp.html", ""},
          784                 {"en", "all.en.html", "all.json", "single.html", "single.html", "single.html", "all.json"},
          785                 {"en", "all.en.html", "single.json", "single.html", "single.html", "single.html", "single.json"},
          786                 {"en", "all.en.html", "all.html", "list.html", "all.en.html", "all.en.html", ""},
          787                 {"en", "list.en.html", "list.html", "list.en.html", "", "", ""},
          788                 {"nn", "all.en.html", "all.html", "single.html", "single.html", "single.html", ""},
          789                 {"nn", "all.en.html", "all.nn.html", "single.html", "single.html", "single.html", ""},
          790                 {"nn", "all.en.html", "all.nn.html", "single.nn.html", "single.nn.html", "single.nn.html", ""},
          791                 {"nn", "single.json", "single.nn.json", "all.json", "", "", "single.nn.json"},
          792                 {"nn", "single.json", "single.en.json", "all.nn.json", "", "", "single.json"},
          793         }
          794 
          795         for i, test := range tests {
          796                 if i != 8 {
          797                         // continue
          798                 }
          799                 files := strings.ReplaceAll(filesTemplate, "L1", test.L1)
          800                 files = strings.ReplaceAll(files, "L2", test.L2)
          801                 files = strings.ReplaceAll(files, "L3", test.L3)
          802                 t.Logf("Test %d: %s %s %s %s", i, test.Lang, test.L1, test.L2, test.L3)
          803 
          804                 for range 3 {
          805                         b := hugolib.Test(t, files)
          806                         b.Assert(len(b.H.Sites), qt.Equals, 2)
          807 
          808                         var (
          809                                 pubhHTML = "public/LANG/s1/p1/index.html"
          810                                 pubhAmp  = "public/LANG/amp/s1/p1/index.html"
          811                                 pubhJSON = "public/LANG/s1/p1/index.json"
          812                         )
          813 
          814                         pubhHTML = strings.ReplaceAll(pubhHTML, "LANG", test.Lang)
          815                         pubhAmp = strings.ReplaceAll(pubhAmp, "LANG", test.Lang)
          816                         pubhJSON = strings.ReplaceAll(pubhJSON, "LANG", test.Lang)
          817 
          818                         if test.ExpectHTML != "" {
          819                                 b.AssertFileContent(pubhHTML, test.ExpectHTML)
          820                         } else {
          821                                 b.AssertFileExists(pubhHTML, false)
          822                         }
          823 
          824                         if test.ExpectAmp != "" {
          825                                 b.AssertFileContent(pubhAmp, test.ExpectAmp)
          826                         } else {
          827                                 b.AssertFileExists(pubhAmp, false)
          828                         }
          829 
          830                         if test.ExpectJSON != "" {
          831                                 b.AssertFileContent(pubhJSON, test.ExpectJSON)
          832                         } else {
          833                                 b.AssertFileExists(pubhJSON, false)
          834                         }
          835                 }
          836         }
          837 }
          838 
          839 func TestLookupShortcodeDepth(t *testing.T) {
          840         t.Parallel()
          841 
          842         files := `
          843 -- hugo.toml --
          844 -- layouts/_shortcodes/myshortcode.html --
          845 layouts/_shortcodes/myshortcode.html
          846 -- layouts/foo/_shortcodes/myshortcode.html --
          847 layouts/foo/_shortcodes/myshortcode.html
          848 -- layouts/single.html --
          849 {{ .Content }}|
          850 -- content/p.md --
          851 ---
          852 ---
          853 {{< myshortcode >}}
          854 -- content/foo/p.md --
          855 ---
          856 ---
          857 {{< myshortcode >}}
          858 -- content/foo/bar/p.md --
          859 ---
          860 ---
          861 {{< myshortcode >}}
          862 `
          863 
          864         b := hugolib.Test(t, files)
          865 
          866         b.AssertFileContent("public/p/index.html", "layouts/_shortcodes/myshortcode.html")
          867         b.AssertFileContent("public/foo/p/index.html", "layouts/foo/_shortcodes/myshortcode.html")
          868         b.AssertFileContent("public/foo/bar/p/index.html", "layouts/foo/_shortcodes/myshortcode.html")
          869 }
          870 
          871 func TestLookupShortcodeLayout(t *testing.T) {
          872         t.Parallel()
          873 
          874         files := `
          875 -- hugo.toml --
          876 -- layouts/_shortcodes/myshortcode.single.html --
          877 layouts/_shortcodes/myshortcode.single.html
          878 -- layouts/_shortcodes/myshortcode.list.html --
          879 layouts/_shortcodes/myshortcode.list.html
          880 -- layouts/single.html --
          881 {{ .Content }}|
          882 -- layouts/list.html --
          883 {{ .Content }}|
          884 -- content/_index.md --
          885 ---
          886 ---
          887 {{< myshortcode >}}
          888 -- content/p.md --
          889 ---
          890 ---
          891 {{< myshortcode >}}
          892 -- content/foo/p.md --
          893 ---
          894 ---
          895 {{< myshortcode >}}
          896 -- content/foo/bar/p.md --
          897 ---
          898 ---
          899 {{< myshortcode >}}
          900 `
          901 
          902         b := hugolib.Test(t, files)
          903 
          904         b.AssertFileContent("public/p/index.html", "layouts/_shortcodes/myshortcode.single.html")
          905         b.AssertFileContent("public/index.html", "layouts/_shortcodes/myshortcode.list.html")
          906 }
          907 
          908 func TestLayoutAll(t *testing.T) {
          909         t.Parallel()
          910 
          911         files := `
          912 -- hugo.toml --
          913 -- layouts/single.html --
          914 Single.
          915 -- layouts/all.html --
          916 All.
          917 -- content/p1.md --
          918 
          919 `
          920 
          921         b := hugolib.Test(t, files)
          922 
          923         b.AssertFileContent("public/p1/index.html", "Single.")
          924         b.AssertFileContent("public/index.html", "All.")
          925 }
          926 
          927 func TestLayoutAllNested(t *testing.T) {
          928         t.Parallel()
          929 
          930         files := `
          931 -- hugo.toml --
          932 disableKinds = ['rss','sitemap','taxonomy','term']
          933 -- content/s1/p1.md --
          934 ---
          935 title: p1
          936 ---
          937 -- content/s2/p2.md --
          938 ---
          939 title: p2
          940 ---
          941 -- layouts/single.html --
          942 layouts/single.html
          943 -- layouts/list.html --
          944 layouts/list.html
          945 -- layouts/s1/all.html --
          946 layouts/s1/all.html
          947 `
          948 
          949         b := hugolib.Test(t, files)
          950 
          951         b.AssertFileContent("public/index.html", "layouts/list.html")
          952         b.AssertFileContent("public/s1/index.html", "layouts/s1/all.html")
          953         b.AssertFileContent("public/s1/p1/index.html", "layouts/s1/all.html")
          954         b.AssertFileContent("public/s2/index.html", "layouts/list.html")
          955         b.AssertFileContent("public/s2/p2/index.html", "layouts/single.html")
          956 }
          957 
          958 func TestPartialHTML(t *testing.T) {
          959         t.Parallel()
          960 
          961         files := `
          962 -- hugo.toml --
          963 -- layouts/all.html --
          964 <html>
          965 <head>
          966 {{ partial "css.html" .}}
          967 </head>
          968 </html>
          969 -- layouts/partials/css.html --
          970 <link rel="stylesheet" href="/css/style.css">
          971 `
          972 
          973         b := hugolib.Test(t, files)
          974 
          975         b.AssertFileContent("public/index.html", "<link rel=\"stylesheet\" href=\"/css/style.css\">")
          976 }
          977 
          978 func TestPartialPlainTextInHTML(t *testing.T) {
          979         t.Parallel()
          980 
          981         files := `
          982 -- hugo.toml --
          983 -- layouts/all.html --
          984 <html>
          985 <head>
          986 {{ partial "mypartial.txt" . }}
          987 </head>
          988 </html>
          989 -- layouts/partials/mypartial.txt --
          990 My <div>partial</div>.
          991 `
          992 
          993         b := hugolib.Test(t, files)
          994 
          995         b.AssertFileContent("public/index.html", "My &lt;div&gt;partial&lt;/div&gt;.")
          996 }
          997 
          998 // Issue #13593.
          999 func TestGoatAndNoGoat(t *testing.T) {
         1000         t.Parallel()
         1001 
         1002         files := `
         1003 -- hugo.toml --
         1004 -- content/_index.md --
         1005 ---
         1006 title: "Home"
         1007 ---
         1008 
         1009 
         1010 §§§
         1011 printf "Hello, world!"
         1012 §§§
         1013 
         1014 
         1015 §§§ goat
         1016 .---.     .-.       .-.       .-.     .---.
         1017 | A +--->| 1 |<--->| 2 |<--->| 3 |<---+ B |
         1018 '---'     '-'       '+'       '+'     '---'
         1019 §§§
         1020 
         1021 
         1022 
         1023 -- layouts/all.html --
         1024 {{ .Content }}
         1025 
         1026 `
         1027 
         1028         b := hugolib.Test(t, files)
         1029 
         1030         // Basic code block.
         1031         b.AssertFileContent("public/index.html", "<code>printf &#34;Hello, world!&#34;\n</code>")
         1032 
         1033         // Goat code block.
         1034         b.AssertFileContent("public/index.html", "Menlo,Lucida")
         1035 }
         1036 
         1037 // Issue #13595.
         1038 func TestGoatAndNoGoatCustomTemplate(t *testing.T) {
         1039         t.Parallel()
         1040 
         1041         files := `
         1042 -- hugo.toml --
         1043 -- content/_index.md --
         1044 ---
         1045 title: "Home"
         1046 ---
         1047 
         1048 §§§
         1049 printf "Hello, world!"
         1050 §§§
         1051 
         1052 §§§ goat
         1053 .---.     .-.       .-.       .-.     .---.
         1054 | A +--->| 1 |<--->| 2 |<--->| 3 |<---+ B |
         1055 '---'     '-'       '+'       '+'     '---'
         1056 §§§
         1057 
         1058 
         1059 
         1060 -- layouts/_markup/render-codeblock.html --
         1061 _markup/render-codeblock.html
         1062 -- layouts/all.html --
         1063 {{ .Content }}
         1064 
         1065 `
         1066 
         1067         b := hugolib.Test(t, files)
         1068 
         1069         // Basic code block.
         1070         b.AssertFileContent("public/index.html", "_markup/render-codeblock.html")
         1071 
         1072         // Goat code block.
         1073         b.AssertFileContent("public/index.html", "Menlo,Lucida")
         1074 }
         1075 
         1076 func TestGoatcustom(t *testing.T) {
         1077         t.Parallel()
         1078 
         1079         files := `
         1080 -- hugo.toml --
         1081 -- content/_index.md --
         1082 ---
         1083 title: "Home"
         1084 ---
         1085 
         1086 §§§
         1087 printf "Hello, world!"
         1088 §§§
         1089 
         1090 §§§ goat
         1091 .---.     .-.       .-.       .-.     .---.
         1092 | A +--->| 1 |<--->| 2 |<--->| 3 |<---+ B |
         1093 '---'     '-'       '+'       '+'     '---'
         1094 §§§
         1095 
         1096 
         1097 
         1098 -- layouts/_markup/render-codeblock.html --
         1099 _markup/render-codeblock.html
         1100 -- layouts/_markup/render-codeblock-goat.html --
         1101 _markup/render-codeblock-goat.html
         1102 -- layouts/all.html --
         1103 {{ .Content }}
         1104 
         1105 `
         1106 
         1107         b := hugolib.Test(t, files)
         1108 
         1109         // Basic code block.
         1110         b.AssertFileContent("public/index.html", "_markup/render-codeblock.html")
         1111 
         1112         // Custom Goat code block.
         1113         b.AssertFileContent("public/index.html", "_markup/render-codeblock.html_markup/render-codeblock-goat.html")
         1114 }
         1115 
         1116 func TestLookupCodeblockIssue13651(t *testing.T) {
         1117         t.Parallel()
         1118 
         1119         files := `
         1120 -- hugo.toml --
         1121 -- layouts/all.html --
         1122 {{ .Content }}|
         1123 -- layouts/_markup/render-codeblock-foo.html --
         1124 render-codeblock-foo.html
         1125 -- content/_index.md --
         1126 ---
         1127 ---
         1128 
         1129 §§§
         1130 printf "Hello, world!"
         1131 §§§
         1132 
         1133 §§§ foo
         1134 printf "Hello, world again!"
         1135 §§§
         1136 `
         1137 
         1138         b := hugolib.Test(t, files)
         1139 
         1140         content := b.FileContent("public/index.html")
         1141         fooCount := strings.Count(content, "render-codeblock-foo.html")
         1142         b.Assert(fooCount, qt.Equals, 1)
         1143 }
         1144 
         1145 // Issue #13515
         1146 func TestPrintPathWarningOnDotRemoval(t *testing.T) {
         1147         t.Parallel()
         1148 
         1149         files := `
         1150 -- hugo.toml --
         1151 baseURL = "https://example.com"
         1152 printPathWarnings = true
         1153 -- content/v0.124.0.md --
         1154 -- content/v0.123.0.md --
         1155 -- layouts/all.html --
         1156 All.
         1157 -- layouts/_default/single.html --
         1158 {{ .Title }}|
         1159 `
         1160 
         1161         b := hugolib.Test(t, files, hugolib.TestOptWarn())
         1162 
         1163         b.AssertLogContains("! Duplicate content path")
         1164 }
         1165 
         1166 // Issue #13577.
         1167 func TestPrintPathWarningOnInvalidMarkupFilename(t *testing.T) {
         1168         t.Parallel()
         1169 
         1170         files := `
         1171 -- hugo.toml --
         1172 -- layouts/all.html --
         1173 All.
         1174 -- layouts/_markup/sitemap.xml --
         1175 `
         1176         b := hugolib.Test(t, files, hugolib.TestOptWarn())
         1177 
         1178         b.AssertLogContains("unrecognized render hook")
         1179 }
         1180 
         1181 func TestLayoutNotFound(t *testing.T) {
         1182         t.Parallel()
         1183 
         1184         files := `
         1185 -- hugo.toml --
         1186 -- layouts/single.html --
         1187 Single.
         1188 `
         1189         b := hugolib.Test(t, files, hugolib.TestOptWarn())
         1190         b.AssertLogContains("WARN  found no layout file for \"html\" for kind \"home\"")
         1191 }
         1192 
         1193 func TestLayoutOverrideThemeWhenThemeOnOldFormatIssue13715(t *testing.T) {
         1194         t.Parallel()
         1195 
         1196         files := `
         1197 -- hugo.toml --
         1198 theme = "mytheme"
         1199 -- layouts/list.html --
         1200  layouts/list.html
         1201 -- themes/mytheme/layouts/_default/list.html --
         1202 mytheme/layouts/_default/list.html
         1203 
         1204 `
         1205 
         1206         b := hugolib.Test(t, files)
         1207         b.AssertFileContent("public/index.html", "layouts/list.html")
         1208 }
         1209 
         1210 func BenchmarkExecuteWithContext(b *testing.B) {
         1211         files := `
         1212 -- hugo.toml --
         1213 disableKinds = ["taxonomy", "term", "home"]
         1214 -- layouts/all.html --
         1215 {{ .Title }}|
         1216 {{ partial "p1.html" . }}
         1217 -- layouts/_partials/p1.html --
         1218  p1.
         1219 {{ partial "p2.html" . }}
         1220 {{ partial "p2.html" . }}
         1221 {{ partial "p3.html" . }}
         1222 {{ partial "p2.html" . }}
         1223 {{ partial "p2.html" . }}
         1224 {{ partial "p2.html" . }}
         1225 {{ partial "p3.html" . }}
         1226 -- layouts/_partials/p2.html --
         1227 {{ partial "p3.html" . }}
         1228 -- layouts/_partials/p3.html --
         1229 p3
         1230 -- content/p1.md --
         1231 `
         1232 
         1233         bb := hugolib.Test(b, files)
         1234 
         1235         store := bb.H.TemplateStore
         1236 
         1237         ti := store.LookupByPath("/all.html")
         1238         bb.Assert(ti, qt.Not(qt.IsNil))
         1239         p := bb.H.Sites[0].RegularPages()[0]
         1240         bb.Assert(p, qt.Not(qt.IsNil))
         1241 
         1242         b.ResetTimer()
         1243         for i := 0; i < b.N; i++ {
         1244                 err := store.ExecuteWithContext(context.Background(), ti, io.Discard, p)
         1245                 if err != nil {
         1246                         b.Fatal(err)
         1247                 }
         1248         }
         1249 }
         1250 
         1251 func BenchmarkLookupPartial(b *testing.B) {
         1252         files := `
         1253 -- hugo.toml --
         1254 disableKinds = ["taxonomy", "term", "home"]
         1255 -- layouts/all.html --
         1256 {{ .Title }}|
         1257 -- layouts/_partials/p1.html --
         1258 -- layouts/_partials/p2.html --
         1259 -- layouts/_partials/p2.json --
         1260 -- layouts/_partials/p3.html --
         1261 `
         1262         bb := hugolib.Test(b, files)
         1263 
         1264         store := bb.H.TemplateStore
         1265 
         1266         for i := 0; i < b.N; i++ {
         1267                 fi := store.LookupPartial("p3.html")
         1268                 if fi == nil {
         1269                         b.Fatal("not found")
         1270                 }
         1271         }
         1272 }
         1273 
         1274 // Implemented by pageOutput.
         1275 type getDescriptorProvider interface {
         1276         GetInternalTemplateBasePathAndDescriptor() (string, tplimpl.TemplateDescriptor)
         1277 }
         1278 
         1279 func BenchmarkLookupShortcode(b *testing.B) {
         1280         files := `
         1281 -- hugo.toml --
         1282 disableKinds = ["taxonomy", "term", "home"]
         1283 -- content/toplevelpage.md --
         1284 -- content/a/b/c/nested.md --
         1285 -- layouts/all.html --
         1286 {{ .Title }}|
         1287 -- layouts/_shortcodes/s.html --
         1288 s1.
         1289 -- layouts/_shortcodes/a/b/s.html --
         1290 s2.
         1291 
         1292 `
         1293         bb := hugolib.Test(b, files)
         1294         store := bb.H.TemplateStore
         1295 
         1296         runOne := func(p page.Page) {
         1297                 pth, desc := p.(getDescriptorProvider).GetInternalTemplateBasePathAndDescriptor()
         1298                 q := tplimpl.TemplateQuery{
         1299                         Path:     pth,
         1300                         Name:     "s",
         1301                         Category: tplimpl.CategoryShortcode,
         1302                         Desc:     desc,
         1303                 }
         1304                 v, err := store.LookupShortcode(q)
         1305                 if v == nil || err != nil {
         1306                         b.Fatal("not found")
         1307                 }
         1308         }
         1309 
         1310         b.Run("toplevelpage", func(b *testing.B) {
         1311                 toplevelpage, _ := bb.H.Sites[0].GetPage("/toplevelpage")
         1312                 for i := 0; i < b.N; i++ {
         1313                         runOne(toplevelpage)
         1314                 }
         1315         })
         1316 
         1317         b.Run("nestedpage", func(b *testing.B) {
         1318                 toplevelpage, _ := bb.H.Sites[0].GetPage("/a/b/c/nested")
         1319                 for i := 0; i < b.N; i++ {
         1320                         runOne(toplevelpage)
         1321                 }
         1322         })
         1323 }
         1324 
         1325 func TestStandardLayoutInFrontMatter13588(t *testing.T) {
         1326         t.Parallel()
         1327 
         1328         files := `
         1329 -- hugo.toml --
         1330 disableKinds = ['home','page','rss','sitemap','taxonomy','term']
         1331 -- content/s1/_index.md --
         1332 ---
         1333 title: s1
         1334 ---
         1335 -- content/s2/_index.md --
         1336 ---
         1337 title: s2
         1338 layout: list
         1339 ---
         1340 -- content/s3/_index.md --
         1341 ---
         1342 title: s3
         1343 layout: single
         1344 ---
         1345 -- layouts/list.html --
         1346 list.html
         1347 -- layouts/section.html --
         1348 section.html
         1349 -- layouts/single.html --
         1350 single.html
         1351 `
         1352 
         1353         b := hugolib.Test(t, files)
         1354 
         1355         b.AssertFileContent("public/s1/index.html", "section.html")
         1356         b.AssertFileContent("public/s2/index.html", "list.html")   // fail
         1357         b.AssertFileContent("public/s3/index.html", "single.html") // fail
         1358 }
         1359 
         1360 func TestIssue13605(t *testing.T) {
         1361         t.Parallel()
         1362 
         1363         files := `
         1364 -- hugo.toml --
         1365 disableKinds = ['home','rss','section','sitemap','taxonomy','term']
         1366 -- content/s1/p1.md --
         1367 ---
         1368 title: p1
         1369 ---
         1370 {{< sc >}}
         1371 -- layouts/s1/_shortcodes/sc.html --
         1372 layouts/s1/_shortcodes/sc.html
         1373 -- layouts/single.html --
         1374 {{ .Content }}
         1375 `
         1376 
         1377         b := hugolib.Test(t, files)
         1378 
         1379         b.AssertFileContent("public/s1/p1/index.html", "layouts/s1/_shortcodes/sc.html")
         1380 }
         1381 
         1382 func TestSkipDotFiles(t *testing.T) {
         1383         t.Parallel()
         1384 
         1385         files := `
         1386 -- hugo.toml --
         1387 -- layouts/all.html --
         1388 All.
         1389 -- layouts/.DS_Store --
         1390 {{ foo }}
         1391 `
         1392 
         1393         // Just make sure it doesn't fail.
         1394         hugolib.Test(t, files)
         1395 }
         1396 
         1397 func TestPartialsLangIssue13612(t *testing.T) {
         1398         t.Parallel()
         1399 
         1400         files := `
         1401 -- hugo.toml --
         1402 disableKinds = ['page','section','sitemap','taxonomy','term']
         1403 
         1404 defaultContentLanguage = 'ru'
         1405 defaultContentLanguageInSubdir = true
         1406 
         1407 [languages.ru]
         1408 weight = 1
         1409 
         1410 [languages.en]
         1411 weight = 2
         1412 
         1413 [outputs]
         1414 home = ['html','rss']
         1415 
         1416 -- layouts/_partials/comment.en.html --
         1417 layouts/_partials/comment.en.html
         1418 -- layouts/_partials/comment.en.xml --
         1419 layouts/_partials/comment.en.xml
         1420 -- layouts/_partials/comment.ru.html --
         1421 layouts/_partials/comment.ru.html
         1422 -- layouts/_partials/comment.ru.xml --
         1423 layouts/_partials/comment.ru.xml
         1424 -- layouts/home.html --
         1425 {{ partial (print "comment." (default "ru" .Lang) ".html") . }}
         1426 -- layouts/home.rss.xml --
         1427 {{ partial (print "comment." (default "ru" .Lang) ".xml") . }}
         1428 `
         1429 
         1430         b := hugolib.Test(t, files)
         1431 
         1432         b.AssertFileContent("public/en/index.html", "layouts/_partials/comment.en.html")
         1433         b.AssertFileContent("public/en/index.xml", "layouts/_partials/comment.en.xml")   // fail
         1434         b.AssertFileContent("public/ru/index.html", "layouts/_partials/comment.ru.html") // fail
         1435         b.AssertFileContent("public/ru/index.xml", "layouts/_partials/comment.ru.xml")   // fail
         1436 }
         1437 
         1438 func TestLayoutIssue13628(t *testing.T) {
         1439         t.Parallel()
         1440 
         1441         files := `
         1442 -- hugo.toml --
         1443 disableKinds = ['home','rss','sitemap','taxonomy','term']
         1444 -- content/p1.md --
         1445 ---
         1446 title: p1
         1447 layout: foo
         1448 ---
         1449 -- layouts/single.html --
         1450 layouts/single.html
         1451 -- layouts/list.html --
         1452 layouts/list.html
         1453 `
         1454 
         1455         for range 5 {
         1456 
         1457                 b := hugolib.Test(t, files)
         1458 
         1459                 b.AssertFileContent("public/p1/index.html", "layouts/single.html")
         1460         }
         1461 }
         1462 
         1463 func TestTemplateLoop(t *testing.T) {
         1464         t.Parallel()
         1465 
         1466         files := `
         1467 -- hugo.toml --
         1468 -- layouts/_partials/p.html --
         1469 p: {{ partial "p.html" . }}
         1470 -- layouts/all.html --
         1471 {{ partial "p.html" . }}
         1472 
         1473 `
         1474         b, err := hugolib.TestE(t, files)
         1475         b.Assert(err, qt.IsNotNil)
         1476         b.Assert(err.Error(), qt.Contains, "error calling partial: maximum template call stack size exceeded")
         1477 }
         1478 
         1479 func TestIssue13630(t *testing.T) {
         1480         t.Parallel()
         1481 
         1482         files := `
         1483 -- hugo.toml --
         1484 disableKinds = ['rss','sitemap']
         1485 -- content/p1.md --
         1486 ---
         1487 title: p1
         1488 layout: foo
         1489 ---
         1490 -- layouts/list.html --
         1491 layouts/list.html
         1492 -- layouts/taxononmy.html.html --
         1493 layouts/taxononmy.html.html
         1494 `
         1495 
         1496         var b *hugolib.IntegrationTestBuilder
         1497 
         1498         for range 3 {
         1499                 b = hugolib.Test(t, files)
         1500                 b.AssertFileExists("public/p1/index.html", false)
         1501         }
         1502 }
         1503 
         1504 func TestTemplateLoopBlogVsBlogrollIssue13672(t *testing.T) {
         1505         t.Parallel()
         1506         files := `
         1507 -- hugo.toml --
         1508 -- layouts/blog/_shortcodes/myshortcode.html --
         1509 layouts/blog/_shortcodes/myshortcode.html
         1510 -- layouts/blog/baseof.html --
         1511 blog/baseof.html {{ block "main" . }}{{ end }}
         1512 -- layouts/blog/all.html --
         1513 {{ define "main" }}blog/all.html|{{ .Content}}{{ end }}
         1514 -- layouts/blogroll/_shortcodes/myshortcode.html --
         1515 layouts/blogroll/myshortcode.html
         1516 -- layouts/blogroll/baseof.html --
         1517 {{ block "main" . }}blogroll/baseof.html{{ end }}
         1518 -- layouts/blogroll/all.html --
         1519 {{ define "main" }}blogroll/all.html|{{ .Content}}{{ end }}
         1520 -- content/blog/p1.md --
         1521 ---
         1522 title: p1
         1523 ---
         1524 {{< myshortcode >}}
         1525 -- content/blogroll/p1.md --
         1526 ---
         1527 title: p1
         1528 ---
         1529 {{< myshortcode >}}
         1530 `
         1531 
         1532         b := hugolib.Test(t, files)
         1533 
         1534         b.AssertFileContent("public/blog/p1/index.html", "blog/baseof.html blog/all.html|layouts/blog/_shortcodes/myshortcode.html")
         1535         b.AssertFileContent("public/blogroll/p1/index.html", "blogroll/all.html|layouts/blogroll/myshortcode.html")
         1536 }
         1537 
         1538 // See issue #13668.
         1539 func TestPartialPlainTextVsHTML(t *testing.T) {
         1540         t.Parallel()
         1541 
         1542         /*
         1543                 Note that in the below, there's no output format named txt,
         1544                 so the isPlainText is fetched from the only output format with that extension.
         1545         */
         1546         files := `
         1547 -- hugo.toml --
         1548 -- layouts/_partials/myhtml.html --
         1549 <div>myhtml</div>
         1550 -- layouts/_partials/mytext.txt --
         1551 <div>mytext</div>
         1552 -- layouts/all.html --
         1553 myhtml: {{ partial "myhtml.html" . }}
         1554 mytext: {{ partial "mytext.txt" . }}
         1555 mytexts|safeHTML: {{ partial "mytext.txt" . | safeHTML }}
         1556 `
         1557 
         1558         b := hugolib.Test(t, files)
         1559 
         1560         b.AssertFileContent("public/index.html",
         1561                 "myhtml: <div>myhtml</div>",
         1562                 "mytext: &lt;div&gt;mytext&lt;/div&gt;",
         1563                 "mytexts|safeHTML: <div>mytext</div>",
         1564         )
         1565 }
         1566 
         1567 func TestIssue13351(t *testing.T) {
         1568         t.Parallel()
         1569 
         1570         files := `
         1571 -- hugo.toml --
         1572 disableKinds = ['page','rss','section','sitemap','taxonomy','term']
         1573 [outputs]
         1574 home = ['html','json']
         1575 [outputFormats.html]
         1576 weight = 1
         1577 [outputFormats.json]
         1578 weight = 2
         1579 -- content/_index.md --
         1580 ---
         1581 title: home
         1582 ---
         1583 a|b
         1584 :--|:--
         1585 1|2
         1586 -- layouts/index.html --
         1587 {{ .Content }}
         1588 -- layouts/index.json --
         1589 {{ .Content }}
         1590 `
         1591 
         1592         b := hugolib.Test(t, files)
         1593         b.AssertFileContent("public/index.html", "<table>")
         1594         b.AssertFileContent("public/index.json", "<table>")
         1595 
         1596         f := strings.ReplaceAll(files, "weight = 1", "weight = 0")
         1597         b = hugolib.Test(t, f)
         1598         b.AssertFileContent("public/index.html", "<table>")
         1599         b.AssertFileContent("public/index.json", "<table>")
         1600 
         1601         f = strings.ReplaceAll(files, "weight = 1", "")
         1602         b = hugolib.Test(t, f)
         1603         b.AssertFileContent("public/index.html", "<table>")
         1604         b.AssertFileContent("public/index.json", "<table>")
         1605 }
         1606 
         1607 func TestPageKindIssue13868(t *testing.T) {
         1608         t.Parallel()
         1609 
         1610         files := `
         1611 -- hugo.toml --
         1612 disableKinds = ['home','rss','section','sitemap','taxonomy','term']
         1613 -- content/p1.md --
         1614 ---
         1615 title: p1
         1616 ---
         1617 -- layouts/page.html --
         1618 layouts/page.html
         1619 -- layouts/p1/page.html --
         1620 layouts/p1/page.html
         1621 `
         1622 
         1623         b := hugolib.Test(t, files)
         1624 
         1625         b.AssertFileContent("public/p1/index.html", "layouts/p1/page.html")
         1626 }