diff options
Diffstat (limited to 'cmd/stringer/endtoend_test.go')
-rw-r--r-- | cmd/stringer/endtoend_test.go | 59 |
1 files changed, 35 insertions, 24 deletions
diff --git a/cmd/stringer/endtoend_test.go b/cmd/stringer/endtoend_test.go index 5b969a52e..29eb91860 100644 --- a/cmd/stringer/endtoend_test.go +++ b/cmd/stringer/endtoend_test.go @@ -14,15 +14,14 @@ import ( "fmt" "go/build" "io" - "io/ioutil" "os" "os/exec" "path" "path/filepath" "strings" + "sync" "testing" - "golang.org/x/tools/internal/testenv" "golang.org/x/tools/internal/typeparams" ) @@ -31,9 +30,22 @@ import ( // we run stringer -type X and then compile and run the program. The resulting // binary panics if the String method for X is not correct, including for error cases. +func TestMain(m *testing.M) { + if os.Getenv("STRINGER_TEST_IS_STRINGER") != "" { + main() + os.Exit(0) + } + + // Inform subprocesses that they should run the cmd/stringer main instead of + // running tests. It's a close approximation to building and running the real + // command, and much less complicated and expensive to build and clean up. + os.Setenv("STRINGER_TEST_IS_STRINGER", "1") + + os.Exit(m.Run()) +} + func TestEndToEnd(t *testing.T) { - dir, stringer := buildStringer(t) - defer os.RemoveAll(dir) + stringer := stringerPath(t) // Read the testdata directory. fd, err := os.Open("testdata") if err != nil { @@ -65,7 +77,7 @@ func TestEndToEnd(t *testing.T) { t.Logf("cgo is not enabled for %s", name) continue } - stringerCompileAndRun(t, dir, stringer, typeName(name), name) + stringerCompileAndRun(t, t.TempDir(), stringer, typeName(name), name) } } @@ -92,8 +104,8 @@ func moreTests(t *testing.T, dirname, prefix string) []string { // TestTags verifies that the -tags flag works as advertised. func TestTags(t *testing.T) { - dir, stringer := buildStringer(t) - defer os.RemoveAll(dir) + stringer := stringerPath(t) + dir := t.TempDir() var ( protectedConst = []byte("TagProtected") output = filepath.Join(dir, "const_string.go") @@ -113,7 +125,7 @@ func TestTags(t *testing.T) { if err != nil { t.Fatal(err) } - result, err := ioutil.ReadFile(output) + result, err := os.ReadFile(output) if err != nil { t.Fatal(err) } @@ -128,7 +140,7 @@ func TestTags(t *testing.T) { if err != nil { t.Fatal(err) } - result, err = ioutil.ReadFile(output) + result, err = os.ReadFile(output) if err != nil { t.Fatal(err) } @@ -140,8 +152,8 @@ func TestTags(t *testing.T) { // TestConstValueChange verifies that if a constant value changes and // the stringer code is not regenerated, we'll get a compiler error. func TestConstValueChange(t *testing.T) { - dir, stringer := buildStringer(t) - defer os.RemoveAll(dir) + stringer := stringerPath(t) + dir := t.TempDir() source := filepath.Join(dir, "day.go") err := copy(source, filepath.Join("testdata", "day.go")) if err != nil { @@ -179,21 +191,20 @@ func TestConstValueChange(t *testing.T) { } } -// buildStringer creates a temporary directory and installs stringer there. -func buildStringer(t *testing.T) (dir string, stringer string) { - t.Helper() - testenv.NeedsTool(t, "go") +var exe struct { + path string + err error + once sync.Once +} - dir, err := ioutil.TempDir("", "stringer") - if err != nil { - t.Fatal(err) - } - stringer = filepath.Join(dir, "stringer.exe") - err = run("go", "build", "-o", stringer) - if err != nil { - t.Fatalf("building stringer: %s", err) +func stringerPath(t *testing.T) string { + exe.once.Do(func() { + exe.path, exe.err = os.Executable() + }) + if exe.err != nil { + t.Fatal(exe.err) } - return dir, stringer + return exe.path } // stringerCompileAndRun runs stringer for the named file and compiles and |