diff options
| author | Zxilly <zhouxinyu1001@gmail.com> | 2024-03-12 10:36:15 +0000 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2024-05-24 21:22:24 +0000 |
| commit | c506f035d99153accf7a9b322c6596fc7652aea6 (patch) | |
| tree | 62f84af72b45c340a7102d5a5856692f45e12c46 /src/text/template/exec_test.go | |
| parent | b89f946c8814b3d984f06cd836c74ef95bc0b868 (diff) | |
| download | go-c506f035d99153accf7a9b322c6596fc7652aea6.tar.xz | |
text/template: add detailed info for goodFunc check
goodFunc now returns a error describe the exact error it met.
builtin call function can print the name of the callee function
if the goodFunc check failed.
For input {{call .InvalidReturnCountFunc}}
before:
can't evaluate field InvalidReturnTypeFunc in type *template.T
after:
invalid function signature for .InvalidReturnTypeFunc: second argument should be error; is bool
Change-Id: I9aa53424ac9a2bffbdbeac889390f41218817575
GitHub-Last-Rev: 7c1e0dbd08884a38d92a42530104884a9ca52b44
GitHub-Pull-Request: golang/go#65509
Reviewed-on: https://go-review.googlesource.com/c/go/+/561115
Reviewed-by: Rob Pike <r@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Commit-Queue: Ian Lance Taylor <iant@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Diffstat (limited to 'src/text/template/exec_test.go')
| -rw-r--r-- | src/text/template/exec_test.go | 84 |
1 files changed, 78 insertions, 6 deletions
diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go index 8fdd9280f2..4ec213d8cf 100644 --- a/src/text/template/exec_test.go +++ b/src/text/template/exec_test.go @@ -75,12 +75,14 @@ type T struct { PSI *[]int NIL *int // Function (not method) - BinaryFunc func(string, string) string - VariadicFunc func(...string) string - VariadicFuncInt func(int, ...string) string - NilOKFunc func(*int) bool - ErrFunc func() (string, error) - PanicFunc func() string + BinaryFunc func(string, string) string + VariadicFunc func(...string) string + VariadicFuncInt func(int, ...string) string + NilOKFunc func(*int) bool + ErrFunc func() (string, error) + PanicFunc func() string + InvalidReturnCountFunc func() (string, error, int) + InvalidReturnTypeFunc func() (string, bool) // Template to test evaluation of templates. Tmpl *Template // Unexported field; cannot be accessed by template. @@ -168,6 +170,8 @@ var tVal = &T{ NilOKFunc: func(s *int) bool { return s == nil }, ErrFunc: func() (string, error) { return "bla", nil }, PanicFunc: func() string { panic("test panic") }, + InvalidReturnCountFunc: func() (string, error, int) { return "", nil, 0 }, + InvalidReturnTypeFunc: func() (string, bool) { return "", false }, Tmpl: Must(New("x").Parse("test template")), // "x" is the value of .X } @@ -1711,6 +1715,74 @@ func TestExecutePanicDuringCall(t *testing.T) { } } +func TestFunctionCheckDuringCall(t *testing.T) { + tests := []struct { + name string + input string + data any + wantErr string + }{{ + name: "call nothing", + input: `{{call}}`, + data: tVal, + wantErr: "wrong number of args for call: want at least 1 got 0", + }, + { + name: "call non-function", + input: "{{call .True}}", + data: tVal, + wantErr: "error calling call: non-function .True of type bool", + }, + { + name: "call func with wrong argument", + input: "{{call .BinaryFunc 1}}", + data: tVal, + wantErr: "error calling call: wrong number of args for .BinaryFunc: got 1 want 2", + }, + { + name: "call variadic func with wrong argument", + input: `{{call .VariadicFuncInt}}`, + data: tVal, + wantErr: "error calling call: wrong number of args for .VariadicFuncInt: got 0 want at least 1", + }, + { + name: "call invalid return number func", + input: `{{call .InvalidReturnCountFunc}}`, + data: tVal, + wantErr: "error calling call: too many return values for .InvalidReturnCountFunc", + }, + { + name: "call invalid return type func", + input: `{{call .InvalidReturnTypeFunc}}`, + data: tVal, + wantErr: "error calling call: invalid function signature for .InvalidReturnTypeFunc: second argument should be error; is bool", + }, + { + name: "call pipeline", + input: `{{call (len "test")}}`, + data: nil, + wantErr: "error calling call: non-function len \"test\" of type int", + }, + } + + for _, tc := range tests { + b := new(bytes.Buffer) + tmpl, err := New("t").Parse(tc.input) + if err != nil { + t.Fatalf("parse error: %s", err) + } + err = tmpl.Execute(b, tc.data) + if err == nil { + t.Errorf("%s: expected error; got none", tc.name) + } else if tc.wantErr == "" || !strings.Contains(err.Error(), tc.wantErr) { + if *debug { + fmt.Printf("%s: test execute error: %s\n", tc.name, err) + } + t.Errorf("%s: expected error:\n%s\ngot:\n%s", tc.name, tc.wantErr, err) + } + } +} + // Issue 31810. Check that a parenthesized first argument behaves properly. func TestIssue31810(t *testing.T) { // A simple value with no arguments is fine. |
