From 718e09ed4bc538f4fccc4337f99e9eb86aea31f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Thu, 3 Dec 2020 13:47:43 +0100 Subject: [PATCH] tpl/internal/go_templates: Revert formatting Should make future fork synch easier. --- .../go_templates/fmtsort/sort_test.go | 3 +- .../go_templates/htmltemplate/content_test.go | 2 +- tpl/internal/go_templates/htmltemplate/css.go | 6 +- .../go_templates/htmltemplate/escape_test.go | 2 + .../go_templates/htmltemplate/example_test.go | 2 + tpl/internal/go_templates/htmltemplate/js.go | 1 - .../go_templates/htmltemplate/js_test.go | 3 +- .../go_templates/htmltemplate/transition.go | 6 +- .../htmltemplate/transition_test.go | 1 + tpl/internal/go_templates/testenv/testenv.go | 3 +- .../go_templates/testenv/testenv_windows.go | 6 +- .../go_templates/texttemplate/example_test.go | 2 +- .../go_templates/texttemplate/exec.go | 5 +- .../go_templates/texttemplate/exec_test.go | 50 +-- .../texttemplate/hugo_template.go | 1 + .../texttemplate/hugo_template_test.go | 1 + .../go_templates/texttemplate/multi_test.go | 35 +- .../go_templates/texttemplate/parse/node.go | 1 + .../go_templates/texttemplate/parse/parse.go | 2 +- .../texttemplate/parse/parse_test.go | 360 ++++++------------ .../go_templates/texttemplate/template.go | 3 +- 21 files changed, 173 insertions(+), 322 deletions(-) diff --git a/tpl/internal/go_templates/fmtsort/sort_test.go b/tpl/internal/go_templates/fmtsort/sort_test.go index 189c693cc..364c5bf6d 100644 --- a/tpl/internal/go_templates/fmtsort/sort_test.go +++ b/tpl/internal/go_templates/fmtsort/sort_test.go @@ -6,12 +6,11 @@ package fmtsort_test import ( "fmt" + "github.com/gohugoio/hugo/tpl/internal/go_templates/fmtsort" "math" "reflect" "strings" "testing" - - "github.com/gohugoio/hugo/tpl/internal/go_templates/fmtsort" ) var compareTests = [][]reflect.Value{ diff --git a/tpl/internal/go_templates/htmltemplate/content_test.go b/tpl/internal/go_templates/htmltemplate/content_test.go index f2c5c5ed1..b5de701d3 100644 --- a/tpl/internal/go_templates/htmltemplate/content_test.go +++ b/tpl/internal/go_templates/htmltemplate/content_test.go @@ -427,7 +427,7 @@ func TestStringer(t *testing.T) { if err := tmpl.Execute(b, s); err != nil { t.Fatal(err) } - expect := "string=3" + var expect = "string=3" if b.String() != expect { t.Errorf("expected %q got %q", expect, b.String()) } diff --git a/tpl/internal/go_templates/htmltemplate/css.go b/tpl/internal/go_templates/htmltemplate/css.go index b006a0718..eb92fc92b 100644 --- a/tpl/internal/go_templates/htmltemplate/css.go +++ b/tpl/internal/go_templates/htmltemplate/css.go @@ -210,10 +210,8 @@ var cssReplacementTable = []string{ '}': `\7d`, } -var ( - expressionBytes = []byte("expression") - mozBindingBytes = []byte("mozbinding") -) +var expressionBytes = []byte("expression") +var mozBindingBytes = []byte("mozbinding") // cssValueFilter allows innocuous CSS values in the output including CSS // quantities (10px or 25%), ID or class literals (#foo, .bar), keyword values diff --git a/tpl/internal/go_templates/htmltemplate/escape_test.go b/tpl/internal/go_templates/htmltemplate/escape_test.go index ee5421cc8..075db4e13 100644 --- a/tpl/internal/go_templates/htmltemplate/escape_test.go +++ b/tpl/internal/go_templates/htmltemplate/escape_test.go @@ -891,6 +891,7 @@ func TestEscapeSet(t *testing.T) { t.Errorf("want\n\t%q\ngot\n\t%q", test.want, got) } } + } func TestErrors(t *testing.T) { @@ -1087,6 +1088,7 @@ func TestErrors(t *testing.T) { // Check that we get the same error if we call Execute again. if err := tmpl.Execute(buf, nil); err == nil || err.Error() != got { t.Errorf("input=%q: unexpected error on second call %q", test.input, err) + } } } diff --git a/tpl/internal/go_templates/htmltemplate/example_test.go b/tpl/internal/go_templates/htmltemplate/example_test.go index ee1cbbb4a..a93b8d2fb 100644 --- a/tpl/internal/go_templates/htmltemplate/example_test.go +++ b/tpl/internal/go_templates/htmltemplate/example_test.go @@ -82,6 +82,7 @@ func Example() { //
no rows
// // + } func Example_autoescaping() { @@ -122,6 +123,7 @@ func Example_escape() { // \"Fran \u0026 Freddie\'s Diner\" \u003Ctasty@example.com\u003E // \"Fran \u0026 Freddie\'s Diner\"32\u003Ctasty@example.com\u003E // %22Fran+%26+Freddie%27s+Diner%2232%3Ctasty%40example.com%3E + } func ExampleTemplate_Delims() { diff --git a/tpl/internal/go_templates/htmltemplate/js.go b/tpl/internal/go_templates/htmltemplate/js.go index f19e774c7..cfd413461 100644 --- a/tpl/internal/go_templates/htmltemplate/js.go +++ b/tpl/internal/go_templates/htmltemplate/js.go @@ -337,7 +337,6 @@ var jsStrNormReplacementTable = []string{ '<': `\u003c`, '>': `\u003e`, } - var jsRegexpReplacementTable = []string{ 0: `\u0000`, '\t': `\t`, diff --git a/tpl/internal/go_templates/htmltemplate/js_test.go b/tpl/internal/go_templates/htmltemplate/js_test.go index f7ee3cfaa..e15087f0f 100644 --- a/tpl/internal/go_templates/htmltemplate/js_test.go +++ b/tpl/internal/go_templates/htmltemplate/js_test.go @@ -206,8 +206,7 @@ func TestJSStrEscaper(t *testing.T) { {"", `--\u003e`}, // From https://code.google.com/p/doctype/wiki/ArticleUtf7 - { - "+ADw-script+AD4-alert(1)+ADw-/script+AD4-", + {"+ADw-script+AD4-alert(1)+ADw-/script+AD4-", `\u002bADw-script\u002bAD4-alert(1)\u002bADw-\/script\u002bAD4-`, }, // Invalid UTF-8 sequence diff --git a/tpl/internal/go_templates/htmltemplate/transition.go b/tpl/internal/go_templates/htmltemplate/transition.go index 5ba7f8017..06df67933 100644 --- a/tpl/internal/go_templates/htmltemplate/transition.go +++ b/tpl/internal/go_templates/htmltemplate/transition.go @@ -41,10 +41,8 @@ var transitionFunc = [...]func(context, []byte) (context, int){ stateError: tError, } -var ( - commentStart = []byte("") -) +var commentStart = []byte("") // tText is the context transition function for the text state. func tText(c context, s []byte) (context, int) { diff --git a/tpl/internal/go_templates/htmltemplate/transition_test.go b/tpl/internal/go_templates/htmltemplate/transition_test.go index c3257a839..00b0ff6ca 100644 --- a/tpl/internal/go_templates/htmltemplate/transition_test.go +++ b/tpl/internal/go_templates/htmltemplate/transition_test.go @@ -42,6 +42,7 @@ func TestFindEndTag(t *testing.T) { } func BenchmarkTemplateSpecialTags(b *testing.B) { + r := struct { Name, Gift string }{"Aunt Mildred", "bone china tea set"} diff --git a/tpl/internal/go_templates/testenv/testenv.go b/tpl/internal/go_templates/testenv/testenv.go index 7c46089f5..90044570d 100644 --- a/tpl/internal/go_templates/testenv/testenv.go +++ b/tpl/internal/go_templates/testenv/testenv.go @@ -13,6 +13,7 @@ package testenv import ( "errors" "flag" + "github.com/gohugoio/hugo/tpl/internal/go_templates/cfg" "os" "os/exec" "path/filepath" @@ -21,8 +22,6 @@ import ( "strings" "sync" "testing" - - "github.com/gohugoio/hugo/tpl/internal/go_templates/cfg" ) // Builder reports the name of the builder running this test diff --git a/tpl/internal/go_templates/testenv/testenv_windows.go b/tpl/internal/go_templates/testenv/testenv_windows.go index f9e7da5a7..eb8d6ac16 100644 --- a/tpl/internal/go_templates/testenv/testenv_windows.go +++ b/tpl/internal/go_templates/testenv/testenv_windows.go @@ -12,10 +12,8 @@ import ( "syscall" ) -var ( - symlinkOnce sync.Once - winSymlinkErr error -) +var symlinkOnce sync.Once +var winSymlinkErr error func initWinHasSymlink() { tmpdir, err := ioutil.TempDir("", "symtest") diff --git a/tpl/internal/go_templates/texttemplate/example_test.go b/tpl/internal/go_templates/texttemplate/example_test.go index 09555c95a..f192cac4f 100644 --- a/tpl/internal/go_templates/texttemplate/example_test.go +++ b/tpl/internal/go_templates/texttemplate/example_test.go @@ -34,7 +34,7 @@ Josie Name, Gift string Attended bool } - recipients := []Recipient{ + var recipients = []Recipient{ {"Aunt Mildred", "bone china tea set", true}, {"Uncle John", "moleskin pants", false}, {"Cousin Rodney", "", false}, diff --git a/tpl/internal/go_templates/texttemplate/exec.go b/tpl/internal/go_templates/texttemplate/exec.go index db533d735..879cd0884 100644 --- a/tpl/internal/go_templates/texttemplate/exec.go +++ b/tpl/internal/go_templates/texttemplate/exec.go @@ -6,13 +6,12 @@ package template import ( "fmt" + "github.com/gohugoio/hugo/tpl/internal/go_templates/fmtsort" + "github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate/parse" "io" "reflect" "runtime" "strings" - - "github.com/gohugoio/hugo/tpl/internal/go_templates/fmtsort" - "github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate/parse" ) // maxExecDepth specifies the maximum stack depth of templates within diff --git a/tpl/internal/go_templates/texttemplate/exec_test.go b/tpl/internal/go_templates/texttemplate/exec_test.go index cc79d2143..940a1de6a 100644 --- a/tpl/internal/go_templates/texttemplate/exec_test.go +++ b/tpl/internal/go_templates/texttemplate/exec_test.go @@ -318,16 +318,12 @@ var execTests = []execTest{ {"$.U.V", "{{$.U.V}}", "v", tVal, true}, {"declare in action", "{{$x := $.U.V}}{{$x}}", "v", tVal, true}, {"simple assignment", "{{$x := 2}}{{$x = 3}}{{$x}}", "3", tVal, true}, - { - "nested assignment", + {"nested assignment", "{{$x := 2}}{{if true}}{{$x = 3}}{{end}}{{$x}}", - "3", tVal, true, - }, - { - "nested assignment changes the last declaration", + "3", tVal, true}, + {"nested assignment changes the last declaration", "{{$x := 1}}{{if true}}{{$x := 2}}{{if true}}{{$x = 3}}{{end}}{{end}}{{$x}}", - "1", tVal, true, - }, + "1", tVal, true}, // Type with String method. {"V{6666}.String()", "-{{.V0}}-", "-<6666>-", tVal, true}, @@ -374,21 +370,15 @@ var execTests = []execTest{ {".Method3(nil constant)", "-{{.Method3 nil}}-", "-Method3: -", tVal, true}, {".Method3(nil value)", "-{{.Method3 .MXI.unset}}-", "-Method3: -", tVal, true}, {"method on var", "{{if $x := .}}-{{$x.Method2 .U16 $x.X}}{{end}}-", "-Method2: 16 x-", tVal, true}, - { - "method on chained var", + {"method on chained var", "{{range .MSIone}}{{if $.U.TrueFalse $.True}}{{$.U.TrueFalse $.True}}{{else}}WRONG{{end}}{{end}}", - "true", tVal, true, - }, - { - "chained method", + "true", tVal, true}, + {"chained method", "{{range .MSIone}}{{if $.GetU.TrueFalse $.True}}{{$.U.TrueFalse $.True}}{{else}}WRONG{{end}}{{end}}", - "true", tVal, true, - }, - { - "chained method on variable", + "true", tVal, true}, + {"chained method on variable", "{{with $x := .}}{{with .SI}}{{$.GetU.TrueFalse $.True}}{{end}}{{end}}", - "true", tVal, true, - }, + "true", tVal, true}, {".NilOKFunc not nil", "{{call .NilOKFunc .PI}}", "false", tVal, true}, {".NilOKFunc nil", "{{call .NilOKFunc nil}}", "true", tVal, true}, {"method on nil value from slice", "-{{range .}}{{.Method1 1234}}{{end}}-", "-1234-", tSliceOfNil, true}, @@ -474,14 +464,10 @@ var execTests = []execTest{ {"printf lots", `{{printf "%d %s %g %s" 127 "hello" 7-3i .Method0}}`, "127 hello (7-3i) M0", tVal, true}, // HTML. - { - "html", `{{html ""}}`, - "<script>alert("XSS");</script>", nil, true, - }, - { - "html pipeline", `{{printf "" | html}}`, - "<script>alert("XSS");</script>", nil, true, - }, + {"html", `{{html ""}}`, + "<script>alert("XSS");</script>", nil, true}, + {"html pipeline", `{{printf "" | html}}`, + "<script>alert("XSS");</script>", nil, true}, {"html", `{{html .PS}}`, "a string", tVal, true}, {"html typed nil", `{{html .NIL}}`, "<nil>", tVal, true}, {"html untyped nil", `{{html .Empty0}}`, "<no value>", tVal, true}, @@ -839,7 +825,7 @@ var delimPairs = []string{ func TestDelims(t *testing.T) { const hello = "Hello, world" - value := struct{ Str string }{hello} + var value = struct{ Str string }{hello} for i := 0; i < len(delimPairs); i += 2 { text := ".Str" left := delimPairs[i+0] @@ -862,7 +848,7 @@ func TestDelims(t *testing.T) { if err != nil { t.Fatalf("delim %q text %q parse err %s", left, text, err) } - b := new(bytes.Buffer) + var b = new(bytes.Buffer) err = tmpl.Execute(b, value) if err != nil { t.Fatalf("delim %q exec err %s", left, err) @@ -963,7 +949,7 @@ const treeTemplate = ` ` func TestTree(t *testing.T) { - tree := &Tree{ + var tree = &Tree{ 1, &Tree{ 2, &Tree{ @@ -1209,7 +1195,7 @@ var cmpTests = []cmpTest{ func TestComparison(t *testing.T) { b := new(bytes.Buffer) - cmpStruct := struct { + var cmpStruct = struct { Uthree, Ufour uint NegOne, Three int Ptr, NilPtr *int diff --git a/tpl/internal/go_templates/texttemplate/hugo_template.go b/tpl/internal/go_templates/texttemplate/hugo_template.go index 0dc6331c7..7cd6df0fb 100644 --- a/tpl/internal/go_templates/texttemplate/hugo_template.go +++ b/tpl/internal/go_templates/texttemplate/hugo_template.go @@ -77,6 +77,7 @@ func (t *executer) Execute(p Preparer, wr io.Writer, data interface{}) error { } return tmpl.executeWithState(state, value) + } // Prepare returns a template ready for execution. diff --git a/tpl/internal/go_templates/texttemplate/hugo_template_test.go b/tpl/internal/go_templates/texttemplate/hugo_template_test.go index 90bb09315..98a2575eb 100644 --- a/tpl/internal/go_templates/texttemplate/hugo_template_test.go +++ b/tpl/internal/go_templates/texttemplate/hugo_template_test.go @@ -85,4 +85,5 @@ Method: {{ .Hello1 "v1" }} c.Assert(got, qt.Contains, "hello hugo") c.Assert(got, qt.Contains, "Map: av") c.Assert(got, qt.Contains, "Method: v2 v1") + } diff --git a/tpl/internal/go_templates/texttemplate/multi_test.go b/tpl/internal/go_templates/texttemplate/multi_test.go index 569a45dbb..7323be379 100644 --- a/tpl/internal/go_templates/texttemplate/multi_test.go +++ b/tpl/internal/go_templates/texttemplate/multi_test.go @@ -11,9 +11,8 @@ package template import ( "bytes" "fmt" - "testing" - "github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate/parse" + "testing" ) const ( @@ -30,32 +29,22 @@ type multiParseTest struct { } var multiParseTests = []multiParseTest{ - { - "empty", "", noError, + {"empty", "", noError, nil, - nil, - }, - { - "one", `{{define "foo"}} FOO {{end}}`, noError, + nil}, + {"one", `{{define "foo"}} FOO {{end}}`, noError, []string{"foo"}, - []string{" FOO "}, - }, - { - "two", `{{define "foo"}} FOO {{end}}{{define "bar"}} BAR {{end}}`, noError, + []string{" FOO "}}, + {"two", `{{define "foo"}} FOO {{end}}{{define "bar"}} BAR {{end}}`, noError, []string{"foo", "bar"}, - []string{" FOO ", " BAR "}, - }, + []string{" FOO ", " BAR "}}, // errors - { - "missing end", `{{define "foo"}} FOO `, hasError, + {"missing end", `{{define "foo"}} FOO `, hasError, nil, + nil}, + {"malformed name", `{{define "foo}} FOO `, hasError, nil, - }, - { - "malformed name", `{{define "foo}} FOO `, hasError, - nil, - nil, - }, + nil}, } func TestMultiParse(t *testing.T) { @@ -411,7 +400,7 @@ func TestIssue19294(t *testing.T) { // by the contents of "stylesheet", but if the internal map associating // names with templates is built in the wrong order, the empty block // looks non-empty and this doesn't happen. - inlined := map[string]string{ + var inlined = map[string]string{ "stylesheet": `{{define "stylesheet"}}stylesheet{{end}}`, "xhtml": `{{block "stylesheet" .}}{{end}}`, } diff --git a/tpl/internal/go_templates/texttemplate/parse/node.go b/tpl/internal/go_templates/texttemplate/parse/node.go index dee67a2ed..1c116ea6f 100644 --- a/tpl/internal/go_templates/texttemplate/parse/node.go +++ b/tpl/internal/go_templates/texttemplate/parse/node.go @@ -249,6 +249,7 @@ func (a *ActionNode) tree() *Tree { func (a *ActionNode) Copy() Node { return a.tr.newAction(a.Pos, a.Line, a.Pipe.CopyPipe()) + } // CommandNode holds a command (a pipeline inside an evaluating action). diff --git a/tpl/internal/go_templates/texttemplate/parse/parse.go b/tpl/internal/go_templates/texttemplate/parse/parse.go index 7a58c5788..c9b80f4a2 100644 --- a/tpl/internal/go_templates/texttemplate/parse/parse.go +++ b/tpl/internal/go_templates/texttemplate/parse/parse.go @@ -453,7 +453,7 @@ func (t *Tree) parseControl(allowElseIf bool, context string) (pos Pos, line int var next Node list, next = t.itemList() switch next.Type() { - case nodeEnd: // done + case nodeEnd: //done case nodeElse: if allowElseIf { // Special case for "else if". If the "else" is followed immediately by an "if", diff --git a/tpl/internal/go_templates/texttemplate/parse/parse_test.go b/tpl/internal/go_templates/texttemplate/parse/parse_test.go index 97511190d..79e7bb5ae 100644 --- a/tpl/internal/go_templates/texttemplate/parse/parse_test.go +++ b/tpl/internal/go_templates/texttemplate/parse/parse_test.go @@ -178,134 +178,70 @@ const ( ) var parseTests = []parseTest{ - { - "empty", "", noError, - ``, - }, - { - "comment", "{{/*\n\n\n*/}}", noError, - ``, - }, - { - "spaces", " \t\n", noError, - `" \t\n"`, - }, - { - "text", "some text", noError, - `"some text"`, - }, - { - "emptyAction", "{{}}", hasError, - `{{}}`, - }, - { - "field", "{{.X}}", noError, - `{{.X}}`, - }, - { - "simple command", "{{printf}}", noError, - `{{printf}}`, - }, - { - "$ invocation", "{{$}}", noError, - "{{$}}", - }, - { - "variable invocation", "{{with $x := 3}}{{$x 23}}{{end}}", noError, - "{{with $x := 3}}{{$x 23}}{{end}}", - }, - { - "variable with fields", "{{$.I}}", noError, - "{{$.I}}", - }, - { - "multi-word command", "{{printf `%d` 23}}", noError, - "{{printf `%d` 23}}", - }, - { - "pipeline", "{{.X|.Y}}", noError, - `{{.X | .Y}}`, - }, - { - "pipeline with decl", "{{$x := .X|.Y}}", noError, - `{{$x := .X | .Y}}`, - }, - { - "nested pipeline", "{{.X (.Y .Z) (.A | .B .C) (.E)}}", noError, - `{{.X (.Y .Z) (.A | .B .C) (.E)}}`, - }, - { - "field applied to parentheses", "{{(.Y .Z).Field}}", noError, - `{{(.Y .Z).Field}}`, - }, - { - "simple if", "{{if .X}}hello{{end}}", noError, - `{{if .X}}"hello"{{end}}`, - }, - { - "if with else", "{{if .X}}true{{else}}false{{end}}", noError, - `{{if .X}}"true"{{else}}"false"{{end}}`, - }, - { - "if with else if", "{{if .X}}true{{else if .Y}}false{{end}}", noError, - `{{if .X}}"true"{{else}}{{if .Y}}"false"{{end}}{{end}}`, - }, - { - "if else chain", "+{{if .X}}X{{else if .Y}}Y{{else if .Z}}Z{{end}}+", noError, - `"+"{{if .X}}"X"{{else}}{{if .Y}}"Y"{{else}}{{if .Z}}"Z"{{end}}{{end}}{{end}}"+"`, - }, - { - "simple range", "{{range .X}}hello{{end}}", noError, - `{{range .X}}"hello"{{end}}`, - }, - { - "chained field range", "{{range .X.Y.Z}}hello{{end}}", noError, - `{{range .X.Y.Z}}"hello"{{end}}`, - }, - { - "nested range", "{{range .X}}hello{{range .Y}}goodbye{{end}}{{end}}", noError, - `{{range .X}}"hello"{{range .Y}}"goodbye"{{end}}{{end}}`, - }, - { - "range with else", "{{range .X}}true{{else}}false{{end}}", noError, - `{{range .X}}"true"{{else}}"false"{{end}}`, - }, - { - "range over pipeline", "{{range .X|.M}}true{{else}}false{{end}}", noError, - `{{range .X | .M}}"true"{{else}}"false"{{end}}`, - }, - { - "range []int", "{{range .SI}}{{.}}{{end}}", noError, - `{{range .SI}}{{.}}{{end}}`, - }, - { - "range 1 var", "{{range $x := .SI}}{{.}}{{end}}", noError, - `{{range $x := .SI}}{{.}}{{end}}`, - }, - { - "range 2 vars", "{{range $x, $y := .SI}}{{.}}{{end}}", noError, - `{{range $x, $y := .SI}}{{.}}{{end}}`, - }, - { - "constants", "{{range .SI 1 -3.2i true false 'a' nil}}{{end}}", noError, - `{{range .SI 1 -3.2i true false 'a' nil}}{{end}}`, - }, - { - "template", "{{template `x`}}", noError, - `{{template "x"}}`, - }, - { - "template with arg", "{{template `x` .Y}}", noError, - `{{template "x" .Y}}`, - }, - { - "with", "{{with .X}}hello{{end}}", noError, - `{{with .X}}"hello"{{end}}`, - }, - { - "with with else", "{{with .X}}hello{{else}}goodbye{{end}}", noError, - `{{with .X}}"hello"{{else}}"goodbye"{{end}}`, - }, + {"empty", "", noError, + ``}, + {"comment", "{{/*\n\n\n*/}}", noError, + ``}, + {"spaces", " \t\n", noError, + `" \t\n"`}, + {"text", "some text", noError, + `"some text"`}, + {"emptyAction", "{{}}", hasError, + `{{}}`}, + {"field", "{{.X}}", noError, + `{{.X}}`}, + {"simple command", "{{printf}}", noError, + `{{printf}}`}, + {"$ invocation", "{{$}}", noError, + "{{$}}"}, + {"variable invocation", "{{with $x := 3}}{{$x 23}}{{end}}", noError, + "{{with $x := 3}}{{$x 23}}{{end}}"}, + {"variable with fields", "{{$.I}}", noError, + "{{$.I}}"}, + {"multi-word command", "{{printf `%d` 23}}", noError, + "{{printf `%d` 23}}"}, + {"pipeline", "{{.X|.Y}}", noError, + `{{.X | .Y}}`}, + {"pipeline with decl", "{{$x := .X|.Y}}", noError, + `{{$x := .X | .Y}}`}, + {"nested pipeline", "{{.X (.Y .Z) (.A | .B .C) (.E)}}", noError, + `{{.X (.Y .Z) (.A | .B .C) (.E)}}`}, + {"field applied to parentheses", "{{(.Y .Z).Field}}", noError, + `{{(.Y .Z).Field}}`}, + {"simple if", "{{if .X}}hello{{end}}", noError, + `{{if .X}}"hello"{{end}}`}, + {"if with else", "{{if .X}}true{{else}}false{{end}}", noError, + `{{if .X}}"true"{{else}}"false"{{end}}`}, + {"if with else if", "{{if .X}}true{{else if .Y}}false{{end}}", noError, + `{{if .X}}"true"{{else}}{{if .Y}}"false"{{end}}{{end}}`}, + {"if else chain", "+{{if .X}}X{{else if .Y}}Y{{else if .Z}}Z{{end}}+", noError, + `"+"{{if .X}}"X"{{else}}{{if .Y}}"Y"{{else}}{{if .Z}}"Z"{{end}}{{end}}{{end}}"+"`}, + {"simple range", "{{range .X}}hello{{end}}", noError, + `{{range .X}}"hello"{{end}}`}, + {"chained field range", "{{range .X.Y.Z}}hello{{end}}", noError, + `{{range .X.Y.Z}}"hello"{{end}}`}, + {"nested range", "{{range .X}}hello{{range .Y}}goodbye{{end}}{{end}}", noError, + `{{range .X}}"hello"{{range .Y}}"goodbye"{{end}}{{end}}`}, + {"range with else", "{{range .X}}true{{else}}false{{end}}", noError, + `{{range .X}}"true"{{else}}"false"{{end}}`}, + {"range over pipeline", "{{range .X|.M}}true{{else}}false{{end}}", noError, + `{{range .X | .M}}"true"{{else}}"false"{{end}}`}, + {"range []int", "{{range .SI}}{{.}}{{end}}", noError, + `{{range .SI}}{{.}}{{end}}`}, + {"range 1 var", "{{range $x := .SI}}{{.}}{{end}}", noError, + `{{range $x := .SI}}{{.}}{{end}}`}, + {"range 2 vars", "{{range $x, $y := .SI}}{{.}}{{end}}", noError, + `{{range $x, $y := .SI}}{{.}}{{end}}`}, + {"constants", "{{range .SI 1 -3.2i true false 'a' nil}}{{end}}", noError, + `{{range .SI 1 -3.2i true false 'a' nil}}{{end}}`}, + {"template", "{{template `x`}}", noError, + `{{template "x"}}`}, + {"template with arg", "{{template `x` .Y}}", noError, + `{{template "x" .Y}}`}, + {"with", "{{with .X}}hello{{end}}", noError, + `{{with .X}}"hello"{{end}}`}, + {"with with else", "{{with .X}}hello{{else}}goodbye{{end}}", noError, + `{{with .X}}"hello"{{else}}"goodbye"{{end}}`}, // Trimming spaces. {"trim left", "x \r\n\t{{- 3}}", noError, `"x"{{3}}`}, {"trim right", "{{3 -}}\n\n\ty", noError, `{{3}}"y"`}, @@ -314,10 +250,8 @@ var parseTests = []parseTest{ {"comment trim left", "x \r\n\t{{- /* hi */}}", noError, `"x"`}, {"comment trim right", "{{/* hi */ -}}\n\n\ty", noError, `"y"`}, {"comment trim left and right", "x \r\n\t{{- /* */ -}}\n\n\ty", noError, `"x""y"`}, - { - "block definition", `{{block "foo" .}}hello{{end}}`, noError, - `{{template "foo" .}}`, - }, + {"block definition", `{{block "foo" .}}hello{{end}}`, noError, + `{{template "foo" .}}`}, // Errors. {"unclosed action", "hello{{range", hasError, ""}, {"unmatched end", "{{end}}", hasError, ""}, @@ -467,143 +401,89 @@ func TestErrorContextWithTreeCopy(t *testing.T) { // All failures, and the result is a string that must appear in the error message. var errorTests = []parseTest{ // Check line numbers are accurate. - { - "unclosed1", + {"unclosed1", "line1\n{{", - hasError, `unclosed1:2: unexpected unclosed action in command`, - }, - { - "unclosed2", + hasError, `unclosed1:2: unexpected unclosed action in command`}, + {"unclosed2", "line1\n{{define `x`}}line2\n{{", - hasError, `unclosed2:3: unexpected unclosed action in command`, - }, + hasError, `unclosed2:3: unexpected unclosed action in command`}, // Specific errors. - { - "function", + {"function", "{{foo}}", - hasError, `function "foo" not defined`, - }, - { - "comment", + hasError, `function "foo" not defined`}, + {"comment", "{{/*}}", - hasError, `unclosed comment`, - }, - { - "lparen", + hasError, `unclosed comment`}, + {"lparen", "{{.X (1 2 3}}", - hasError, `unclosed left paren`, - }, - { - "rparen", + hasError, `unclosed left paren`}, + {"rparen", "{{.X 1 2 3)}}", - hasError, `unexpected ")"`, - }, - { - "space", + hasError, `unexpected ")"`}, + {"space", "{{`x`3}}", - hasError, `in operand`, - }, - { - "idchar", + hasError, `in operand`}, + {"idchar", "{{a#}}", - hasError, `'#'`, - }, - { - "charconst", + hasError, `'#'`}, + {"charconst", "{{'a}}", - hasError, `unterminated character constant`, - }, - { - "stringconst", + hasError, `unterminated character constant`}, + {"stringconst", `{{"a}}`, - hasError, `unterminated quoted string`, - }, - { - "rawstringconst", + hasError, `unterminated quoted string`}, + {"rawstringconst", "{{`a}}", - hasError, `unterminated raw quoted string`, - }, - { - "number", + hasError, `unterminated raw quoted string`}, + {"number", "{{0xi}}", - hasError, `number syntax`, - }, - { - "multidefine", + hasError, `number syntax`}, + {"multidefine", "{{define `a`}}a{{end}}{{define `a`}}b{{end}}", - hasError, `multiple definition of template`, - }, - { - "eof", + hasError, `multiple definition of template`}, + {"eof", "{{range .X}}", - hasError, `unexpected EOF`, - }, - { - "variable", + hasError, `unexpected EOF`}, + {"variable", // Declare $x so it's defined, to avoid that error, and then check we don't parse a declaration. "{{$x := 23}}{{with $x.y := 3}}{{$x 23}}{{end}}", - hasError, `unexpected ":="`, - }, - { - "multidecl", + hasError, `unexpected ":="`}, + {"multidecl", "{{$a,$b,$c := 23}}", - hasError, `too many declarations`, - }, - { - "undefvar", + hasError, `too many declarations`}, + {"undefvar", "{{$a}}", - hasError, `undefined variable`, - }, - { - "wrongdot", + hasError, `undefined variable`}, + {"wrongdot", "{{true.any}}", - hasError, `unexpected . after term`, - }, - { - "wrongpipeline", + hasError, `unexpected . after term`}, + {"wrongpipeline", "{{12|false}}", - hasError, `non executable command in pipeline`, - }, - { - "emptypipeline", + hasError, `non executable command in pipeline`}, + {"emptypipeline", `{{ ( ) }}`, - hasError, `missing value for parenthesized pipeline`, - }, - { - "multilinerawstring", + hasError, `missing value for parenthesized pipeline`}, + {"multilinerawstring", "{{ $v := `\n` }} {{", - hasError, `multilinerawstring:2: unexpected unclosed action`, - }, - { - "rangeundefvar", + hasError, `multilinerawstring:2: unexpected unclosed action`}, + {"rangeundefvar", "{{range $k}}{{end}}", - hasError, `undefined variable`, - }, - { - "rangeundefvars", + hasError, `undefined variable`}, + {"rangeundefvars", "{{range $k, $v}}{{end}}", - hasError, `undefined variable`, - }, - { - "rangemissingvalue1", + hasError, `undefined variable`}, + {"rangemissingvalue1", "{{range $k,}}{{end}}", - hasError, `missing value for range`, - }, - { - "rangemissingvalue2", + hasError, `missing value for range`}, + {"rangemissingvalue2", "{{range $k, $v := }}{{end}}", - hasError, `missing value for range`, - }, - { - "rangenotvariable1", + hasError, `missing value for range`}, + {"rangenotvariable1", "{{range $k, .}}{{end}}", - hasError, `range can only initialize variables`, - }, - { - "rangenotvariable2", + hasError, `range can only initialize variables`}, + {"rangenotvariable2", "{{range $k, 123 := .}}{{end}}", - hasError, `range can only initialize variables`, - }, + hasError, `range can only initialize variables`}, } func TestErrors(t *testing.T) { diff --git a/tpl/internal/go_templates/texttemplate/template.go b/tpl/internal/go_templates/texttemplate/template.go index 755a8426e..9c6ba6dfc 100644 --- a/tpl/internal/go_templates/texttemplate/template.go +++ b/tpl/internal/go_templates/texttemplate/template.go @@ -5,10 +5,9 @@ package template import ( + "github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate/parse" "reflect" "sync" - - "github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate/parse" ) // common holds the information shared by related templates.