Commit edd1c911 authored by Esko Luontola's avatar Esko Luontola Committed by Andrew Gerrand

gotest: avoid conflicts with the name of the tested package

Uses a generic solution of renaming the tested package, instead of
using cryptic names for all other imports, variables and methods
in the generated _testmain.go file.

Fixes #2346.

R=golang-dev, r, adg
CC=golang-dev, rsc
https://golang.org/cl/5254061
parent aeacd9df
...@@ -234,7 +234,7 @@ func getTestNames() { ...@@ -234,7 +234,7 @@ func getTestNames() {
} }
// TODO: worth checking the signature? Probably not. // TODO: worth checking the signature? Probably not.
} }
if strings.HasSuffix(f.pkg, "_test") { if isOutsideTest(f.pkg) {
outsideFileNames = append(outsideFileNames, f.name) outsideFileNames = append(outsideFileNames, f.name)
} else { } else {
insideFileNames = append(insideFileNames, f.name) insideFileNames = append(insideFileNames, f.name)
...@@ -371,38 +371,41 @@ func writeTestmainGo() { ...@@ -371,38 +371,41 @@ func writeTestmainGo() {
if len(f.tests) == 0 && len(f.benchmarks) == 0 { if len(f.tests) == 0 && len(f.benchmarks) == 0 {
continue continue
} }
if strings.HasSuffix(f.pkg, "_test") { if isOutsideTest(f.pkg) {
outsideTests = true outsideTests = true
} else { } else {
insideTests = true insideTests = true
} }
} }
// Rename the imports for the system under test,
// in case the tested package has the same name
// as any of the other imports, variables or methods.
if insideTests { if insideTests {
switch importPath { switch importPath {
case "testing": case "testing":
case "main": case "main":
// Import path main is reserved, so import with // Import path main is reserved, so import with
// explicit reference to ./_test/main instead. // explicit reference to ./_test/main instead.
// Also, the file we are writing defines a function named main, fmt.Fprintf(b, "import target %q\n", "./_test/main")
// so rename this import to __main__ to avoid name conflict.
fmt.Fprintf(b, "import __main__ %q\n", "./_test/main")
default: default:
fmt.Fprintf(b, "import %q\n", importPath) fmt.Fprintf(b, "import target %q\n", importPath)
} }
} }
if outsideTests { if outsideTests {
fmt.Fprintf(b, "import %q\n", "./_xtest_") // It is possible to have both inside and outside tests
// at the same time, so a different import name is needed.
fmt.Fprintf(b, "import target_test %q\n", "./_xtest_")
} }
fmt.Fprintf(b, "import %q\n", "testing") fmt.Fprintf(b, "import %q\n", "testing")
fmt.Fprintf(b, "import __os__ %q\n", "os") // rename in case tested package is called os fmt.Fprintf(b, "import %q\n", "os")
fmt.Fprintf(b, "import __regexp__ %q\n", "regexp") // rename in case tested package is called regexp fmt.Fprintf(b, "import %q\n", "regexp")
fmt.Fprintln(b) // for gofmt fmt.Fprintln(b) // for gofmt
// Tests. // Tests.
fmt.Fprintln(b, "var tests = []testing.InternalTest{") fmt.Fprintln(b, "var tests = []testing.InternalTest{")
for _, f := range files { for _, f := range files {
for _, t := range f.tests { for _, t := range f.tests {
fmt.Fprintf(b, "\t{\"%s.%s\", %s.%s},\n", f.pkg, t, notMain(f.pkg), t) fmt.Fprintf(b, "\t{\"%s.%s\", %s.%s},\n", f.pkg, t, renamedPackage(f.pkg), t)
} }
} }
fmt.Fprintln(b, "}") fmt.Fprintln(b, "}")
...@@ -412,7 +415,7 @@ func writeTestmainGo() { ...@@ -412,7 +415,7 @@ func writeTestmainGo() {
fmt.Fprintf(b, "var benchmarks = []testing.InternalBenchmark{") fmt.Fprintf(b, "var benchmarks = []testing.InternalBenchmark{")
for _, f := range files { for _, f := range files {
for _, bm := range f.benchmarks { for _, bm := range f.benchmarks {
fmt.Fprintf(b, "\t{\"%s.%s\", %s.%s},\n", f.pkg, bm, notMain(f.pkg), bm) fmt.Fprintf(b, "\t{\"%s.%s\", %s.%s},\n", f.pkg, bm, renamedPackage(f.pkg), bm)
} }
} }
fmt.Fprintln(b, "}") fmt.Fprintln(b, "}")
...@@ -421,7 +424,7 @@ func writeTestmainGo() { ...@@ -421,7 +424,7 @@ func writeTestmainGo() {
fmt.Fprintf(b, "var examples = []testing.InternalExample{") fmt.Fprintf(b, "var examples = []testing.InternalExample{")
for _, f := range files { for _, f := range files {
for _, eg := range f.examples { for _, eg := range f.examples {
fmt.Fprintf(b, "\t{%q, %s.%s, %q},\n", eg.name, f.pkg, eg.name, eg.output) fmt.Fprintf(b, "\t{%q, %s.%s, %q},\n", eg.name, renamedPackage(f.pkg), eg.name, eg.output)
} }
} }
fmt.Fprintln(b, "}") fmt.Fprintln(b, "}")
...@@ -430,23 +433,27 @@ func writeTestmainGo() { ...@@ -430,23 +433,27 @@ func writeTestmainGo() {
fmt.Fprintln(b, testBody) fmt.Fprintln(b, testBody)
} }
// notMain returns the package, renaming as appropriate if it's "main". // renamedPackage returns the name under which the test package was imported.
func notMain(pkg string) string { func renamedPackage(pkg string) string {
if pkg == "main" { if isOutsideTest(pkg) {
return "__main__" return "target_test"
} }
return pkg return "target"
}
func isOutsideTest(pkg string) bool {
return strings.HasSuffix(pkg, "_test")
} }
// testBody is just copied to the output. It's the code that runs the tests. // testBody is just copied to the output. It's the code that runs the tests.
var testBody = ` var testBody = `
var matchPat string var matchPat string
var matchRe *__regexp__.Regexp var matchRe *regexp.Regexp
func matchString(pat, str string) (result bool, err __os__.Error) { func matchString(pat, str string) (result bool, err os.Error) {
if matchRe == nil || matchPat != pat { if matchRe == nil || matchPat != pat {
matchPat = pat matchPat = pat
matchRe, err = __regexp__.Compile(matchPat) matchRe, err = regexp.Compile(matchPat)
if err != nil { if err != nil {
return return
} }
......
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