package tplimpl_test import ( "path/filepath" "strings" "testing" qt "github.com/frankban/quicktest" "github.com/gohugoio/hugo/hugolib" "github.com/gohugoio/hugo/tpl" ) func TestPrintUnusedTemplates(t *testing.T) { t.Parallel() files := ` -- config.toml -- baseURL = 'http://example.com/' printUnusedTemplates=true -- content/p1.md -- --- title: "P1" --- {{< usedshortcode >}} -- layouts/baseof.html -- {{ block "main" . }}{{ end }} -- layouts/baseof.json -- {{ block "main" . }}{{ end }} -- layouts/index.html -- {{ define "main" }}FOO{{ end }} -- layouts/_default/single.json -- -- layouts/_default/single.html -- {{ define "main" }}MAIN{{ end }} -- layouts/post/single.html -- {{ define "main" }}MAIN{{ end }} -- layouts/partials/usedpartial.html -- -- layouts/partials/unusedpartial.html -- -- layouts/shortcodes/usedshortcode.html -- {{ partial "usedpartial.html" }} -- layouts/shortcodes/unusedshortcode.html -- ` b := hugolib.NewIntegrationTestBuilder( hugolib.IntegrationTestConfig{ T: t, TxtarString: files, NeedsOsFS: true, }, ) b.Build() unused := b.H.Tmpl().(tpl.UnusedTemplatesProvider).UnusedTemplates() var names []string for _, tmpl := range unused { names = append(names, tmpl.Name()) } b.Assert(names, qt.DeepEquals, []string{"_default/single.json", "baseof.json", "partials/unusedpartial.html", "post/single.html", "shortcodes/unusedshortcode.html"}) b.Assert(unused[0].Filename(), qt.Equals, filepath.Join(b.Cfg.WorkingDir, "layouts/_default/single.json")) } // Verify that the new keywords in Go 1.18 is available. func TestGo18Constructs(t *testing.T) { t.Parallel() files := ` -- config.toml -- baseURL = 'http://example.com/' disableKinds = ["section", "home", "rss", "taxonomy", "term", "rss"] -- content/p1.md -- --- title: "P1" --- -- layouts/partials/counter.html -- {{ if .Scratch.Get "counter" }}{{ .Scratch.Add "counter" 1 }}{{ else }}{{ .Scratch.Set "counter" 1 }}{{ end }}{{ return true }} -- layouts/_default/single.html -- continue:{{ range seq 5 }}{{ if eq . 2 }}{{continue}}{{ end }}{{ . }}{{ end }}:END: break:{{ range seq 5 }}{{ if eq . 2 }}{{break}}{{ end }}{{ . }}{{ end }}:END: continue2:{{ range seq 5 }}{{ if eq . 2 }}{{ continue }}{{ end }}{{ . }}{{ end }}:END: break2:{{ range seq 5 }}{{ if eq . 2 }}{{ break }}{{ end }}{{ . }}{{ end }}:END: counter1: {{ partial "counter.html" . }}/{{ .Scratch.Get "counter" }} and1: {{ if (and false (partial "counter.html" .)) }}true{{ else }}false{{ end }} or1: {{ if (or true (partial "counter.html" .)) }}true{{ else }}false{{ end }} and2: {{ if (and true (partial "counter.html" .)) }}true{{ else }}false{{ end }} or2: {{ if (or false (partial "counter.html" .)) }}true{{ else }}false{{ end }} counter2: {{ .Scratch.Get "counter" }} ` b := hugolib.NewIntegrationTestBuilder( hugolib.IntegrationTestConfig{ T: t, TxtarString: files, NeedsOsFS: true, }, ) b.Build() b.AssertFileContent("public/p1/index.html", ` continue:1345:END: break:1:END: continue2:1345:END: break2:1:END: counter1: true/1 and1: false or1: true and2: true or2: true counter2: 3 `) } // Issue 10495 func TestCommentsBeforeBlockDefinition(t *testing.T) { t.Parallel() files := ` -- config.toml -- baseURL = 'http://example.com/' -- content/s1/p1.md -- --- title: "S1P1" --- -- content/s2/p1.md -- --- title: "S2P1" --- -- content/s3/p1.md -- --- title: "S3P1" --- -- layouts/_default/baseof.html -- {{ block "main" . }}{{ end }} -- layouts/s1/single.html -- {{/* foo */}} {{ define "main" }}{{ .Title }}{{ end }} -- layouts/s2/single.html -- {{- /* foo */}} {{ define "main" }}{{ .Title }}{{ end }} -- layouts/s3/single.html -- {{- /* foo */ -}} {{ define "main" }}{{ .Title }}{{ end }} ` b := hugolib.NewIntegrationTestBuilder( hugolib.IntegrationTestConfig{ T: t, TxtarString: files, }, ) b.Build() b.AssertFileContent("public/s1/p1/index.html", `S1P1`) b.AssertFileContent("public/s2/p1/index.html", `S2P1`) b.AssertFileContent("public/s3/p1/index.html", `S3P1`) } func TestGoTemplateBugs(t *testing.T) { t.Run("Issue 11112", func(t *testing.T) { t.Parallel() files := ` -- config.toml -- -- layouts/index.html -- {{ $m := dict "key" "value" }} {{ $k := "" }} {{ $v := "" }} {{ range $k, $v = $m }} {{ $k }} = {{ $v }} {{ end }} ` b := hugolib.NewIntegrationTestBuilder( hugolib.IntegrationTestConfig{ T: t, TxtarString: files, }, ) b.Build() b.AssertFileContent("public/index.html", `key = value`) }) } func TestSecurityAllowActionJSTmpl(t *testing.T) { filesTemplate := ` -- config.toml -- SECURITYCONFIG -- layouts/index.html -- ` files := strings.ReplaceAll(filesTemplate, "SECURITYCONFIG", "") b, err := hugolib.NewIntegrationTestBuilder( hugolib.IntegrationTestConfig{ T: t, TxtarString: files, }, ).BuildE() b.Assert(err, qt.Not(qt.IsNil)) b.Assert(err.Error(), qt.Contains, "{{.Title}} appears in a JS template literal") files = strings.ReplaceAll(filesTemplate, "SECURITYCONFIG", ` [security] [security.gotemplates] allowActionJSTmpl = true `) b = hugolib.NewIntegrationTestBuilder( hugolib.IntegrationTestConfig{ T: t, TxtarString: files, }, ).Build() }