...
Run Format

Source file src/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		"sort"
    13		"strings"
    14		"time"
    15	)
    16	
    17	type InternalExample struct {
    18		Name      string
    19		F         func()
    20		Output    string
    21		Unordered bool
    22	}
    23	
    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
    29	}
    30	
    31	func runExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ran, ok bool) {
    32		ok = true
    33	
    34		var eg InternalExample
    35	
    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)
    41			}
    42			if !matched {
    43				continue
    44			}
    45			ran = true
    46			if !runExample(eg) {
    47				ok = false
    48			}
    49		}
    50	
    51		return ran, ok
    52	}
    53	
    54	func sortLines(output string) string {
    55		lines := strings.Split(output, "\n")
    56		sort.Strings(lines)
    57		return strings.Join(lines, "\n")
    58	}
    59	
    60	func runExample(eg InternalExample) (ok bool) {
    61		if *chatty {
    62			fmt.Printf("=== RUN   %s\n", eg.Name)
    63		}
    64	
    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)
    71		}
    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)
    81			}
    82			outC <- buf.String()
    83		}()
    84	
    85		start := time.Now()
    86		ok = true
    87	
    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))
    91	
    92			// Close pipe, restore stdout, get output.
    93			w.Close()
    94			os.Stdout = stdout
    95			out := <-outC
    96	
    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)
   104				}
   105			} else {
   106				if got != want && err == nil {
   107					fail = fmt.Sprintf("got:\n%s\nwant:\n%s\n", got, want)
   108				}
   109			}
   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)
   115			}
   116			if err != nil {
   117				panic(err)
   118			}
   119		}()
   120	
   121		// Run example.
   122		eg.F()
   123		return
   124	}
   125	

View as plain text