@@ -19,9 +19,9 @@ import (
1919 "path"
2020 "path/filepath"
2121 "strings"
22+ "sync"
2223 "testing"
2324
24- "golang.org/x/tools/internal/testenv"
2525 "golang.org/x/tools/internal/typeparams"
2626)
2727
@@ -30,9 +30,22 @@ import (
3030// we run stringer -type X and then compile and run the program. The resulting
3131// binary panics if the String method for X is not correct, including for error cases.
3232
33+ func TestMain (m * testing.M ) {
34+ if os .Getenv ("STRINGER_TEST_IS_STRINGER" ) != "" {
35+ main ()
36+ os .Exit (0 )
37+ }
38+
39+ // Inform subprocesses that they should run the cmd/stringer main instead of
40+ // running tests. It's a close approximation to building and running the real
41+ // command, and much less complicated and expensive to build and clean up.
42+ os .Setenv ("STRINGER_TEST_IS_STRINGER" , "1" )
43+
44+ os .Exit (m .Run ())
45+ }
46+
3347func TestEndToEnd (t * testing.T ) {
34- dir , stringer := buildStringer (t )
35- defer os .RemoveAll (dir )
48+ stringer := stringerPath (t )
3649 // Read the testdata directory.
3750 fd , err := os .Open ("testdata" )
3851 if err != nil {
@@ -64,7 +77,7 @@ func TestEndToEnd(t *testing.T) {
6477 t .Logf ("cgo is not enabled for %s" , name )
6578 continue
6679 }
67- stringerCompileAndRun (t , dir , stringer , typeName (name ), name )
80+ stringerCompileAndRun (t , t . TempDir () , stringer , typeName (name ), name )
6881 }
6982}
7083
@@ -91,8 +104,8 @@ func moreTests(t *testing.T, dirname, prefix string) []string {
91104
92105// TestTags verifies that the -tags flag works as advertised.
93106func TestTags (t * testing.T ) {
94- dir , stringer := buildStringer (t )
95- defer os . RemoveAll ( dir )
107+ stringer := stringerPath (t )
108+ dir := t . TempDir ( )
96109 var (
97110 protectedConst = []byte ("TagProtected" )
98111 output = filepath .Join (dir , "const_string.go" )
@@ -139,8 +152,8 @@ func TestTags(t *testing.T) {
139152// TestConstValueChange verifies that if a constant value changes and
140153// the stringer code is not regenerated, we'll get a compiler error.
141154func TestConstValueChange (t * testing.T ) {
142- dir , stringer := buildStringer (t )
143- defer os . RemoveAll ( dir )
155+ stringer := stringerPath (t )
156+ dir := t . TempDir ( )
144157 source := filepath .Join (dir , "day.go" )
145158 err := copy (source , filepath .Join ("testdata" , "day.go" ))
146159 if err != nil {
@@ -178,21 +191,20 @@ func TestConstValueChange(t *testing.T) {
178191 }
179192}
180193
181- // buildStringer creates a temporary directory and installs stringer there.
182- func buildStringer (t * testing.T ) (dir string , stringer string ) {
183- t .Helper ()
184- testenv .NeedsTool (t , "go" )
194+ var exe struct {
195+ path string
196+ err error
197+ once sync.Once
198+ }
185199
186- dir , err := os .MkdirTemp ("" , "stringer" )
187- if err != nil {
188- t .Fatal (err )
189- }
190- stringer = filepath .Join (dir , "stringer.exe" )
191- err = run ("go" , "build" , "-o" , stringer )
192- if err != nil {
193- t .Fatalf ("building stringer: %s" , err )
200+ func stringerPath (t * testing.T ) string {
201+ exe .once .Do (func () {
202+ exe .path , exe .err = os .Executable ()
203+ })
204+ if exe .err != nil {
205+ t .Fatal (exe .err )
194206 }
195- return dir , stringer
207+ return exe . path
196208}
197209
198210// stringerCompileAndRun runs stringer for the named file and compiles and
0 commit comments