Source file src/pkg/testing/example.go
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package testing
6
7 import (
8 "bytes"
9 "fmt"
10 "io"
11 "os"
12 "strings"
13 "time"
14 )
15
16 type InternalExample struct {
17 Name string
18 F func()
19 Output string
20 }
21
22 func RunExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ok bool) {
23 ok = true
24
25 var eg InternalExample
26
27 stdout, stderr := os.Stdout, os.Stderr
28
29 for _, eg = range examples {
30 matched, err := matchString(*match, eg.Name)
31 if err != nil {
32 fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\n", err)
33 os.Exit(1)
34 }
35 if !matched {
36 continue
37 }
38 if *chatty {
39 fmt.Printf("=== RUN: %s\n", eg.Name)
40 }
41
42 // capture stdout and stderr
43 r, w, err := os.Pipe()
44 if err != nil {
45 fmt.Fprintln(os.Stderr, err)
46 os.Exit(1)
47 }
48 os.Stdout, os.Stderr = w, w
49 outC := make(chan string)
50 go func() {
51 buf := new(bytes.Buffer)
52 _, err := io.Copy(buf, r)
53 if err != nil {
54 fmt.Fprintf(stderr, "testing: copying pipe: %v\n", err)
55 os.Exit(1)
56 }
57 outC <- buf.String()
58 }()
59
60 // run example
61 t0 := time.Now()
62 eg.F()
63 dt := time.Now().Sub(t0)
64
65 // close pipe, restore stdout/stderr, get output
66 w.Close()
67 os.Stdout, os.Stderr = stdout, stderr
68 out := <-outC
69
70 // report any errors
71 tstr := fmt.Sprintf("(%.2f seconds)", dt.Seconds())
72 if g, e := strings.TrimSpace(out), strings.TrimSpace(eg.Output); g != e {
73 fmt.Printf("--- FAIL: %s %s\ngot:\n%s\nwant:\n%s\n",
74 eg.Name, tstr, g, e)
75 ok = false
76 } else if *chatty {
77 fmt.Printf("--- PASS: %s %s\n", eg.Name, tstr)
78 }
79 }
80
81 return
82 }