Skip to content

Commit

Permalink
Allow *testing.T as first parameter for context parameter check
Browse files Browse the repository at this point in the history
  • Loading branch information
posener authored and euank committed Oct 22, 2021
1 parent 8a3653c commit 9a452fb
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
10 changes: 9 additions & 1 deletion rule/context-as-argument.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,15 @@ func (w lintContextArguments) Visit(n ast.Node) ast.Visitor {
// A context.Context should be the first parameter of a function.
// Flag any that show up after the first.
previousArgIsCtx := isPkgDot(fn.Type.Params.List[0].Type, "context", "Context")
for _, arg := range fn.Type.Params.List[1:] {
// In case that the first parameter is *testing.T, we don't want
// to fail the linter. For example:
// func testContext(t *testint.T, ctx context.Context)
firstArgIsTestingT := isPtrPkgDot(fn.Type.Params.List[0].Type, "testing", "T")
remArgs := fn.Type.Params.List[1:]
if firstArgIsTestingT && len(fn.Type.Params.List) > 1 {
remArgs = fn.Type.Params.List[2:]
}
for _, arg := range remArgs {
argIsCtx := isPkgDot(arg.Type, "context", "Context")
if argIsCtx && !previousArgIsCtx {
w.onFailure(lint.Failure{
Expand Down
7 changes: 7 additions & 0 deletions rule/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,18 @@ func validType(T types.Type) bool {
!strings.Contains(T.String(), "invalid type") // good but not foolproof
}

// isPkgDot checks if the expression is <pkg>.<name>
func isPkgDot(expr ast.Expr, pkg, name string) bool {
sel, ok := expr.(*ast.SelectorExpr)
return ok && isIdent(sel.X, pkg) && isIdent(sel.Sel, name)
}

// isPtrPkgDot checks if the expression is *<pkg>.<name>.
func isPtrPkgDot(expr ast.Expr, pkg, name string) bool {
star, ok := expr.(*ast.StarExpr)
return ok && isPkgDot(star.X, pkg, name)
}

func srcLine(src []byte, p token.Position) string {
// Run to end of line in both directions if not at line start/end.
lo, hi := p.Offset, p.Offset+1
Expand Down
5 changes: 5 additions & 0 deletions testdata/golint/context-as-argument.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package foo

import (
"context"
"testing"
)

// A proper context.Context location
Expand All @@ -15,6 +16,10 @@ func x(ctx context.Context) { // ok
func x(ctx context.Context, s string) { // ok
}

// A test helper function with context object allowes context to be not the first argument.
func x(t *testing.T, ctx context.Context) { // ok
}

// An invalid context.Context location
func y(s string, ctx context.Context) { // MATCH /context.Context should be the first parameter of a function/
}
Expand Down

0 comments on commit 9a452fb

Please sign in to comment.