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 }