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 }