github.com/flyinox/gosm@v0.0.0-20171117061539-16768cb62077/src/go/doc/testdata/example.go (about)

     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  }