Commit c2d3e112 authored by Caio Marcelo de Oliveira Filho's avatar Caio Marcelo de Oliveira Filho Committed by Brad Fitzpatrick

cmd/go: better error for test functions with wrong signature

Check the function types before compiling the tests. Extend the same
approach taken by the type check used for TestMain function.

To keep existing behavior, wrong arguments for TestMain are ignored
instead of causing an error.

Fixes #14226.

Change-Id: I488a2555cddb273d35c1a8c4645bb5435c9eb91d
Reviewed-on: https://go-review.googlesource.com/19763
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent e1035c5e
...@@ -1206,11 +1206,11 @@ func (b *builder) notest(a *action) error { ...@@ -1206,11 +1206,11 @@ func (b *builder) notest(a *action) error {
return nil return nil
} }
// isTestMain tells whether fn is a TestMain(m *testing.M) function. // isTestFunc tells whether fn has the type of a testing function. arg
func isTestMain(fn *ast.FuncDecl) bool { // specifies the parameter type we look for: B, M or T.
if fn.Name.String() != "TestMain" || func isTestFunc(fn *ast.FuncDecl, arg string) bool {
fn.Type.Results != nil && len(fn.Type.Results.List) > 0 || if fn.Type.Results != nil && len(fn.Type.Results.List) > 0 ||
fn.Type.Params == nil || fn.Type.Params.List == nil ||
len(fn.Type.Params.List) != 1 || len(fn.Type.Params.List) != 1 ||
len(fn.Type.Params.List[0].Names) > 1 { len(fn.Type.Params.List[0].Names) > 1 {
return false return false
...@@ -1222,10 +1222,11 @@ func isTestMain(fn *ast.FuncDecl) bool { ...@@ -1222,10 +1222,11 @@ func isTestMain(fn *ast.FuncDecl) bool {
// We can't easily check that the type is *testing.M // We can't easily check that the type is *testing.M
// because we don't know how testing has been imported, // because we don't know how testing has been imported,
// but at least check that it's *M or *something.M. // but at least check that it's *M or *something.M.
if name, ok := ptr.X.(*ast.Ident); ok && name.Name == "M" { // Same applies for B and T.
if name, ok := ptr.X.(*ast.Ident); ok && name.Name == arg {
return true return true
} }
if sel, ok := ptr.X.(*ast.SelectorExpr); ok && sel.Sel.Name == "M" { if sel, ok := ptr.X.(*ast.SelectorExpr); ok && sel.Sel.Name == arg {
return true return true
} }
return false return false
...@@ -1344,16 +1345,22 @@ func (t *testFuncs) load(filename, pkg string, doImport, seen *bool) error { ...@@ -1344,16 +1345,22 @@ func (t *testFuncs) load(filename, pkg string, doImport, seen *bool) error {
} }
name := n.Name.String() name := n.Name.String()
switch { switch {
case isTestMain(n): case name == "TestMain" && isTestFunc(n, "M"):
if t.TestMain != nil { if t.TestMain != nil {
return errors.New("multiple definitions of TestMain") return errors.New("multiple definitions of TestMain")
} }
t.TestMain = &testFunc{pkg, name, ""} t.TestMain = &testFunc{pkg, name, ""}
*doImport, *seen = true, true *doImport, *seen = true, true
case isTest(name, "Test"): case isTest(name, "Test"):
if !isTestFunc(n, "T") {
return fmt.Errorf("wrong type for %s", name)
}
t.Tests = append(t.Tests, testFunc{pkg, name, ""}) t.Tests = append(t.Tests, testFunc{pkg, name, ""})
*doImport, *seen = true, true *doImport, *seen = true, true
case isTest(name, "Benchmark"): case isTest(name, "Benchmark"):
if !isTestFunc(n, "B") {
return fmt.Errorf("wrong type for %s", name)
}
t.Benchmarks = append(t.Benchmarks, testFunc{pkg, name, ""}) t.Benchmarks = append(t.Benchmarks, testFunc{pkg, name, ""})
*doImport, *seen = true, true *doImport, *seen = true, true
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment