diff --git a/test/run.go b/test/run.go
index 10dbceff5d4..49bcd96c94c 100644
--- a/test/run.go
+++ b/test/run.go
@@ -165,6 +165,22 @@ func goFiles(dir string) []string {
return names
}
+type runCmd func(...string) ([]byte, error)
+
+func compileFile(runcmd runCmd, longname string) (out []byte, err error) {
+ return runcmd("go", "tool", gc, "-e", longname)
+}
+
+func compileInDir(runcmd runCmd, dir, name string) (out []byte, err error) {
+ return runcmd("go", "tool", gc, "-e", "-D.", "-I.", filepath.Join(dir, name))
+}
+
+func linkFile(runcmd runCmd, goname string) (err error) {
+ pfile := strings.Replace(goname, ".go", "."+letter, -1)
+ _, err = runcmd("go", "tool", ld, "-o", "run.out", "-L", ".", pfile)
+ return
+}
+
// skipError describes why a test was skipped.
type skipError string
@@ -230,6 +246,19 @@ func (t *test) goDirName() string {
return filepath.Join(t.dir, strings.Replace(t.gofile, ".go", ".dir", -1))
}
+func goDirFiles(longdir string) (filter []os.FileInfo, err error) {
+ files, dirErr := ioutil.ReadDir(longdir)
+ if dirErr != nil {
+ return nil, dirErr
+ }
+ for _, gofile := range files {
+ if filepath.Ext(gofile.Name()) == ".go" {
+ filter = append(filter, gofile)
+ }
+ }
+ return
+}
+
// run runs a test.
func (t *test) run() {
defer close(t.donec)
@@ -263,12 +292,15 @@ func (t *test) run() {
}
switch action {
+ case "rundircmpout":
+ action = "rundir"
+ t.action = "rundir"
case "cmpout":
action = "run" // the run case already looks for
/.out files
fallthrough
- case "compile", "compiledir", "build", "run", "runoutput":
+ case "compile", "compiledir", "build", "run", "runoutput", "rundir":
t.action = action
- case "errorcheck":
+ case "errorcheck", "errorcheckdir":
t.action = action
wantError = true
for len(args) > 0 && strings.HasPrefix(args[0], "-") {
@@ -308,6 +340,9 @@ func (t *test) run() {
cmd.Dir = t.tempDir
}
err := cmd.Run()
+ if err != nil {
+ err = fmt.Errorf("%s\n%s", err, buf.Bytes())
+ }
return buf.Bytes(), err
}
@@ -328,7 +363,7 @@ func (t *test) run() {
}
} else {
if err != nil {
- t.err = fmt.Errorf("%s\n%s", err, out)
+ t.err = err
return
}
}
@@ -336,42 +371,95 @@ func (t *test) run() {
return
case "compile":
- out, err := runcmd("go", "tool", gc, "-e", "-o", "a."+letter, long)
- if err != nil {
- t.err = fmt.Errorf("%s\n%s", err, out)
- }
+ _, t.err = compileFile(runcmd, long)
case "compiledir":
// Compile all files in the directory in lexicographic order.
longdir := filepath.Join(cwd, t.goDirName())
- files, dirErr := ioutil.ReadDir(longdir)
- if dirErr != nil {
- t.err = dirErr
+ files, err := goDirFiles(longdir)
+ if err != nil {
+ t.err = err
return
}
for _, gofile := range files {
- if filepath.Ext(gofile.Name()) != ".go" {
- continue
+ _, t.err = compileInDir(runcmd, longdir, gofile.Name())
+ if t.err != nil {
+ return
}
- afile := strings.Replace(gofile.Name(), ".go", "."+letter, -1)
- out, err := runcmd("go", "tool", gc, "-e", "-D.", "-I.", "-o", afile, filepath.Join(longdir, gofile.Name()))
- if err != nil {
- t.err = fmt.Errorf("%s\n%s", err, out)
+ }
+
+ case "errorcheckdir":
+ // errorcheck all files in lexicographic order
+ // useful for finding importing errors
+ longdir := filepath.Join(cwd, t.goDirName())
+ files, err := goDirFiles(longdir)
+ if err != nil {
+ t.err = err
+ return
+ }
+ for i, gofile := range files {
+ out, err := compileInDir(runcmd, longdir, gofile.Name())
+ if i == len(files)-1 {
+ if wantError && err == nil {
+ t.err = fmt.Errorf("compilation succeeded unexpectedly\n%s", out)
+ return
+ } else if !wantError && err != nil {
+ t.err = err
+ return
+ }
+ } else if err != nil {
+ t.err = err
+ return
+ }
+ longname := filepath.Join(longdir, gofile.Name())
+ t.err = t.errorCheck(string(out), longname, gofile.Name())
+ if t.err != nil {
break
}
}
- case "build":
- out, err := runcmd("go", "build", "-o", "a.exe", long)
+ case "rundir":
+ // Compile all files in the directory in lexicographic order.
+ // then link as if the last file is the main package and run it
+ longdir := filepath.Join(cwd, t.goDirName())
+ files, err := goDirFiles(longdir)
if err != nil {
- t.err = fmt.Errorf("%s\n%s", err, out)
+ t.err = err
+ return
+ }
+ var gofile os.FileInfo
+ for _, gofile = range files {
+ _, err := compileInDir(runcmd, longdir, gofile.Name())
+ if err != nil {
+ t.err = err
+ return
+ }
+ }
+ err = linkFile(runcmd, gofile.Name())
+ if err != nil {
+ t.err = err
+ return
+ }
+ out, err := runcmd(append([]string{filepath.Join(t.tempDir, "run.out")}, args...)...)
+ if err != nil {
+ t.err = err
+ return
+ }
+ if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
+ t.err = fmt.Errorf("incorrect output\n%s", out)
+ }
+
+ case "build":
+ _, err := runcmd("go", "build", "-o", "a.exe", long)
+ if err != nil {
+ t.err = err
}
case "run":
useTmp = false
out, err := runcmd(append([]string{"go", "run", t.goFileName()}, args...)...)
if err != nil {
- t.err = fmt.Errorf("%s\n%s", err, out)
+ t.err = err
}
if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
t.err = fmt.Errorf("incorrect output\n%s", out)
@@ -381,7 +469,7 @@ func (t *test) run() {
useTmp = false
out, err := runcmd("go", "run", t.goFileName())
if err != nil {
- t.err = fmt.Errorf("%s\n%s", err, out)
+ t.err = err
}
tfile := filepath.Join(t.tempDir, "tmp__.go")
err = ioutil.WriteFile(tfile, out, 0666)
@@ -391,7 +479,7 @@ func (t *test) run() {
}
out, err = runcmd("go", "run", tfile)
if err != nil {
- t.err = fmt.Errorf("%s\n%s", err, out)
+ t.err = err
}
if string(out) != t.expectedOutput() {
t.err = fmt.Errorf("incorrect output\n%s", out)
@@ -444,7 +532,7 @@ func (t *test) errorCheck(outStr string, full, short string) (err error) {
out[i] = strings.Replace(out[i], full, short, -1)
}
- for _, we := range t.wantedErrors() {
+ for _, we := range t.wantedErrors(full, short) {
var errmsgs []string
errmsgs, out = partitionStrings(we.filterRe, out)
if len(errmsgs) == 0 {
@@ -505,8 +593,9 @@ var (
lineRx = regexp.MustCompile(`LINE(([+-])([0-9]+))?`)
)
-func (t *test) wantedErrors() (errs []wantedError) {
- for i, line := range strings.Split(t.src, "\n") {
+func (t *test) wantedErrors(file, short string) (errs []wantedError) {
+ src, _ := ioutil.ReadFile(file)
+ for i, line := range strings.Split(string(src), "\n") {
lineNum := i + 1
if strings.Contains(line, "////") {
// double comment disables ERROR
@@ -531,15 +620,15 @@ func (t *test) wantedErrors() (errs []wantedError) {
delta, _ := strconv.Atoi(m[5:])
n -= delta
}
- return fmt.Sprintf("%s:%d", t.gofile, n)
+ return fmt.Sprintf("%s:%d", short, n)
})
- filterPattern := fmt.Sprintf(`^(\w+/)?%s:%d[:[]`, t.gofile, lineNum)
+ filterPattern := fmt.Sprintf(`^(\w+/)?%s:%d[:[]`, short, lineNum)
errs = append(errs, wantedError{
reStr: rx,
re: regexp.MustCompile(rx),
filterRe: regexp.MustCompile(filterPattern),
lineNum: lineNum,
- file: t.gofile,
+ file: short,
})
}
}
diff --git a/test/testlib b/test/testlib
index 29de7672ce1..8033b7f93cd 100644
--- a/test/testlib
+++ b/test/testlib
@@ -16,6 +16,46 @@ compiledir() {
done
}
+errorcheckdir() {
+ lastzero=""
+ if [ "$1" = "-0" ]; then
+ lastzero="-0"
+ fi
+ files=($D/$F.dir/*.go)
+ for gofile in ${files[@]}
+ do
+ zero="-0"
+ if [ ${files[${#files[@]}-1]} = $gofile ]; then
+ zero=$lastzero
+ fi
+ errchk $zero $G -D. -I. -e $gofile
+ done
+}
+
+rundir() {
+ lastfile=""
+ for gofile in $D/$F.dir/*.go
+ do
+ name=$(basename ${gofile/\.go/} )
+ $G -D. -I. -e "$gofile" || return 1
+ lastfile=$name
+ done
+ $L -o $A.out -L. $lastfile.$A
+ ./$A.out
+}
+
+rundircmpout() {
+ lastfile=""
+ for gofile in $D/$F.dir/*.go
+ do
+ name=$(basename ${gofile/\.go/} )
+ $G -D. -I. -e "$gofile" || return 1
+ lastfile=$name
+ done
+ $L -o $A.out -L. $lastfile.$A
+ ./$A.out | cmp - $D/$F.out
+}
+
build() {
$G $D/$F.go && $L $F.$A
}