-
-
Notifications
You must be signed in to change notification settings - Fork 26
/
util.go
144 lines (118 loc) · 3.54 KB
/
util.go
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package cupaloy
import (
"bytes"
"errors"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
"github.com/bradleyjkemp/cupaloy/v2/internal"
"github.com/davecgh/go-spew/spew"
"github.com/pmezard/go-difflib/difflib"
)
//go:generate $GOPATH/bin/mockery -output=examples -outpkg=examples_test -testonly -name=TestingT
// TestingT is a subset of the interface testing.TB allowing it to be mocked in tests.
type TestingT interface {
Helper()
Failed() bool
Error(args ...interface{})
Fatal(args ...interface{})
Name() string
}
func getNameOfCaller() string {
pc, _, _, _ := runtime.Caller(2) // first caller is the caller of this function, we want the caller of our caller
fullPath := runtime.FuncForPC(pc).Name()
packageFunctionName := filepath.Base(fullPath)
return strings.Replace(packageFunctionName, ".", "-", -1)
}
func envVariableSet(envVariable string) bool {
_, varSet := os.LookupEnv(envVariable)
return varSet
}
func (c *Config) getSpewConfig() *spew.ConfigState {
return &spew.ConfigState{
Indent: " ",
SortKeys: true, // maps should be spewed in a deterministic order
DisablePointerAddresses: true, // don't spew the addresses of pointers
DisableCapacities: true, // don't spew capacities of collections
SpewKeys: true, // if unable to sort map keys then spew keys to strings and sort those
DisableMethods: !c.useStringerMethods,
}
}
func (c *Config) snapshotFilePath(testName string) string {
return filepath.Join(c.subDirName, testName+c.snapshotFileExtension)
}
// Legacy snapshot format where all items were spewed
func (c *Config) takeV1Snapshot(i ...interface{}) string {
return c.getSpewConfig().Sdump(i...)
}
// New snapshot format where some types are written out raw to the file
func (c *Config) takeSnapshot(i ...interface{}) string {
snapshot := &bytes.Buffer{}
for _, v := range i {
switch vt := v.(type) {
case string:
snapshot.WriteString(vt)
snapshot.WriteString("\n")
case []byte:
snapshot.Write(vt)
snapshot.WriteString("\n")
default:
c.getSpewConfig().Fdump(snapshot, v)
}
}
return snapshot.String()
}
func (c *Config) readSnapshot(snapshotName string) (string, error) {
snapshotFile := c.snapshotFilePath(snapshotName)
buf, err := ioutil.ReadFile(snapshotFile)
if os.IsNotExist(err) {
return "", err
}
if err != nil {
return "", err
}
return string(buf), nil
}
func (c *Config) updateSnapshot(snapshotName string, prevSnapshot string, snapshot string) error {
// check that subdirectory exists before writing snapshot
err := os.MkdirAll(c.subDirName, os.ModePerm)
if err != nil {
return errors.New("could not create snapshots directory")
}
snapshotFile := c.snapshotFilePath(snapshotName)
_, err = os.Stat(snapshotFile)
isNewSnapshot := os.IsNotExist(err)
err = ioutil.WriteFile(snapshotFile, []byte(snapshot), os.FileMode(0644))
if err != nil {
return err
}
if !c.failOnUpdate {
//TODO: should a warning still be printed here?
return nil
}
snapshotDiff := c.diffSnapshots(prevSnapshot, snapshot)
if isNewSnapshot {
return internal.ErrSnapshotCreated{
Name: snapshotName,
Contents: snapshot,
}
}
return internal.ErrSnapshotUpdated{
Name: snapshotName,
Diff: snapshotDiff,
}
}
func diffSnapshots(previous, current string) string {
diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
A: difflib.SplitLines(previous),
B: difflib.SplitLines(current),
FromFile: "Previous",
FromDate: "",
ToFile: "Current",
ToDate: "",
Context: 1,
})
return diff
}