Skip to content

Commit 6d27bba

Browse files
committed
gopls/internal/golang: add testcase handling for func with error returns
This commit improves the handling of test cases for functions that return an error as their last return value. - A boolean field called "wantErr" is added to the test case struct to indicate whether an error is expected. - The error return value is now handled before comparing other return values, ensuring correct error handling in test cases. For golang/vscode-go#1594 Change-Id: Ib48f6b85b2fdad96cb7fb563b8bdbf17d692f569 Reviewed-on: https://go-review.googlesource.com/c/tools/+/623997 Reviewed-by: Robert Findley <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent e5417d7 commit 6d27bba

File tree

2 files changed

+134
-13
lines changed

2 files changed

+134
-13
lines changed

gopls/internal/golang/addtest.go

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const testTmplString = `func {{.TestFuncName}}(t *testing.T) {
3737
{{- end}}
3838
}
3939
{{- end}}
40+
4041
{{- /* Test cases struct declaration and empty initialization. */}}
4142
tests := []struct {
4243
name string // description of this test case
@@ -47,12 +48,18 @@ const testTmplString = `func {{.TestFuncName}}(t *testing.T) {
4748
arg {{(index .Args 0).Type}}
4849
{{- end}}
4950
{{- range $index, $res := .Results}}
50-
{{if eq $index 0}}want{{else}}want{{add $index 1}}{{end}} {{$res.Type}}
51-
{{- /* TODO(hxjiang): check whether the last return type is error and handle it using field "wantErr". */}}
51+
{{- if eq $res.Name "gotErr"}}
52+
wantErr bool
53+
{{- else if eq $index 0}}
54+
want {{$res.Type}}
55+
{{- else}}
56+
want{{add $index 1}} {{$res.Type}}
57+
{{- end}}
5258
{{- end}}
5359
}{
5460
// TODO: Add test cases.
5561
}
62+
5663
{{- /* Loop over all the test cases. */}}
5764
for _, tt := range tests {
5865
{{/* Got variables. */}}
@@ -66,14 +73,31 @@ const testTmplString = `func {{.TestFuncName}}(t *testing.T) {
6673
{{- /* Input parameters. */ -}}
6774
({{if eq (len .Args) 1}}tt.arg{{end}}{{if gt (len .Args) 1}}{{fieldNames .Args "tt.args."}}{{end}})
6875
69-
{{- if .Results}}
76+
{{- /* Handles the returned error before the rest of return value. */}}
77+
{{- $last := index .Results (add (len .Results) -1)}}
78+
{{- if eq $last.Name "gotErr"}}
79+
if gotErr != nil {
80+
if !tt.wantErr {
81+
t.Errorf("%s: {{$.FuncName}}() failed: %v", tt.name, gotErr)
82+
}
83+
return
84+
}
85+
if tt.wantErr {
86+
t.Fatalf("%s: {{$.FuncName}}() succeeded unexpectedly", tt.name)
87+
}
88+
{{- end}}
89+
90+
{{- /* Compare the returned values except for the last returned error. */}}
91+
{{- if or (and .Results (ne $last.Name "gotErr")) (and (gt (len .Results) 1) (eq $last.Name "gotErr"))}}
7092
// TODO: update the condition below to compare got with tt.want.
7193
{{- range $index, $res := .Results}}
94+
{{- if ne $res.Name "gotErr"}}
7295
if true {
7396
t.Errorf("%s: {{$.FuncName}}() = %v, want %v", tt.name, {{.Name}}, tt.{{if eq $index 0}}want{{else}}want{{add $index 1}}{{end}})
7497
}
7598
{{- end}}
7699
{{- end}}
100+
{{- end}}
77101
}
78102
}
79103
`
@@ -306,18 +330,18 @@ func AddTestForFunc(ctx context.Context, snapshot *cache.Snapshot, loc protocol.
306330
}
307331
}
308332

333+
errorType := types.Universe.Lookup("error").Type()
309334
for i := range sig.Results().Len() {
310-
if i == 0 {
311-
data.Results = append(data.Results, field{
312-
Name: "got",
313-
Type: types.TypeString(sig.Results().At(i).Type(), qf),
314-
})
315-
} else {
316-
data.Results = append(data.Results, field{
317-
Name: fmt.Sprintf("got%d", i+1),
318-
Type: types.TypeString(sig.Results().At(i).Type(), qf),
319-
})
335+
name := "got"
336+
if i == sig.Results().Len()-1 && types.Identical(sig.Results().At(i).Type(), errorType) {
337+
name = "gotErr"
338+
} else if i > 0 {
339+
name = fmt.Sprintf("got%d", i+1)
320340
}
341+
data.Results = append(data.Results, field{
342+
Name: name,
343+
Type: types.TypeString(sig.Results().At(i).Type(), qf),
344+
})
321345
}
322346

323347
var test bytes.Buffer

gopls/internal/test/marker/testdata/codeaction/addtest.txt

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,3 +473,100 @@ var fooNode = yourast.Node{}
473473
+ }
474474
+ }
475475
+}
476+
-- returnwitherror/returnwitherror.go --
477+
package main
478+
479+
func OnlyErr() error {return nil} //@codeactionedit("OnlyErr", "source.addTest", return_only_error)
480+
func StringErr() (string, error) {return "", nil} //@codeactionedit("StringErr", "source.addTest", return_string_error)
481+
func MultipleStringErr() (string, string, string, error) {return "", "", "", nil} //@codeactionedit("MultipleStringErr", "source.addTest", return_multiple_string_error)
482+
483+
-- @return_only_error/returnwitherror/returnwitherror_test.go --
484+
@@ -0,0 +1,22 @@
485+
+package main_test
486+
+
487+
+func TestOnlyErr(t *testing.T) {
488+
+ tests := []struct {
489+
+ name string // description of this test case
490+
+ wantErr bool
491+
+ }{
492+
+ // TODO: Add test cases.
493+
+ }
494+
+ for _, tt := range tests {
495+
+ gotErr := main.OnlyErr()
496+
+ if gotErr != nil {
497+
+ if !tt.wantErr {
498+
+ t.Errorf("%s: OnlyErr() failed: %v", tt.name, gotErr)
499+
+ }
500+
+ return
501+
+ }
502+
+ if tt.wantErr {
503+
+ t.Fatalf("%s: OnlyErr() succeeded unexpectedly", tt.name)
504+
+ }
505+
+ }
506+
+}
507+
-- @return_string_error/returnwitherror/returnwitherror_test.go --
508+
@@ -0,0 +1,27 @@
509+
+package main_test
510+
+
511+
+func TestStringErr(t *testing.T) {
512+
+ tests := []struct {
513+
+ name string // description of this test case
514+
+ want string
515+
+ wantErr bool
516+
+ }{
517+
+ // TODO: Add test cases.
518+
+ }
519+
+ for _, tt := range tests {
520+
+ got, gotErr := main.StringErr()
521+
+ if gotErr != nil {
522+
+ if !tt.wantErr {
523+
+ t.Errorf("%s: StringErr() failed: %v", tt.name, gotErr)
524+
+ }
525+
+ return
526+
+ }
527+
+ if tt.wantErr {
528+
+ t.Fatalf("%s: StringErr() succeeded unexpectedly", tt.name)
529+
+ }
530+
+ // TODO: update the condition below to compare got with tt.want.
531+
+ if true {
532+
+ t.Errorf("%s: StringErr() = %v, want %v", tt.name, got, tt.want)
533+
+ }
534+
+ }
535+
+}
536+
-- @return_multiple_string_error/returnwitherror/returnwitherror_test.go --
537+
@@ -0,0 +1,35 @@
538+
+package main_test
539+
+
540+
+func TestMultipleStringErr(t *testing.T) {
541+
+ tests := []struct {
542+
+ name string // description of this test case
543+
+ want string
544+
+ want2 string
545+
+ want3 string
546+
+ wantErr bool
547+
+ }{
548+
+ // TODO: Add test cases.
549+
+ }
550+
+ for _, tt := range tests {
551+
+ got, got2, got3, gotErr := main.MultipleStringErr()
552+
+ if gotErr != nil {
553+
+ if !tt.wantErr {
554+
+ t.Errorf("%s: MultipleStringErr() failed: %v", tt.name, gotErr)
555+
+ }
556+
+ return
557+
+ }
558+
+ if tt.wantErr {
559+
+ t.Fatalf("%s: MultipleStringErr() succeeded unexpectedly", tt.name)
560+
+ }
561+
+ // TODO: update the condition below to compare got with tt.want.
562+
+ if true {
563+
+ t.Errorf("%s: MultipleStringErr() = %v, want %v", tt.name, got, tt.want)
564+
+ }
565+
+ if true {
566+
+ t.Errorf("%s: MultipleStringErr() = %v, want %v", tt.name, got2, tt.want2)
567+
+ }
568+
+ if true {
569+
+ t.Errorf("%s: MultipleStringErr() = %v, want %v", tt.name, got3, tt.want3)
570+
+ }
571+
+ }
572+
+}

0 commit comments

Comments
 (0)