1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
7 // Tests for mulitple-template parsing and execution.
22 type multiParseTest
struct {
30 var multiParseTests
= []multiParseTest
{
31 {"empty", "", noError
,
34 {"one", `{{define "foo"}} FOO {{end}}`, noError
,
37 {"two", `{{define "foo"}} FOO {{end}}{{define "bar"}} BAR {{end}}`, noError
,
38 []string{"foo", "bar"},
39 []string{" FOO ", " BAR "}},
41 {"missing end", `{{define "foo"}} FOO `, hasError
,
44 {"malformed name", `{{define "foo}} FOO `, hasError
,
49 func TestMultiParse(t
*testing
.T
) {
50 for _
, test
:= range multiParseTests
{
51 template
, err
:= New("root").Parse(test
.input
)
53 case err
== nil && !test
.ok
:
54 t
.Errorf("%q: expected error; got none", test
.name
)
56 case err
!= nil && test
.ok
:
57 t
.Errorf("%q: unexpected error: %v", test
.name
, err
)
59 case err
!= nil && !test
.ok
:
60 // expected error, got one
62 fmt
.Printf("%s: %s\n\t%s\n", test
.name
, test
.input
, err
)
69 if len(template
.tmpl
) != len(test
.names
)+1 { // +1 for root
70 t
.Errorf("%s: wrong number of templates; wanted %d got %d", test
.name
, len(test
.names
), len(template
.tmpl
))
73 for i
, name
:= range test
.names
{
74 tmpl
, ok
:= template
.tmpl
[name
]
76 t
.Errorf("%s: can't find template %q", test
.name
, name
)
79 result
:= tmpl
.Root
.String()
80 if result
!= test
.results
[i
] {
81 t
.Errorf("%s=(%q): got\n\t%v\nexpected\n\t%v", test
.name
, test
.input
, result
, test
.results
[i
])
87 var multiExecTests
= []execTest
{
88 {"empty", "", "", nil, true},
89 {"text", "some text", "some text", nil, true},
90 {"invoke x", `{{template "x" .SI}}`, "TEXT", tVal
, true},
91 {"invoke x no args", `{{template "x"}}`, "TEXT", tVal
, true},
92 {"invoke dot int", `{{template "dot" .I}}`, "17", tVal
, true},
93 {"invoke dot []int", `{{template "dot" .SI}}`, "[3 4 5]", tVal
, true},
94 {"invoke dotV", `{{template "dotV" .U}}`, "v", tVal
, true},
95 {"invoke nested int", `{{template "nested" .I}}`, "17", tVal
, true},
96 {"variable declared by template", `{{template "nested" $x:=.SI}},{{index $x 1}}`, "[3 4 5],4", tVal
, true},
98 // User-defined function: test argument evaluator.
99 {"testFunc literal", `{{oneArg "joe"}}`, "oneArg=joe", tVal
, true},
100 {"testFunc .", `{{oneArg .}}`, "oneArg=joe", "joe", true},
103 // These strings are also in testdata/*.
105 {{define "x"}}TEXT{{end}}
106 {{define "dotV"}}{{.V}}{{end}}
110 {{define "dot"}}{{.}}{{end}}
111 {{define "nested"}}{{template "dot" .}}{{end}}
114 func TestMultiExecute(t
*testing
.T
) {
115 // Declare a couple of templates first.
116 template
, err
:= New("root").Parse(multiText1
)
118 t
.Fatalf("parse error for 1: %s", err
)
120 _
, err
= template
.Parse(multiText2
)
122 t
.Fatalf("parse error for 2: %s", err
)
124 testExecute(multiExecTests
, template
, t
)
127 func TestParseFiles(t
*testing
.T
) {
128 _
, err
:= ParseFiles("DOES NOT EXIST")
130 t
.Error("expected error for non-existent file; got none")
132 template
:= New("root")
133 _
, err
= template
.ParseFiles("testdata/file1.tmpl", "testdata/file2.tmpl")
135 t
.Fatalf("error parsing files: %v", err
)
137 testExecute(multiExecTests
, template
, t
)
140 func TestParseGlob(t
*testing
.T
) {
141 _
, err
:= ParseGlob("DOES NOT EXIST")
143 t
.Error("expected error for non-existent file; got none")
145 _
, err
= New("error").ParseGlob("[x")
147 t
.Error("expected error for bad pattern; got none")
149 template
:= New("root")
150 _
, err
= template
.ParseGlob("testdata/file*.tmpl")
152 t
.Fatalf("error parsing files: %v", err
)
154 testExecute(multiExecTests
, template
, t
)
157 // In these tests, actual content (not just template definitions) comes from the parsed files.
159 var templateFileExecTests
= []execTest
{
160 {"test", `{{template "tmpl1.tmpl"}}{{template "tmpl2.tmpl"}}`, "template1\n\ny\ntemplate2\n\nx\n", 0, true},
163 func TestParseFilesWithData(t
*testing
.T
) {
164 template
, err
:= New("root").ParseFiles("testdata/tmpl1.tmpl", "testdata/tmpl2.tmpl")
166 t
.Fatalf("error parsing files: %v", err
)
168 testExecute(templateFileExecTests
, template
, t
)
171 func TestParseGlobWithData(t
*testing
.T
) {
172 template
, err
:= New("root").ParseGlob("testdata/tmpl*.tmpl")
174 t
.Fatalf("error parsing files: %v", err
)
176 testExecute(templateFileExecTests
, template
, t
)
180 cloneText1
= `{{define "a"}}{{template "b"}}{{template "c"}}{{end}}`
181 cloneText2
= `{{define "b"}}b{{end}}`
182 cloneText3
= `{{define "c"}}root{{end}}`
183 cloneText4
= `{{define "c"}}clone{{end}}`
186 func TestClone(t
*testing
.T
) {
187 // Create some templates and clone the root.
188 root
, err
:= New("root").Parse(cloneText1
)
192 _
, err
= root
.Parse(cloneText2
)
196 clone
:= Must(root
.Clone())
197 // Add variants to both.
198 _
, err
= root
.Parse(cloneText3
)
202 _
, err
= clone
.Parse(cloneText4
)
206 // Verify that the clone is self-consistent.
207 for k
, v
:= range clone
.tmpl
{
208 if k
== clone
.name
&& v
.tmpl
[k
] != clone
{
209 t
.Error("clone does not contain root")
211 if v
!= v
.tmpl
[v
.name
] {
212 t
.Errorf("clone does not contain self for %q", k
)
217 err
= root
.ExecuteTemplate(&b
, "a", 0)
221 if b
.String() != "broot" {
222 t
.Errorf("expected %q got %q", "broot", b
.String())
226 err
= clone
.ExecuteTemplate(&b
, "a", 0)
230 if b
.String() != "bclone" {
231 t
.Errorf("expected %q got %q", "bclone", b
.String())
235 func TestAddParseTree(t
*testing
.T
) {
236 // Create some templates.
237 root
, err
:= New("root").Parse(cloneText1
)
241 _
, err
= root
.Parse(cloneText2
)
245 // Add a new parse tree.
246 tree
, err
:= parse
.Parse("cloneText3", cloneText3
, "", "", nil, builtins
)
250 added
, err
:= root
.AddParseTree("c", tree
["c"])
253 err
= added
.ExecuteTemplate(&b
, "a", 0)
257 if b
.String() != "broot" {
258 t
.Errorf("expected %q got %q", "broot", b
.String())
263 func TestAddParseTreeToUnparsedTemplate(t
*testing
.T
) {
264 master
:= "{{define \"master\"}}{{end}}"
265 tmpl
:= New("master")
266 tree
, err
:= parse
.Parse("master", master
, "", "", nil)
268 t
.Fatalf("unexpected parse err: %v", err
)
270 masterTree
:= tree
["master"]
271 tmpl
.AddParseTree("master", masterTree
) // used to panic
274 func TestRedefinition(t
*testing
.T
) {
277 if tmpl
, err
= New("tmpl1").Parse(`{{define "test"}}foo{{end}}`); err
!= nil {
278 t
.Fatalf("parse 1: %v", err
)
280 if _
, err
= tmpl
.Parse(`{{define "test"}}bar{{end}}`); err
== nil {
281 t
.Fatal("expected error")
283 if !strings
.Contains(err
.Error(), "redefinition") {
284 t
.Fatalf("expected redefinition error; got %v", err
)
286 if _
, err
= tmpl
.New("tmpl2").Parse(`{{define "test"}}bar{{end}}`); err
== nil {
287 t
.Fatal("expected error")
289 if !strings
.Contains(err
.Error(), "redefinition") {
290 t
.Fatalf("expected redefinition error; got %v", err
)