Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / libgo / go / 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         for _, eg = range examples {
28                 matched, err := matchString(*match, eg.Name)
29                 if err != nil {
30                         fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\n", err)
31                         os.Exit(1)
32                 }
33                 if !matched {
34                         continue
35                 }
36                 if !runExample(eg) {
37                         ok = false
38                 }
39         }
40
41         return
42 }
43
44 func runExample(eg InternalExample) (ok bool) {
45         if *chatty {
46                 fmt.Printf("=== RUN: %s\n", eg.Name)
47         }
48
49         // Capture stdout.
50         stdout := os.Stdout
51         r, w, err := os.Pipe()
52         if err != nil {
53                 fmt.Fprintln(os.Stderr, err)
54                 os.Exit(1)
55         }
56         os.Stdout = w
57         outC := make(chan string)
58         go func() {
59                 buf := new(bytes.Buffer)
60                 _, err := io.Copy(buf, r)
61                 r.Close()
62                 if err != nil {
63                         fmt.Fprintf(os.Stderr, "testing: copying pipe: %v\n", err)
64                         os.Exit(1)
65                 }
66                 outC <- buf.String()
67         }()
68
69         start := time.Now()
70         ok = true
71
72         // Clean up in a deferred call so we can recover if the example panics.
73         defer func() {
74                 d := time.Now().Sub(start)
75
76                 // Close pipe, restore stdout, get output.
77                 w.Close()
78                 os.Stdout = stdout
79                 out := <-outC
80
81                 var fail string
82                 err := recover()
83                 if g, e := strings.TrimSpace(out), strings.TrimSpace(eg.Output); g != e && err == nil {
84                         fail = fmt.Sprintf("got:\n%s\nwant:\n%s\n", g, e)
85                 }
86                 if fail != "" || err != nil {
87                         fmt.Printf("--- FAIL: %s (%v)\n%s", eg.Name, d, fail)
88                         ok = false
89                 } else if *chatty {
90                         fmt.Printf("--- PASS: %s (%v)\n", eg.Name, d)
91                 }
92                 if err != nil {
93                         panic(err)
94                 }
95         }()
96
97         // Run example.
98         eg.F()
99         return
100 }