Skip to content

Commit

Permalink
Fix bug: false positive warning for typed function calls
Browse files Browse the repository at this point in the history
When calling a function that return a type in the async
assertion (eventually/constantly) body, if this type is a function, the
linter fiels to recognize it and fire a warning.

This PR fixes this bug, by checking the underline types.
  • Loading branch information
nunnatsa committed Jun 27, 2023
1 parent afbbe92 commit f095b68
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
17 changes: 13 additions & 4 deletions ginkgo_linter.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,10 +333,7 @@ func checkAsyncAssertion(pass *analysis.Pass, config types.Config, expr *ast.Cal
if len(actualExpr.Args) > funcIndex {
if fun, funcCall := actualExpr.Args[funcIndex].(*ast.CallExpr); funcCall {
t = pass.TypesInfo.TypeOf(fun)
switch t.(type) {
// allow functions that return function or channel.
case *gotypes.Signature, *gotypes.Chan, *gotypes.Pointer:
default:
if !isValidAsyncValueType(t) {
actualExpr = handler.GetActualExpr(expr.Fun.(*ast.SelectorExpr))

if len(fun.Args) > 0 {
Expand Down Expand Up @@ -371,6 +368,18 @@ func checkAsyncAssertion(pass *analysis.Pass, config types.Config, expr *ast.Cal
return true
}

func isValidAsyncValueType(t gotypes.Type) bool {
switch t.(type) {
// allow functions that return function or channel.
case *gotypes.Signature, *gotypes.Chan, *gotypes.Pointer:
return true
case *gotypes.Named:
return isValidAsyncValueType(t.Underlying())
}

return false
}

func startCheckComparison(exp *ast.CallExpr, handler gomegahandler.Handler) (*ast.CallExpr, bool) {
matcher, ok := exp.Args[0].(*ast.CallExpr)
if !ok {
Expand Down
12 changes: 12 additions & 0 deletions testdata/src/a/eventually/eventuallyFunc.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ import (
. "github.com/onsi/gomega"
)

type GetFunc[T any] func(ctx context.Context) (T, error)

func retFuncType() GetFunc[int] {
return func(_ context.Context) (int, error) {
return 1, nil
}
}

func slowInt() int {
time.Sleep(time.Second)
return 42
Expand Down Expand Up @@ -46,6 +54,10 @@ func retChan() chan int {

var _ = Describe("Eventually with function", func() {
Context("Eventually", func() {
It("should not trigger warning", func() {
Eventually(retFuncType()).Should(Equal(1))
})

Eventually(retFunc(5)).Should(Equal(5)) // valid. retFunc returns a function
ch := make(chan int)
Eventually(ch).Should(BeClosed()) // valid
Expand Down

0 comments on commit f095b68

Please sign in to comment.