diff options
Diffstat (limited to 'src/pkg/testing/example.go')
-rw-r--r-- | src/pkg/testing/example.go | 80 |
1 files changed, 49 insertions, 31 deletions
diff --git a/src/pkg/testing/example.go b/src/pkg/testing/example.go index 671c79876..828c2d3ed 100644 --- a/src/pkg/testing/example.go +++ b/src/pkg/testing/example.go @@ -24,8 +24,6 @@ func RunExamples(matchString func(pat, str string) (bool, error), examples []Int var eg InternalExample - stdout, stderr := os.Stdout, os.Stderr - for _, eg = range examples { matched, err := matchString(*match, eg.Name) if err != nil { @@ -35,48 +33,68 @@ func RunExamples(matchString func(pat, str string) (bool, error), examples []Int if !matched { continue } - if *chatty { - fmt.Printf("=== RUN: %s\n", eg.Name) + if !runExample(eg) { + ok = false } + } + + return +} + +func runExample(eg InternalExample) (ok bool) { + if *chatty { + fmt.Printf("=== RUN: %s\n", eg.Name) + } - // capture stdout and stderr - r, w, err := os.Pipe() + // Capture stdout. + stdout := os.Stdout + r, w, err := os.Pipe() + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + os.Stdout = w + outC := make(chan string) + go func() { + buf := new(bytes.Buffer) + _, err := io.Copy(buf, r) + r.Close() if err != nil { - fmt.Fprintln(os.Stderr, err) + fmt.Fprintf(os.Stderr, "testing: copying pipe: %v\n", err) os.Exit(1) } - os.Stdout, os.Stderr = w, w - outC := make(chan string) - go func() { - buf := new(bytes.Buffer) - _, err := io.Copy(buf, r) - if err != nil { - fmt.Fprintf(stderr, "testing: copying pipe: %v\n", err) - os.Exit(1) - } - outC <- buf.String() - }() + outC <- buf.String() + }() + + start := time.Now() + ok = true - // run example - t0 := time.Now() - eg.F() - dt := time.Now().Sub(t0) + // Clean up in a deferred call so we can recover if the example panics. + defer func() { + d := time.Now().Sub(start) - // close pipe, restore stdout/stderr, get output + // Close pipe, restore stdout, get output. w.Close() - os.Stdout, os.Stderr = stdout, stderr + os.Stdout = stdout out := <-outC - // report any errors - tstr := fmt.Sprintf("(%.2f seconds)", dt.Seconds()) - if g, e := strings.TrimSpace(out), strings.TrimSpace(eg.Output); g != e { - fmt.Printf("--- FAIL: %s %s\ngot:\n%s\nwant:\n%s\n", - eg.Name, tstr, g, e) + var fail string + err := recover() + if g, e := strings.TrimSpace(out), strings.TrimSpace(eg.Output); g != e && err == nil { + fail = fmt.Sprintf("got:\n%s\nwant:\n%s\n", g, e) + } + if fail != "" || err != nil { + fmt.Printf("--- FAIL: %s (%v)\n%s", eg.Name, d, fail) ok = false } else if *chatty { - fmt.Printf("--- PASS: %s %s\n", eg.Name, tstr) + fmt.Printf("--- PASS: %s (%v)\n", eg.Name, d) } - } + if err != nil { + panic(err) + } + }() + // Run example. + eg.F() return } |