URI: 
       multi_test.go - hugo - [fork] hugo port for 9front
  HTML git clone https://git.drkhsh.at/hugo.git
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
       multi_test.go (8292B)
       ---
            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.
            4 
            5 // Tests for multiple-template execution, copied from text/template.
            6 
            7 //go:build go1.13 && !windows
            8 // +build go1.13,!windows
            9 
           10 package template
           11 
           12 import (
           13         "archive/zip"
           14         "os"
           15         "strings"
           16         "testing"
           17 
           18         "github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate/parse"
           19 )
           20 
           21 var multiExecTests = []execTest{
           22         {"empty", "", "", nil, true},
           23         {"text", "some text", "some text", nil, true},
           24         {"invoke x", `{{template "x" .SI}}`, "TEXT", tVal, true},
           25         {"invoke x no args", `{{template "x"}}`, "TEXT", tVal, true},
           26         {"invoke dot int", `{{template "dot" .I}}`, "17", tVal, true},
           27         {"invoke dot []int", `{{template "dot" .SI}}`, "[3 4 5]", tVal, true},
           28         {"invoke dotV", `{{template "dotV" .U}}`, "v", tVal, true},
           29         {"invoke nested int", `{{template "nested" .I}}`, "17", tVal, true},
           30         {"variable declared by template", `{{template "nested" $x:=.SI}},{{index $x 1}}`, "[3 4 5],4", tVal, true},
           31 
           32         // User-defined function: test argument evaluator.
           33         {"testFunc literal", `{{oneArg "joe"}}`, "oneArg=joe", tVal, true},
           34         {"testFunc .", `{{oneArg .}}`, "oneArg=joe", "joe", true},
           35 }
           36 
           37 // These strings are also in testdata/*.
           38 const multiText1 = `
           39         {{define "x"}}TEXT{{end}}
           40         {{define "dotV"}}{{.V}}{{end}}
           41 `
           42 
           43 const multiText2 = `
           44         {{define "dot"}}{{.}}{{end}}
           45         {{define "nested"}}{{template "dot" .}}{{end}}
           46 `
           47 
           48 func TestMultiExecute(t *testing.T) {
           49         // Declare a couple of templates first.
           50         template, err := New("root").Parse(multiText1)
           51         if err != nil {
           52                 t.Fatalf("parse error for 1: %s", err)
           53         }
           54         _, err = template.Parse(multiText2)
           55         if err != nil {
           56                 t.Fatalf("parse error for 2: %s", err)
           57         }
           58         testExecute(multiExecTests, template, t)
           59 }
           60 
           61 func TestParseFiles(t *testing.T) {
           62         _, err := ParseFiles("DOES NOT EXIST")
           63         if err == nil {
           64                 t.Error("expected error for non-existent file; got none")
           65         }
           66         template := New("root")
           67         _, err = template.ParseFiles("testdata/file1.tmpl", "testdata/file2.tmpl")
           68         if err != nil {
           69                 t.Fatalf("error parsing files: %v", err)
           70         }
           71         testExecute(multiExecTests, template, t)
           72 }
           73 
           74 func TestParseGlob(t *testing.T) {
           75         _, err := ParseGlob("DOES NOT EXIST")
           76         if err == nil {
           77                 t.Error("expected error for non-existent file; got none")
           78         }
           79         _, err = New("error").ParseGlob("[x")
           80         if err == nil {
           81                 t.Error("expected error for bad pattern; got none")
           82         }
           83         template := New("root")
           84         _, err = template.ParseGlob("testdata/file*.tmpl")
           85         if err != nil {
           86                 t.Fatalf("error parsing files: %v", err)
           87         }
           88         testExecute(multiExecTests, template, t)
           89 }
           90 
           91 func TestParseFS(t *testing.T) {
           92         fs := os.DirFS("testdata")
           93 
           94         {
           95                 _, err := ParseFS(fs, "DOES NOT EXIST")
           96                 if err == nil {
           97                         t.Error("expected error for non-existent file; got none")
           98                 }
           99         }
          100 
          101         {
          102                 template := New("root")
          103                 _, err := template.ParseFS(fs, "file1.tmpl", "file2.tmpl")
          104                 if err != nil {
          105                         t.Fatalf("error parsing files: %v", err)
          106                 }
          107                 testExecute(multiExecTests, template, t)
          108         }
          109 
          110         {
          111                 template := New("root")
          112                 _, err := template.ParseFS(fs, "file*.tmpl")
          113                 if err != nil {
          114                         t.Fatalf("error parsing files: %v", err)
          115                 }
          116                 testExecute(multiExecTests, template, t)
          117         }
          118 }
          119 
          120 // In these tests, actual content (not just template definitions) comes from the parsed files.
          121 
          122 var templateFileExecTests = []execTest{
          123         {"test", `{{template "tmpl1.tmpl"}}{{template "tmpl2.tmpl"}}`, "template1\n\ny\ntemplate2\n\nx\n", 0, true},
          124 }
          125 
          126 func TestParseFilesWithData(t *testing.T) {
          127         template, err := New("root").ParseFiles("testdata/tmpl1.tmpl", "testdata/tmpl2.tmpl")
          128         if err != nil {
          129                 t.Fatalf("error parsing files: %v", err)
          130         }
          131         testExecute(templateFileExecTests, template, t)
          132 }
          133 
          134 func TestParseGlobWithData(t *testing.T) {
          135         template, err := New("root").ParseGlob("testdata/tmpl*.tmpl")
          136         if err != nil {
          137                 t.Fatalf("error parsing files: %v", err)
          138         }
          139         testExecute(templateFileExecTests, template, t)
          140 }
          141 
          142 func TestParseZipFS(t *testing.T) {
          143         z, err := zip.OpenReader("testdata/fs.zip")
          144         if err != nil {
          145                 t.Fatalf("error parsing zip: %v", err)
          146         }
          147         template, err := New("root").ParseFS(z, "tmpl*.tmpl")
          148         if err != nil {
          149                 t.Fatalf("error parsing files: %v", err)
          150         }
          151         testExecute(templateFileExecTests, template, t)
          152 }
          153 
          154 const (
          155         cloneText1 = `{{define "a"}}{{template "b"}}{{template "c"}}{{end}}`
          156         cloneText2 = `{{define "b"}}b{{end}}`
          157         cloneText3 = `{{define "c"}}root{{end}}`
          158         cloneText4 = `{{define "c"}}clone{{end}}`
          159 )
          160 
          161 // Issue 7032
          162 func TestAddParseTreeToUnparsedTemplate(t *testing.T) {
          163         master := "{{define \"master\"}}{{end}}"
          164         tmpl := New("master")
          165         tree, err := parse.Parse("master", master, "", "", nil)
          166         if err != nil {
          167                 t.Fatalf("unexpected parse err: %v", err)
          168         }
          169         masterTree := tree["master"]
          170         tmpl.AddParseTree("master", masterTree) // used to panic
          171 }
          172 
          173 func TestRedefinition(t *testing.T) {
          174         var tmpl *Template
          175         var err error
          176         if tmpl, err = New("tmpl1").Parse(`{{define "test"}}foo{{end}}`); err != nil {
          177                 t.Fatalf("parse 1: %v", err)
          178         }
          179         if _, err = tmpl.Parse(`{{define "test"}}bar{{end}}`); err != nil {
          180                 t.Fatalf("got error %v, expected nil", err)
          181         }
          182         if _, err = tmpl.New("tmpl2").Parse(`{{define "test"}}bar{{end}}`); err != nil {
          183                 t.Fatalf("got error %v, expected nil", err)
          184         }
          185 }
          186 
          187 // Issue 10879
          188 func TestEmptyTemplateCloneCrash(t *testing.T) {
          189         t1 := New("base")
          190         t1.Clone() // used to panic
          191 }
          192 
          193 // Issue 10910, 10926
          194 func TestTemplateLookUp(t *testing.T) {
          195         t.Skip("broken on html/template") // TODO
          196         t1 := New("foo")
          197         if t1.Lookup("foo") != nil {
          198                 t.Error("Lookup returned non-nil value for undefined template foo")
          199         }
          200         t1.New("bar")
          201         if t1.Lookup("bar") != nil {
          202                 t.Error("Lookup returned non-nil value for undefined template bar")
          203         }
          204         t1.Parse(`{{define "foo"}}test{{end}}`)
          205         if t1.Lookup("foo") == nil {
          206                 t.Error("Lookup returned nil value for defined template")
          207         }
          208 }
          209 
          210 func TestParse(t *testing.T) {
          211         // In multiple calls to Parse with the same receiver template, only one call
          212         // can contain text other than space, comments, and template definitions
          213         t1 := New("test")
          214         if _, err := t1.Parse(`{{define "test"}}{{end}}`); err != nil {
          215                 t.Fatalf("parsing test: %s", err)
          216         }
          217         if _, err := t1.Parse(`{{define "test"}}{{/* this is a comment */}}{{end}}`); err != nil {
          218                 t.Fatalf("parsing test: %s", err)
          219         }
          220         if _, err := t1.Parse(`{{define "test"}}foo{{end}}`); err != nil {
          221                 t.Fatalf("parsing test: %s", err)
          222         }
          223 }
          224 
          225 func TestEmptyTemplate(t *testing.T) {
          226         cases := []struct {
          227                 defn []string
          228                 in   string
          229                 want string
          230         }{
          231                 {[]string{"x", "y"}, "", "y"},
          232                 {[]string{""}, "once", ""},
          233                 {[]string{"", ""}, "twice", ""},
          234                 {[]string{"{{.}}", "{{.}}"}, "twice", "twice"},
          235                 {[]string{"{{/* a comment */}}", "{{/* a comment */}}"}, "comment", ""},
          236                 {[]string{"{{.}}", ""}, "twice", "twice"}, // TODO: should want "" not "twice"
          237         }
          238 
          239         for i, c := range cases {
          240                 root := New("root")
          241 
          242                 var (
          243                         m   *Template
          244                         err error
          245                 )
          246                 for _, d := range c.defn {
          247                         m, err = root.New(c.in).Parse(d)
          248                         if err != nil {
          249                                 t.Fatal(err)
          250                         }
          251                 }
          252                 buf := &strings.Builder{}
          253                 if err := m.Execute(buf, c.in); err != nil {
          254                         t.Error(i, err)
          255                         continue
          256                 }
          257                 if buf.String() != c.want {
          258                         t.Errorf("expected string %q: got %q", c.want, buf.String())
          259                 }
          260         }
          261 }
          262 
          263 // Issue 19249 was a regression in 1.8 caused by the handling of empty
          264 // templates added in that release, which got different answers depending
          265 // on the order templates appeared in the internal map.
          266 func TestIssue19294(t *testing.T) {
          267         // The empty block in "xhtml" should be replaced during execution
          268         // by the contents of "stylesheet", but if the internal map associating
          269         // names with templates is built in the wrong order, the empty block
          270         // looks non-empty and this doesn't happen.
          271         var inlined = map[string]string{
          272                 "stylesheet": `{{define "stylesheet"}}stylesheet{{end}}`,
          273                 "xhtml":      `{{block "stylesheet" .}}{{end}}`,
          274         }
          275         all := []string{"stylesheet", "xhtml"}
          276         for i := 0; i < 100; i++ {
          277                 res, err := New("title.xhtml").Parse(`{{template "xhtml" .}}`)
          278                 if err != nil {
          279                         t.Fatal(err)
          280                 }
          281                 for _, name := range all {
          282                         _, err := res.New(name).Parse(inlined[name])
          283                         if err != nil {
          284                                 t.Fatal(err)
          285                         }
          286                 }
          287                 var buf strings.Builder
          288                 res.Execute(&buf, 0)
          289                 if buf.String() != "stylesheet" {
          290                         t.Fatalf("iteration %d: got %q; expected %q", i, buf.String(), "stylesheet")
          291                 }
          292         }
          293 }