...
Run Format

Source file src/testing/example.go

Documentation: testing

  // Copyright 2009 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  package testing
  
  import (
  	"bytes"
  	"fmt"
  	"io"
  	"os"
  	"sort"
  	"strings"
  	"time"
  )
  
  type InternalExample struct {
  	Name      string
  	F         func()
  	Output    string
  	Unordered bool
  }
  
  // An internal function but exported because it is cross-package; part of the implementation
  // of the "go test" command.
  func RunExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ok bool) {
  	_, ok = runExamples(matchString, examples)
  	return ok
  }
  
  func runExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ran, ok bool) {
  	ok = true
  
  	var eg InternalExample
  
  	for _, eg = range examples {
  		matched, err := matchString(*match, eg.Name)
  		if err != nil {
  			fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\n", err)
  			os.Exit(1)
  		}
  		if !matched {
  			continue
  		}
  		ran = true
  		if !runExample(eg) {
  			ok = false
  		}
  	}
  
  	return ran, ok
  }
  
  func sortLines(output string) string {
  	lines := strings.Split(output, "\n")
  	sort.Strings(lines)
  	return strings.Join(lines, "\n")
  }
  
  func runExample(eg InternalExample) (ok bool) {
  	if *chatty {
  		fmt.Printf("=== RUN   %s\n", eg.Name)
  	}
  
  	// Capture stdout.
  	stdout := os.Stdout
  	r, w, err := os.Pipe()
  	if err != nil {
  		fmt.Fprintln(os.Stderr, err)
  		os.Exit(1)
  	}
  	os.Stdout = w
  	outC := make(chan string)
  	go func() {
  		var buf bytes.Buffer
  		_, err := io.Copy(&buf, r)
  		r.Close()
  		if err != nil {
  			fmt.Fprintf(os.Stderr, "testing: copying pipe: %v\n", err)
  			os.Exit(1)
  		}
  		outC <- buf.String()
  	}()
  
  	start := time.Now()
  	ok = true
  
  	// Clean up in a deferred call so we can recover if the example panics.
  	defer func() {
  		dstr := fmtDuration(time.Now().Sub(start))
  
  		// Close pipe, restore stdout, get output.
  		w.Close()
  		os.Stdout = stdout
  		out := <-outC
  
  		var fail string
  		err := recover()
  		got := strings.TrimSpace(out)
  		want := strings.TrimSpace(eg.Output)
  		if eg.Unordered {
  			if sortLines(got) != sortLines(want) && err == nil {
  				fail = fmt.Sprintf("got:\n%s\nwant (unordered):\n%s\n", out, eg.Output)
  			}
  		} else {
  			if got != want && err == nil {
  				fail = fmt.Sprintf("got:\n%s\nwant:\n%s\n", got, want)
  			}
  		}
  		if fail != "" || err != nil {
  			fmt.Printf("--- FAIL: %s (%s)\n%s", eg.Name, dstr, fail)
  			ok = false
  		} else if *chatty {
  			fmt.Printf("--- PASS: %s (%s)\n", eg.Name, dstr)
  		}
  		if err != nil {
  			panic(err)
  		}
  	}()
  
  	// Run example.
  	eg.F()
  	return
  }
  

View as plain text