2011-10-06 12:56:17 -06:00
|
|
|
// 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"
|
2012-02-26 18:49:10 -07:00
|
|
|
"flag"
|
2011-10-06 12:56:17 -06:00
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"os"
|
2011-12-15 15:43:58 -07:00
|
|
|
"strings"
|
2011-10-06 12:56:17 -06:00
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2012-02-26 18:49:10 -07:00
|
|
|
var matchExamples = flag.String("test.example", "", "regular expression to select examples to run")
|
|
|
|
|
2011-10-06 12:56:17 -06:00
|
|
|
type InternalExample struct {
|
|
|
|
Name string
|
|
|
|
F func()
|
|
|
|
Output string
|
|
|
|
}
|
|
|
|
|
2012-02-26 18:49:10 -07:00
|
|
|
func RunExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ok bool) {
|
2012-02-26 22:23:22 -07:00
|
|
|
if *match != "" && *matchExamples == "" {
|
2012-02-26 18:49:10 -07:00
|
|
|
return // Don't run examples if testing is restricted: we're debugging.
|
|
|
|
}
|
2011-10-06 12:56:17 -06:00
|
|
|
ok = true
|
|
|
|
|
2011-11-15 11:09:19 -07:00
|
|
|
var eg InternalExample
|
|
|
|
|
2011-10-06 12:56:17 -06:00
|
|
|
stdout, stderr := os.Stdout, os.Stderr
|
|
|
|
|
2011-11-15 11:09:19 -07:00
|
|
|
for _, eg = range examples {
|
2012-02-26 18:49:10 -07:00
|
|
|
matched, err := matchString(*matchExamples, eg.Name)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.example: %s\n", err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
if !matched {
|
|
|
|
continue
|
|
|
|
}
|
2011-10-06 12:56:17 -06:00
|
|
|
if *chatty {
|
2011-11-15 11:09:19 -07:00
|
|
|
fmt.Printf("=== RUN: %s\n", eg.Name)
|
2011-10-06 12:56:17 -06:00
|
|
|
}
|
|
|
|
|
2011-11-15 11:09:19 -07:00
|
|
|
// capture stdout and stderr
|
2011-10-06 12:56:17 -06:00
|
|
|
r, w, err := os.Pipe()
|
|
|
|
if err != nil {
|
|
|
|
fmt.Fprintln(os.Stderr, err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
os.Stdout, os.Stderr = w, w
|
|
|
|
outC := make(chan string)
|
|
|
|
go func() {
|
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
_, err := io.Copy(buf, r)
|
|
|
|
if err != nil {
|
2011-11-15 11:09:19 -07:00
|
|
|
fmt.Fprintf(stderr, "testing: copying pipe: %v\n", err)
|
2011-10-06 12:56:17 -06:00
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
outC <- buf.String()
|
|
|
|
}()
|
|
|
|
|
|
|
|
// run example
|
2011-11-30 10:01:46 -07:00
|
|
|
t0 := time.Now()
|
2011-10-06 12:56:17 -06:00
|
|
|
eg.F()
|
2011-11-30 10:01:46 -07:00
|
|
|
dt := time.Now().Sub(t0)
|
2011-10-06 12:56:17 -06:00
|
|
|
|
|
|
|
// close pipe, restore stdout/stderr, get output
|
|
|
|
w.Close()
|
|
|
|
os.Stdout, os.Stderr = stdout, stderr
|
|
|
|
out := <-outC
|
|
|
|
|
|
|
|
// report any errors
|
2011-11-30 10:01:46 -07:00
|
|
|
tstr := fmt.Sprintf("(%.2f seconds)", dt.Seconds())
|
2011-12-15 15:43:58 -07:00
|
|
|
if g, e := strings.TrimSpace(out), strings.TrimSpace(eg.Output); g != e {
|
|
|
|
fmt.Printf("--- FAIL: %s %s\ngot:\n%s\nwant:\n%s\n",
|
|
|
|
eg.Name, tstr, g, e)
|
2011-10-06 12:56:17 -06:00
|
|
|
ok = false
|
|
|
|
} else if *chatty {
|
2011-11-15 11:09:19 -07:00
|
|
|
fmt.Printf("--- PASS: %s %s\n", eg.Name, tstr)
|
2011-10-06 12:56:17 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|