template_ast_transformers_test.go (3566B)
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 package tplimpl
14
15 import (
16 "testing"
17
18 template "github.com/gohugoio/hugo/tpl/internal/go_templates/htmltemplate"
19
20 qt "github.com/frankban/quicktest"
21 "github.com/gohugoio/hugo/tpl"
22 )
23
24 // Issue #2927
25 func TestTransformRecursiveTemplate(t *testing.T) {
26 c := qt.New(t)
27
28 recursive := `
29 {{ define "menu-nodes" }}
30 {{ template "menu-node" }}
31 {{ end }}
32 {{ define "menu-node" }}
33 {{ template "menu-node" }}
34 {{ end }}
35 {{ template "menu-nodes" }}
36 `
37
38 templ, err := template.New("foo").Parse(recursive)
39 c.Assert(err, qt.IsNil)
40 ts := newTestTemplate(templ)
41
42 ctx := newTemplateContext(
43 ts,
44 newTestTemplateLookup(ts),
45 )
46 ctx.applyTransformations(templ.Tree.Root)
47 }
48
49 func newTestTemplate(templ tpl.Template) *templateState {
50 return newTemplateState(
51 templ,
52 templateInfo{
53 name: templ.Name(),
54 },
55 )
56 }
57
58 func newTestTemplateLookup(in *templateState) func(name string) *templateState {
59 m := make(map[string]*templateState)
60 return func(name string) *templateState {
61 if in.Name() == name {
62 return in
63 }
64
65 if ts, found := m[name]; found {
66 return ts
67 }
68
69 if templ, found := findTemplateIn(name, in); found {
70 ts := newTestTemplate(templ)
71 m[name] = ts
72 return ts
73 }
74
75 return nil
76 }
77 }
78
79 func TestCollectInfo(t *testing.T) {
80 configStr := `{ "version": 42 }`
81
82 tests := []struct {
83 name string
84 tplString string
85 expected tpl.ParseInfo
86 }{
87 {"Basic Inner", `{{ .Inner }}`, tpl.ParseInfo{IsInner: true, Config: tpl.DefaultParseConfig}},
88 {"Basic config map", "{{ $_hugo_config := `" + configStr + "` }}", tpl.ParseInfo{Config: tpl.ParseConfig{Version: 42}}},
89 }
90
91 echo := func(in any) any {
92 return in
93 }
94
95 funcs := template.FuncMap{
96 "highlight": echo,
97 }
98
99 for _, test := range tests {
100 t.Run(test.name, func(t *testing.T) {
101 c := qt.New(t)
102
103 templ, err := template.New("foo").Funcs(funcs).Parse(test.tplString)
104 c.Assert(err, qt.IsNil)
105 ts := newTestTemplate(templ)
106 ts.typ = templateShortcode
107 ctx := newTemplateContext(
108 ts,
109 newTestTemplateLookup(ts),
110 )
111 ctx.applyTransformations(templ.Tree.Root)
112 c.Assert(ctx.t.parseInfo, qt.DeepEquals, test.expected)
113 })
114 }
115 }
116
117 func TestPartialReturn(t *testing.T) {
118 tests := []struct {
119 name string
120 tplString string
121 expected bool
122 }{
123 {"Basic", `
124 {{ $a := "Hugo Rocks!" }}
125 {{ return $a }}
126 `, true},
127 {"Expression", `
128 {{ return add 32 }}
129 `, true},
130 }
131
132 echo := func(in any) any {
133 return in
134 }
135
136 funcs := template.FuncMap{
137 "return": echo,
138 "add": echo,
139 }
140
141 for _, test := range tests {
142 t.Run(test.name, func(t *testing.T) {
143 c := qt.New(t)
144
145 templ, err := template.New("foo").Funcs(funcs).Parse(test.tplString)
146 c.Assert(err, qt.IsNil)
147 ts := newTestTemplate(templ)
148 ctx := newTemplateContext(
149 ts,
150 newTestTemplateLookup(ts),
151 )
152
153 _, err = ctx.applyTransformations(templ.Tree.Root)
154
155 // Just check that it doesn't fail in this test. We have functional tests
156 // in hugoblib.
157 c.Assert(err, qt.IsNil)
158 })
159 }
160 }