]> Cypherpunks repositories - gostls13.git/commitdiff
testing: add file:line stamps to messages.
authorRob Pike <r@golang.org>
Thu, 10 Nov 2011 19:59:50 +0000 (11:59 -0800)
committerRob Pike <r@golang.org>
Thu, 10 Nov 2011 19:59:50 +0000 (11:59 -0800)
A single-line error looks like this:
--- FAIL: foo_test.TestFoo (0.00 seconds)
        foo_test.go:123: Foo(8) = "10" want "100"

A multi-line error looks like this:
--- FAIL: foo_test.TestFoo (0.00 seconds)
        foo_test.go:456: Foo(88) = "100"
                want "1000"

R=rsc, bradfitz
CC=golang-dev
https://golang.org/cl/5376057

src/pkg/testing/testing.go

index 5869642c7e1f1ebb6bc707edbd8dbc1cc35089aa..32c3fc3ad5cb9bfcfe237c24149878bc49e8bd54 100644 (file)
@@ -75,8 +75,25 @@ func Short() bool {
        return *short
 }
 
-// Insert final newline if needed and tabs after internal newlines.
-func tabify(s string) string {
+// decorate inserts the a final newline if needed and indentation tabs for formatting.
+// If addFileLine is true, it also prefixes the string with the file and line of the call site.
+func decorate(s string, addFileLine bool) string {
+       if addFileLine {
+               _, file, line, ok := runtime.Caller(3) // decorate + log + public function.
+               if ok {
+                       // Truncate file name at last file name separator.
+                       if index := strings.LastIndex(file, "/"); index >= 0 {
+                               file = file[index+1:]
+                       } else if index = strings.LastIndex(file, "\\"); index >= 0 {
+                               file = file[index+1:]
+                       }
+               } else {
+                       file = "???"
+                       line = 1
+               }
+               s = fmt.Sprintf("%s:%d: %s", file, line, s)
+       }
+       s = "\t" + s // Every line is indented at least one tab.
        n := len(s)
        if n > 0 && s[n-1] != '\n' {
                s += "\n"
@@ -84,7 +101,8 @@ func tabify(s string) string {
        }
        for i := 0; i < n-1; i++ { // -1 to avoid final newline
                if s[i] == '\n' {
-                       return s[0:i+1] + "\t" + tabify(s[i+1:n])
+                       // Second and subsequent lines are indented an extra tab.
+                       return s[0:i+1] + "\t" + decorate(s[i+1:n], false)
                }
        }
        return s
@@ -116,37 +134,38 @@ func (t *T) FailNow() {
        runtime.Goexit()
 }
 
+// log generates the output. It's always at the same stack depth.
+func (t *T) log(s string) { t.errors += decorate(s, true) }
+
 // Log formats its arguments using default formatting, analogous to Print(),
 // and records the text in the error log.
-func (t *T) Log(args ...interface{}) { t.errors += "\t" + tabify(fmt.Sprintln(args...)) }
+func (t *T) Log(args ...interface{}) { t.log(fmt.Sprintln(args...)) }
 
 // Logf formats its arguments according to the format, analogous to Printf(),
 // and records the text in the error log.
-func (t *T) Logf(format string, args ...interface{}) {
-       t.errors += "\t" + tabify(fmt.Sprintf(format, args...))
-}
+func (t *T) Logf(format string, args ...interface{}) { t.log(fmt.Sprintf(format, args...)) }
 
 // Error is equivalent to Log() followed by Fail().
 func (t *T) Error(args ...interface{}) {
-       t.Log(args...)
+       t.log(fmt.Sprintln(args...))
        t.Fail()
 }
 
 // Errorf is equivalent to Logf() followed by Fail().
 func (t *T) Errorf(format string, args ...interface{}) {
-       t.Logf(format, args...)
+       t.log(fmt.Sprintf(format, args...))
        t.Fail()
 }
 
 // Fatal is equivalent to Log() followed by FailNow().
 func (t *T) Fatal(args ...interface{}) {
-       t.Log(args...)
+       t.log(fmt.Sprintln(args...))
        t.FailNow()
 }
 
 // Fatalf is equivalent to Logf() followed by FailNow().
 func (t *T) Fatalf(format string, args ...interface{}) {
-       t.Logf(format, args...)
+       t.log(fmt.Sprintf(format, args...))
        t.FailNow()
 }