Home | History | Annotate | Download | only in testdata
      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(examples []InternalExample) (ok bool) {
     23 	ok = true
     24 
     25 	var eg InternalExample
     26 
     27 	stdout, stderr := os.Stdout, os.Stderr
     28 	defer func() {
     29 		os.Stdout, os.Stderr = stdout, stderr
     30 		if e := recover(); e != nil {
     31 			fmt.Printf("--- FAIL: %s\npanic: %v\n", eg.Name, e)
     32 			os.Exit(1)
     33 		}
     34 	}()
     35 
     36 	for _, eg = range examples {
     37 		if *chatty {
     38 			fmt.Printf("=== RUN: %s\n", eg.Name)
     39 		}
     40 
     41 		// capture stdout and stderr
     42 		r, w, err := os.Pipe()
     43 		if err != nil {
     44 			fmt.Fprintln(os.Stderr, err)
     45 			os.Exit(1)
     46 		}
     47 		os.Stdout, os.Stderr = w, w
     48 		outC := make(chan string)
     49 		go func() {
     50 			buf := new(bytes.Buffer)
     51 			_, err := io.Copy(buf, r)
     52 			if err != nil {
     53 				fmt.Fprintf(stderr, "testing: copying pipe: %v\n", err)
     54 				os.Exit(1)
     55 			}
     56 			outC <- buf.String()
     57 		}()
     58 
     59 		// run example
     60 		t0 := time.Now()
     61 		eg.F()
     62 		dt := time.Now().Sub(t0)
     63 
     64 		// close pipe, restore stdout/stderr, get output
     65 		w.Close()
     66 		os.Stdout, os.Stderr = stdout, stderr
     67 		out := <-outC
     68 
     69 		// report any errors
     70 		tstr := fmt.Sprintf("(%.2f seconds)", dt.Seconds())
     71 		if g, e := strings.TrimSpace(out), strings.TrimSpace(eg.Output); g != e {
     72 			fmt.Printf("--- FAIL: %s %s\ngot:\n%s\nwant:\n%s\n",
     73 				eg.Name, tstr, g, e)
     74 			ok = false
     75 		} else if *chatty {
     76 			fmt.Printf("--- PASS: %s %s\n", eg.Name, tstr)
     77 		}
     78 	}
     79 
     80 	return
     81 }
     82