golang.org/x/playground@v0.0.0-20230418134305-14ebe15bcd59/sandbox_test.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "go/token" 9 "os" 10 "os/exec" 11 "reflect" 12 "runtime" 13 "strings" 14 "testing" 15 ) 16 17 // TestIsTest verifies that the isTest helper function matches 18 // exactly (and only) the names of functions recognized as tests. 19 func TestIsTest(t *testing.T) { 20 cmd := exec.Command(os.Args[0], "-test.list=.") 21 out, err := cmd.CombinedOutput() 22 if err != nil { 23 t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, out) 24 } 25 t.Logf("%s:\n%s", strings.Join(cmd.Args, " "), out) 26 27 isTestFunction := map[string]bool{} 28 lines := strings.Split(string(out), "\n") 29 for _, line := range lines { 30 isTestFunction[strings.TrimSpace(line)] = true 31 } 32 33 for _, tc := range []struct { 34 prefix string 35 f interface{} 36 want bool 37 }{ 38 {"Test", Test, true}, 39 {"Test", TestIsTest, true}, 40 {"Test", Test1IsATest, true}, 41 {"Test", TestÑIsATest, true}, 42 43 {"Test", TestisNotATest, false}, 44 45 {"Example", Example, true}, 46 {"Example", ExampleTest, true}, 47 {"Example", Example_isAnExample, true}, 48 {"Example", ExampleTest_isAnExample, true}, 49 50 // Example_noOutput has a valid example function name but lacks an output 51 // declaration, but the isTest function operates only on the test name 52 // so it cannot detect that the function is not a test. 53 54 {"Example", Example1IsAnExample, true}, 55 {"Example", ExampleisNotAnExample, false}, 56 57 {"Benchmark", Benchmark, true}, 58 {"Benchmark", BenchmarkNop, true}, 59 {"Benchmark", Benchmark1IsABenchmark, true}, 60 61 {"Benchmark", BenchmarkisNotABenchmark, false}, 62 63 {"Fuzz", Fuzz, true}, 64 {"Fuzz", Fuzz1IsAFuzz, true}, 65 {"Fuzz", FuzzÑIsAFuzz, true}, 66 67 {"Fuzz", FuzzisNotAFuzz, false}, 68 } { 69 name := nameOf(t, tc.f) 70 t.Run(name, func(t *testing.T) { 71 if tc.want != isTestFunction[name] { 72 t.Fatalf(".want (%v) is inconsistent with -test.list", tc.want) 73 } 74 if !strings.HasPrefix(name, tc.prefix) { 75 t.Fatalf("%q is not a prefix of %v", tc.prefix, name) 76 } 77 78 got := isTest(name, tc.prefix) 79 if got != tc.want { 80 t.Errorf(`isTest(%q, %q) = %v; want %v`, name, tc.prefix, got, tc.want) 81 } 82 }) 83 } 84 } 85 86 // nameOf returns the runtime-reported name of function f. 87 func nameOf(t *testing.T, f interface{}) string { 88 t.Helper() 89 90 v := reflect.ValueOf(f) 91 if v.Kind() != reflect.Func { 92 t.Fatalf("%v is not a function", f) 93 } 94 95 rf := runtime.FuncForPC(v.Pointer()) 96 if rf == nil { 97 t.Fatalf("%v.Pointer() is not a known function", f) 98 } 99 100 fullName := rf.Name() 101 parts := strings.Split(fullName, ".") 102 103 name := parts[len(parts)-1] 104 if !token.IsIdentifier(name) { 105 t.Fatalf("%q is not a valid identifier", name) 106 } 107 return name 108 } 109 110 // TestisNotATest is not a test function, despite appearances. 111 // 112 // Please ignore any lint or vet warnings for this function. 113 func TestisNotATest(t *testing.T) { 114 panic("This is not a valid test function.") 115 } 116 117 // Test1IsATest is a valid test function. 118 func Test1IsATest(t *testing.T) { 119 } 120 121 // Test is a test with a minimal name. 122 func Test(t *testing.T) { 123 } 124 125 // TestÑIsATest is a test with an interesting Unicode name. 126 func TestÑIsATest(t *testing.T) { 127 } 128 129 func Example() { 130 // Output: 131 } 132 133 func ExampleTest() { 134 // This is an example for the function Test. 135 // ❤ recursion. 136 Test(nil) 137 138 // Output: 139 } 140 141 func Example1IsAnExample() { 142 // Output: 143 } 144 145 // ExampleisNotAnExample is not an example function, despite appearances. 146 // 147 // Please ignore any lint or vet warnings for this function. 148 func ExampleisNotAnExample() { 149 panic("This is not a valid example function.") 150 151 // Output: 152 // None. (This is not really an example function.) 153 } 154 155 func Example_isAnExample() { 156 // Output: 157 } 158 159 func ExampleTest_isAnExample() { 160 Test(nil) 161 162 // Output: 163 } 164 165 func Example_noOutput() { 166 // No output declared: should be compiled but not run. 167 } 168 169 func Benchmark(b *testing.B) { 170 for i := 0; i < b.N; i++ { 171 } 172 } 173 174 func BenchmarkNop(b *testing.B) { 175 for i := 0; i < b.N; i++ { 176 } 177 } 178 179 func Benchmark1IsABenchmark(b *testing.B) { 180 for i := 0; i < b.N; i++ { 181 } 182 } 183 184 // BenchmarkisNotABenchmark is not a benchmark function, despite appearances. 185 // 186 // Please ignore any lint or vet warnings for this function. 187 func BenchmarkisNotABenchmark(b *testing.B) { 188 panic("This is not a valid benchmark function.") 189 } 190 191 // FuzzisNotAFuzz is not a fuzz test function, despite appearances. 192 // 193 // Please ignore any lint or vet warnings for this function. 194 func FuzzisNotAFuzz(f *testing.F) { 195 panic("This is not a valid fuzzing function.") 196 } 197 198 // Fuzz1IsAFuzz is a valid fuzz function. 199 func Fuzz1IsAFuzz(f *testing.F) { 200 f.Skip() 201 } 202 203 // Fuzz is a fuzz with a minimal name. 204 func Fuzz(f *testing.F) { 205 f.Skip() 206 } 207 208 // FuzzÑIsAFuzz is a fuzz with an interesting Unicode name. 209 func FuzzÑIsAFuzz(f *testing.F) { 210 f.Skip() 211 }