TestIsTest: move ill-formed tests into a testdata subpackage
This avoids triggering the go1.24 vet check for ill-formed
Test (etc) function names.
Fixes golang/go#68999
Change-Id: I60a21e99dd4835f20c3e999a1ee8f29451cf653b
Reviewed-on: https://go-review.googlesource.com/c/playground/+/607835
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/sandbox_test.go b/sandbox_test.go
index 6130936..0beae04 100644
--- a/sandbox_test.go
+++ b/sandbox_test.go
@@ -5,11 +5,8 @@
package main
import (
- "go/token"
- "os"
"os/exec"
"reflect"
- "runtime"
"strings"
"testing"
)
@@ -39,7 +36,9 @@
// TestIsTest verifies that the isTest helper function matches
// exactly (and only) the names of functions recognized as tests.
func TestIsTest(t *testing.T) {
- cmd := exec.Command(os.Args[0], "-test.list=.")
+ // We must disable vet's "tests" analyzer which would otherwise cause
+ // go test to fail due to the intentional problems in testdata/p's tests.
+ cmd := exec.Command("go", "test", "./testdata/p", "-vet=off", "-test.list=.")
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, out)
@@ -49,46 +48,50 @@
isTestFunction := map[string]bool{}
lines := strings.Split(string(out), "\n")
for _, line := range lines {
+ // We want Test/Benchmark/Example/Fuzz functions.
+ // Reject extraneous output such as "ok ...".
+ if line == "" || !strings.Contains("TBEF", line[:1]) {
+ continue
+ }
isTestFunction[strings.TrimSpace(line)] = true
}
for _, tc := range []struct {
prefix string
- f interface{}
+ name string // name of a Test (etc) in ./testdata/p
want bool
}{
- {"Test", Test, true},
- {"Test", TestIsTest, true},
- {"Test", Test1IsATest, true},
- {"Test", TestÑIsATest, true},
+ {"Test", "Test", true},
+ {"Test", "Test1IsATest", true},
+ {"Test", "TestÑIsATest", true},
- {"Test", TestisNotATest, false},
+ {"Test", "TestisNotATest", false},
- {"Example", Example, true},
- {"Example", ExampleTest, true},
- {"Example", Example_isAnExample, true},
- {"Example", ExampleTest_isAnExample, true},
+ {"Example", "Example", true},
+ {"Example", "ExampleTest", true},
+ {"Example", "Example_isAnExample", true},
+ {"Example", "ExampleTest_isAnExample", true},
// Example_noOutput has a valid example function name but lacks an output
// declaration, but the isTest function operates only on the test name
// so it cannot detect that the function is not a test.
- {"Example", Example1IsAnExample, true},
- {"Example", ExampleisNotAnExample, false},
+ {"Example", "Example1IsAnExample", true},
+ {"Example", "ExampleisNotAnExample", false},
- {"Benchmark", Benchmark, true},
- {"Benchmark", BenchmarkNop, true},
- {"Benchmark", Benchmark1IsABenchmark, true},
+ {"Benchmark", "Benchmark", true},
+ {"Benchmark", "BenchmarkNop", true},
+ {"Benchmark", "Benchmark1IsABenchmark", true},
- {"Benchmark", BenchmarkisNotABenchmark, false},
+ {"Benchmark", "BenchmarkisNotABenchmark", false},
- {"Fuzz", Fuzz, true},
- {"Fuzz", Fuzz1IsAFuzz, true},
- {"Fuzz", FuzzÑIsAFuzz, true},
+ {"Fuzz", "Fuzz", true},
+ {"Fuzz", "Fuzz1IsAFuzz", true},
+ {"Fuzz", "FuzzÑIsAFuzz", true},
- {"Fuzz", FuzzisNotAFuzz, false},
+ {"Fuzz", "FuzzisNotAFuzz", false},
} {
- name := nameOf(t, tc.f)
+ name := tc.name
t.Run(name, func(t *testing.T) {
if tc.want != isTestFunction[name] {
t.Fatalf(".want (%v) is inconsistent with -test.list", tc.want)
@@ -104,130 +107,3 @@
})
}
}
-
-// nameOf returns the runtime-reported name of function f.
-func nameOf(t *testing.T, f interface{}) string {
- t.Helper()
-
- v := reflect.ValueOf(f)
- if v.Kind() != reflect.Func {
- t.Fatalf("%v is not a function", f)
- }
-
- rf := runtime.FuncForPC(v.Pointer())
- if rf == nil {
- t.Fatalf("%v.Pointer() is not a known function", f)
- }
-
- fullName := rf.Name()
- parts := strings.Split(fullName, ".")
-
- name := parts[len(parts)-1]
- if !token.IsIdentifier(name) {
- t.Fatalf("%q is not a valid identifier", name)
- }
- return name
-}
-
-// TestisNotATest is not a test function, despite appearances.
-//
-// Please ignore any lint or vet warnings for this function.
-func TestisNotATest(t *testing.T) {
- panic("This is not a valid test function.")
-}
-
-// Test1IsATest is a valid test function.
-func Test1IsATest(t *testing.T) {
-}
-
-// Test is a test with a minimal name.
-func Test(t *testing.T) {
-}
-
-// TestÑIsATest is a test with an interesting Unicode name.
-func TestÑIsATest(t *testing.T) {
-}
-
-func Example() {
- // Output:
-}
-
-func ExampleTest() {
- // This is an example for the function Test.
- // ❤ recursion.
- Test(nil)
-
- // Output:
-}
-
-func Example1IsAnExample() {
- // Output:
-}
-
-// ExampleisNotAnExample is not an example function, despite appearances.
-//
-// Please ignore any lint or vet warnings for this function.
-func ExampleisNotAnExample() {
- panic("This is not a valid example function.")
-
- // Output:
- // None. (This is not really an example function.)
-}
-
-func Example_isAnExample() {
- // Output:
-}
-
-func ExampleTest_isAnExample() {
- Test(nil)
-
- // Output:
-}
-
-func Example_noOutput() {
- // No output declared: should be compiled but not run.
-}
-
-func Benchmark(b *testing.B) {
- for i := 0; i < b.N; i++ {
- }
-}
-
-func BenchmarkNop(b *testing.B) {
- for i := 0; i < b.N; i++ {
- }
-}
-
-func Benchmark1IsABenchmark(b *testing.B) {
- for i := 0; i < b.N; i++ {
- }
-}
-
-// BenchmarkisNotABenchmark is not a benchmark function, despite appearances.
-//
-// Please ignore any lint or vet warnings for this function.
-func BenchmarkisNotABenchmark(b *testing.B) {
- panic("This is not a valid benchmark function.")
-}
-
-// FuzzisNotAFuzz is not a fuzz test function, despite appearances.
-//
-// Please ignore any lint or vet warnings for this function.
-func FuzzisNotAFuzz(f *testing.F) {
- panic("This is not a valid fuzzing function.")
-}
-
-// Fuzz1IsAFuzz is a valid fuzz function.
-func Fuzz1IsAFuzz(f *testing.F) {
- f.Skip()
-}
-
-// Fuzz is a fuzz with a minimal name.
-func Fuzz(f *testing.F) {
- f.Skip()
-}
-
-// FuzzÑIsAFuzz is a fuzz with an interesting Unicode name.
-func FuzzÑIsAFuzz(f *testing.F) {
- f.Skip()
-}
diff --git a/testdata/p/p_test.go b/testdata/p/p_test.go
new file mode 100644
index 0000000..0d0c218
--- /dev/null
+++ b/testdata/p/p_test.go
@@ -0,0 +1,112 @@
+package p_test
+
+// This file defines various Test, Benchmark, Example, and Fuzz
+// functions for use by TestIsTest in sandbox_test.go. Some are
+// ill-formed and will fail go vet's static checks, would fail at
+// runtime if executed by go test, or would not be recognized as tests
+// by either tool.
+
+import "testing"
+
+// TestisNotATest is not a test function, despite appearances.
+//
+// Please ignore any lint or vet warnings for this function.
+func TestisNotATest(t *testing.T) {
+ panic("This is not a valid test function.")
+}
+
+// Test1IsATest is a valid test function.
+func Test1IsATest(t *testing.T) {
+}
+
+// Test is a test with a minimal name.
+func Test(t *testing.T) {
+}
+
+// TestÑIsATest is a test with an interesting Unicode name.
+func TestÑIsATest(t *testing.T) {
+}
+
+func Example() {
+ // Output:
+}
+
+func ExampleTest() {
+ // This is an example for the function Test.
+ // ❤ recursion.
+ Test(nil)
+
+ // Output:
+}
+
+func Example1IsAnExample() {
+ // Output:
+}
+
+// ExampleisNotAnExample is not an example function, despite appearances.
+//
+// Please ignore any lint or vet warnings for this function.
+func ExampleisNotAnExample() {
+ panic("This is not a valid example function.")
+
+ // Output:
+ // None. (This is not really an example function.)
+}
+
+func Example_isAnExample() {
+ // Output:
+}
+
+func ExampleTest_isAnExample() {
+ Test(nil)
+
+ // Output:
+}
+
+func Example_noOutput() {
+ // No output declared: should be compiled but not run.
+}
+
+func Benchmark(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ }
+}
+
+func BenchmarkNop(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ }
+}
+
+func Benchmark1IsABenchmark(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ }
+}
+
+// BenchmarkisNotABenchmark is not a benchmark function, despite appearances.
+//
+// Please ignore any lint or vet warnings for this function.
+func BenchmarkisNotABenchmark(b *testing.B) {
+ panic("This is not a valid benchmark function.")
+}
+
+// FuzzisNotAFuzz is not a fuzz test function, despite appearances.
+//
+// Please ignore any lint or vet warnings for this function.
+func FuzzisNotAFuzz(f *testing.F) {
+ panic("This is not a valid fuzzing function.")
+}
+
+// Fuzz1IsAFuzz is a valid fuzz function.
+func Fuzz1IsAFuzz(f *testing.F) {
+ f.Skip()
+}
+
+// Fuzz is a fuzz with a minimal name.
+func Fuzz(f *testing.F) {
+ f.Skip()
+}
+
+// FuzzÑIsAFuzz is a fuzz with an interesting Unicode name.
+func FuzzÑIsAFuzz(f *testing.F) {
+ f.Skip()
+}