github.com/hairyhenderson/gomplate/v4@v4.0.0-pre-2.0.20240520121557-362f058f0c93/internal/texttemplate/exec_test.go (about)

     1  // Taken and adapted from the stdlib text/template/exec_test.go.
     2  // Copyright 2011 The Go Authors. All rights reserved.
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSE file.
     5  
     6  package texttemplate
     7  
     8  import (
     9  	"bytes"
    10  	"testing"
    11  	gotemplate "text/template"
    12  )
    13  
    14  // T has lots of interesting pieces to use to test execution.
    15  type T struct {
    16  	Tmpl   *gotemplate.Template
    17  	Empty3 any
    18  	S      string
    19  	SI     []int
    20  	SICap  []int
    21  	AI     [3]int
    22  }
    23  
    24  var tVal = &T{
    25  	S:      "xyz",
    26  	SI:     []int{3, 4, 5},
    27  	SICap:  make([]int, 5, 10),
    28  	AI:     [3]int{3, 4, 5},
    29  	Empty3: []int{7, 8},
    30  	Tmpl:   gotemplate.Must(gotemplate.New("").Parse("test template")),
    31  }
    32  
    33  //nolint:govet
    34  type execTest struct {
    35  	name   string
    36  	input  string
    37  	output string
    38  	data   any
    39  	ok     bool
    40  }
    41  
    42  var execTests = []execTest{
    43  	// Slicing.
    44  	{"slice[:]", "{{slice .SI}}", "[3 4 5]", tVal, true},
    45  	{"slice[1:]", "{{slice .SI 1}}", "[4 5]", tVal, true},
    46  	{"slice[1:2]", "{{slice .SI 1 2}}", "[4]", tVal, true},
    47  	{"slice[-1:]", "{{slice .SI -1}}", "", tVal, false},
    48  	{"slice[1:-2]", "{{slice .SI 1 -2}}", "", tVal, false},
    49  	{"slice[1:2:-1]", "{{slice .SI 1 2 -1}}", "", tVal, false},
    50  	{"slice[2:1]", "{{slice .SI 2 1}}", "", tVal, false},
    51  	{"slice[2:2:1]", "{{slice .SI 2 2 1}}", "", tVal, false},
    52  	{"out of range", "{{slice .SI 4 5}}", "", tVal, false},
    53  	{"out of range", "{{slice .SI 2 2 5}}", "", tVal, false},
    54  	{"len(s) < indexes < cap(s)", "{{slice .SICap 6 10}}", "[0 0 0 0]", tVal, true},
    55  	{"len(s) < indexes < cap(s)", "{{slice .SICap 6 10 10}}", "[0 0 0 0]", tVal, true},
    56  	{"indexes > cap(s)", "{{slice .SICap 10 11}}", "", tVal, false},
    57  	{"indexes > cap(s)", "{{slice .SICap 6 10 11}}", "", tVal, false},
    58  	{"array[:]", "{{slice .AI}}", "[3 4 5]", tVal, true},
    59  	{"array[1:]", "{{slice .AI 1}}", "[4 5]", tVal, true},
    60  	{"array[1:2]", "{{slice .AI 1 2}}", "[4]", tVal, true},
    61  	{"string[:]", "{{slice .S}}", "xyz", tVal, true},
    62  	{"string[0:1]", "{{slice .S 0 1}}", "x", tVal, true},
    63  	{"string[1:]", "{{slice .S 1}}", "yz", tVal, true},
    64  	{"string[1:2]", "{{slice .S 1 2}}", "y", tVal, true},
    65  	{"out of range", "{{slice .S 1 5}}", "", tVal, false},
    66  	{"3-index slice of string", "{{slice .S 1 2 2}}", "", tVal, false},
    67  	{"slice of an interface field", "{{slice .Empty3 0 1}}", "[7]", tVal, true},
    68  }
    69  
    70  func testExecute(execTests []execTest, template *gotemplate.Template, t *testing.T) {
    71  	b := new(bytes.Buffer)
    72  	funcs := gotemplate.FuncMap{"slice": GoSlice}
    73  
    74  	for _, test := range execTests {
    75  		var tmpl *gotemplate.Template
    76  		var err error
    77  		if template == nil {
    78  			tmpl, err = gotemplate.New(test.name).Funcs(funcs).Parse(test.input)
    79  		} else {
    80  			tmpl, err = template.New(test.name).Funcs(funcs).Parse(test.input)
    81  		}
    82  		if err != nil {
    83  			t.Errorf("%s: parse error: %s", test.name, err)
    84  			continue
    85  		}
    86  		b.Reset()
    87  		err = tmpl.Execute(b, test.data)
    88  		switch {
    89  		case !test.ok && err == nil:
    90  			t.Errorf("%s: expected error; got none", test.name)
    91  			continue
    92  		case test.ok && err != nil:
    93  			t.Errorf("%s: unexpected execute error: %s", test.name, err)
    94  			continue
    95  		case !test.ok && err != nil:
    96  			// expected error, got one
    97  		}
    98  		result := b.String()
    99  		if result != test.output {
   100  			t.Errorf("%s: expected\n\t%q\ngot\n\t%q", test.name, test.output, result)
   101  		}
   102  	}
   103  }
   104  
   105  func TestExecute(t *testing.T) {
   106  	testExecute(execTests, nil, t)
   107  }