1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
//go:build golden
package onpar_test
import (
"flag"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"testing"
)
const goldenDir = "testdata"
var (
update = flag.Bool("update", false, "update the golden files")
// timingRe is a regular expression to find timings in test output.
timingRe = regexp.MustCompile(`[0-9]+\.[0-9]{2,}s`)
)
func zeroTimings(line string) string {
return timingRe.ReplaceAllString(line, "0.00s")
}
func goldenPath(path ...string) string {
full := append([]string{goldenDir}, path...)
return filepath.Join(full...)
}
func goldenFile(t *testing.T, path ...string) []byte {
fullPath := goldenPath(path...)
f, err := os.Open(fullPath)
if err != nil {
t.Fatalf("golden: could not open file %v for reading: %v", fullPath, err)
}
defer f.Close()
b, err := ioutil.ReadAll(f)
if err != nil {
t.Fatalf("golden: could not read file %v: %v", fullPath, err)
}
return b
}
func updateGoldenFile(t *testing.T, body []byte, path ...string) {
fullPath := goldenPath(path...)
f, err := os.Create(fullPath)
if err != nil {
t.Fatalf("golden: could not open file %v for writing: %v", fullPath, err)
}
defer f.Close()
for len(body) > 0 {
n, err := f.Write(body)
if err != nil {
t.Fatalf("golden: could not write to file %v: %v", fullPath, err)
}
body = body[n:]
}
}
func TestMain(m *testing.M) {
flag.Parse()
os.Exit(m.Run())
}
func TestVerboseOutput(t *testing.T) {
got, err := exec.Command("go", "test", "-v", "-tags", "goldenoutput", "-run", "TestNestedStructure").CombinedOutput()
if err != nil {
t.Fatalf("golden: tests failed: %v", err)
}
fn := "verbose.out"
if *update {
updateGoldenFile(t, got, fn)
return
}
// All tests run in parallel, so we can't rely on the lines coming out in
// the same order. But we _can_ test that all lines exist in the output,
// complete with matching indentation.
//
// This is mainly to prove that t.Run calls are nested properly.
want := goldenFile(t, fn)
wantedLines := strings.Split(string(want), "\n")
gotLines := strings.Split(string(got), "\n")
if len(wantedLines) != len(gotLines) {
t.Fatalf("expected %d lines of output; got %d", len(wantedLines), len(gotLines))
}
for _, wl := range wantedLines {
wl = zeroTimings(wl)
found := false
for i, gl := range gotLines {
gl = zeroTimings(gl)
if wl == gl {
gotLines = append(gotLines[:i], gotLines[i+1:]...)
found = true
break
}
}
if !found {
t.Errorf("missing line %v in actual output", wl)
}
}
for _, l := range gotLines {
t.Errorf("extra line %v in actual output", l)
}
}
|