Skip to content

Commit

Permalink
feat: support subtest builder as anonymous function and fixture method
Browse files Browse the repository at this point in the history
  • Loading branch information
kulti committed Dec 15, 2021
1 parent 76bbd21 commit f64c636
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 10 deletions.
66 changes: 58 additions & 8 deletions pkg/analyzer/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,23 +406,38 @@ func unwrapTestingFunctionBuilding(pass *analysis.Pass, expr ast.Expr, testFuncT
return nil
}

funIdent, ok := callExpr.Fun.(*ast.Ident)
if !ok {
return nil
}
var funcDecl funcDecl
switch f := callExpr.Fun.(type) {
case *ast.FuncLit:
funcDecl.Body = f.Body
funcDecl.Type = f.Type
case *ast.Ident:
funObjDecl, ok := f.Obj.Decl.(*ast.FuncDecl)
if !ok {
return nil
}

funDecl, ok := funIdent.Obj.Decl.(*ast.FuncDecl)
if !ok {
funcDecl.Body = funObjDecl.Body
funcDecl.Type = funObjDecl.Type
case *ast.SelectorExpr:
fd := findSelectroDeclaration(pass, f)
if fd == nil {
return nil
}

funcDecl.Body = fd.Body
funcDecl.Type = fd.Type
default:
return nil
}

results := funDecl.Type.Results.List
results := funcDecl.Type.Results.List
if len(results) != 1 || !isExprHasType(pass, results[0].Type, testFuncType) {
return nil
}

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

return types.Identical(typeInfo.Type, expType)
}

// findSelectroDeclaration returns function declaration called by selectro expression.
func findSelectroDeclaration(pass *analysis.Pass, expr *ast.SelectorExpr) *ast.FuncDecl {
xsel, ok := pass.TypesInfo.Selections[expr]
if !ok {
return nil
}

for _, file := range pass.Files {
for _, decl := range file.Decls {
fd, ok := decl.(*ast.FuncDecl)
if ok && fd.Recv != nil && len(fd.Recv.List) == 1 {
recvType, ok := fd.Recv.List[0].Type.(*ast.Ident)
if !ok {
continue
}

recvObj, ok := pass.TypesInfo.Uses[recvType]
if !ok {
continue
}

if !(types.Identical(recvObj.Type(), xsel.Recv())) {
continue
}

if fd.Name.Name == expr.Sel.Name {
return fd
}
}
}
}

return nil
}
14 changes: 12 additions & 2 deletions pkg/analyzer/testdata/src/t/s.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ func (sh subhelper) check(t *testing.T) {
func (sh subhelper) anotherCheck(t *testing.T) {} // want "test helper function should start from t.Helper()"

func TestSubtestWithBuilder(t *testing.T) {
t.Run("sub", subtestBuilder("first"))
t.Run("sub", subtestBuilder("second"))
t.Run("sub1", subtestBuilder("first"))
t.Run("sub2", subtestBuilder("second"))
t.Run("anon", func() func(t *testing.T) { return func(t *testing.T) {} }())

fixture := subtestFixture{}
t.Run("sel", fixture.subtest())
}

func subtestBuilder(name string) func(t *testing.T) {
Expand All @@ -44,3 +48,9 @@ func subtestBuilder(name string) func(t *testing.T) {
}
return func(t *testing.T) {}
}

type subtestFixture struct{}

func (f subtestFixture) subtest() func(t *testing.T) {
return func(t *testing.T) {}
}

0 comments on commit f64c636

Please sign in to comment.