Skip to content

Commit f64c636

Browse files
committed
feat: support subtest builder as anonymous function and fixture method
1 parent 76bbd21 commit f64c636

File tree

2 files changed

+70
-10
lines changed

2 files changed

+70
-10
lines changed

pkg/analyzer/analyzer.go

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -406,23 +406,38 @@ func unwrapTestingFunctionBuilding(pass *analysis.Pass, expr ast.Expr, testFuncT
406406
return nil
407407
}
408408

409-
funIdent, ok := callExpr.Fun.(*ast.Ident)
410-
if !ok {
411-
return nil
412-
}
409+
var funcDecl funcDecl
410+
switch f := callExpr.Fun.(type) {
411+
case *ast.FuncLit:
412+
funcDecl.Body = f.Body
413+
funcDecl.Type = f.Type
414+
case *ast.Ident:
415+
funObjDecl, ok := f.Obj.Decl.(*ast.FuncDecl)
416+
if !ok {
417+
return nil
418+
}
413419

414-
funDecl, ok := funIdent.Obj.Decl.(*ast.FuncDecl)
415-
if !ok {
420+
funcDecl.Body = funObjDecl.Body
421+
funcDecl.Type = funObjDecl.Type
422+
case *ast.SelectorExpr:
423+
fd := findSelectroDeclaration(pass, f)
424+
if fd == nil {
425+
return nil
426+
}
427+
428+
funcDecl.Body = fd.Body
429+
funcDecl.Type = fd.Type
430+
default:
416431
return nil
417432
}
418433

419-
results := funDecl.Type.Results.List
434+
results := funcDecl.Type.Results.List
420435
if len(results) != 1 || !isExprHasType(pass, results[0].Type, testFuncType) {
421436
return nil
422437
}
423438

424439
var funcs []ast.Expr
425-
ast.Inspect(funDecl.Body, func(n ast.Node) bool {
440+
ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
426441
if n == nil {
427442
return false
428443
}
@@ -483,3 +498,38 @@ func isExprHasType(pass *analysis.Pass, expr ast.Expr, expType types.Type) bool
483498

484499
return types.Identical(typeInfo.Type, expType)
485500
}
501+
502+
// findSelectroDeclaration returns function declaration called by selectro expression.
503+
func findSelectroDeclaration(pass *analysis.Pass, expr *ast.SelectorExpr) *ast.FuncDecl {
504+
xsel, ok := pass.TypesInfo.Selections[expr]
505+
if !ok {
506+
return nil
507+
}
508+
509+
for _, file := range pass.Files {
510+
for _, decl := range file.Decls {
511+
fd, ok := decl.(*ast.FuncDecl)
512+
if ok && fd.Recv != nil && len(fd.Recv.List) == 1 {
513+
recvType, ok := fd.Recv.List[0].Type.(*ast.Ident)
514+
if !ok {
515+
continue
516+
}
517+
518+
recvObj, ok := pass.TypesInfo.Uses[recvType]
519+
if !ok {
520+
continue
521+
}
522+
523+
if !(types.Identical(recvObj.Type(), xsel.Recv())) {
524+
continue
525+
}
526+
527+
if fd.Name.Name == expr.Sel.Name {
528+
return fd
529+
}
530+
}
531+
}
532+
}
533+
534+
return nil
535+
}

pkg/analyzer/testdata/src/t/s.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,12 @@ func (sh subhelper) check(t *testing.T) {
3434
func (sh subhelper) anotherCheck(t *testing.T) {} // want "test helper function should start from t.Helper()"
3535

3636
func TestSubtestWithBuilder(t *testing.T) {
37-
t.Run("sub", subtestBuilder("first"))
38-
t.Run("sub", subtestBuilder("second"))
37+
t.Run("sub1", subtestBuilder("first"))
38+
t.Run("sub2", subtestBuilder("second"))
39+
t.Run("anon", func() func(t *testing.T) { return func(t *testing.T) {} }())
40+
41+
fixture := subtestFixture{}
42+
t.Run("sel", fixture.subtest())
3943
}
4044

4145
func subtestBuilder(name string) func(t *testing.T) {
@@ -44,3 +48,9 @@ func subtestBuilder(name string) func(t *testing.T) {
4448
}
4549
return func(t *testing.T) {}
4650
}
51+
52+
type subtestFixture struct{}
53+
54+
func (f subtestFixture) subtest() func(t *testing.T) {
55+
return func(t *testing.T) {}
56+
}

0 commit comments

Comments
 (0)