PR target/82855
[official-gcc.git] / libgo / go / testing / example.go
blobe5bce7af4e7a3e6a691e6f42e097e51d69e2fd9c
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.
5 package testing
7 import (
8 "bytes"
9 "fmt"
10 "io"
11 "os"
12 "sort"
13 "strings"
14 "time"
17 type InternalExample struct {
18 Name string
19 F func()
20 Output string
21 Unordered bool
24 // An internal function but exported because it is cross-package; part of the implementation
25 // of the "go test" command.
26 func RunExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ok bool) {
27 _, ok = runExamples(matchString, examples)
28 return ok
31 func runExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ran, ok bool) {
32 ok = true
34 var eg InternalExample
36 for _, eg = range examples {
37 matched, err := matchString(*match, eg.Name)
38 if err != nil {
39 fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\n", err)
40 os.Exit(1)
42 if !matched {
43 continue
45 ran = true
46 if !runExample(eg) {
47 ok = false
51 return ran, ok
54 func sortLines(output string) string {
55 lines := strings.Split(output, "\n")
56 sort.Strings(lines)
57 return strings.Join(lines, "\n")
60 func runExample(eg InternalExample) (ok bool) {
61 if *chatty {
62 fmt.Printf("=== RUN %s\n", eg.Name)
65 // Capture stdout.
66 stdout := os.Stdout
67 r, w, err := os.Pipe()
68 if err != nil {
69 fmt.Fprintln(os.Stderr, err)
70 os.Exit(1)
72 os.Stdout = w
73 outC := make(chan string)
74 go func() {
75 var buf bytes.Buffer
76 _, err := io.Copy(&buf, r)
77 r.Close()
78 if err != nil {
79 fmt.Fprintf(os.Stderr, "testing: copying pipe: %v\n", err)
80 os.Exit(1)
82 outC <- buf.String()
83 }()
85 start := time.Now()
86 ok = true
88 // Clean up in a deferred call so we can recover if the example panics.
89 defer func() {
90 dstr := fmtDuration(time.Now().Sub(start))
92 // Close pipe, restore stdout, get output.
93 w.Close()
94 os.Stdout = stdout
95 out := <-outC
97 var fail string
98 err := recover()
99 got := strings.TrimSpace(out)
100 want := strings.TrimSpace(eg.Output)
101 if eg.Unordered {
102 if sortLines(got) != sortLines(want) && err == nil {
103 fail = fmt.Sprintf("got:\n%s\nwant (unordered):\n%s\n", out, eg.Output)
105 } else {
106 if got != want && err == nil {
107 fail = fmt.Sprintf("got:\n%s\nwant:\n%s\n", got, want)
110 if fail != "" || err != nil {
111 fmt.Printf("--- FAIL: %s (%s)\n%s", eg.Name, dstr, fail)
112 ok = false
113 } else if *chatty {
114 fmt.Printf("--- PASS: %s (%s)\n", eg.Name, dstr)
116 if err != nil {
117 panic(err)
121 // Run example.
122 eg.F()
123 return