1 package assert_test
2
3 import (
4 "go/ast"
5 "go/parser"
6 "go/token"
7 "os"
8 "runtime"
9 "strings"
10 "testing"
11
12 "gotest.tools/v3/assert"
13 "gotest.tools/v3/internal/source"
14 )
15
16 func TestEqual_WithGoldenUpdate(t *testing.T) {
17 t.Run("assert failed with -update=false", func(t *testing.T) {
18 ft := &fakeTestingT{}
19 actual := `not this value`
20 assert.Equal(ft, actual, expectedOne)
21 assert.Assert(t, ft.failNowed)
22 })
23
24 t.Run("var is updated when -update=true", func(t *testing.T) {
25 patchUpdate(t)
26 t.Cleanup(func() {
27 resetVariable(t, "expectedOne", "")
28 })
29
30 actual := `this is the
31 actual value
32 that we are testing
33 `
34 assert.Equal(t, actual, expectedOne)
35
36 raw, err := os.ReadFile(fileName(t))
37 assert.NilError(t, err)
38
39 expected := "var expectedOne = `this is the\nactual value\nthat we are testing\n`"
40 assert.Assert(t, strings.Contains(string(raw), expected), "actual=%v", string(raw))
41 })
42
43 t.Run("const is updated when -update=true", func(t *testing.T) {
44 patchUpdate(t)
45 t.Cleanup(func() {
46 resetVariable(t, "expectedTwo", "")
47 })
48
49 actual := `this is the new
50 expected value
51 `
52 assert.Equal(t, actual, expectedTwo)
53
54 raw, err := os.ReadFile(fileName(t))
55 assert.NilError(t, err)
56
57 expected := "const expectedTwo = `this is the new\nexpected value\n`"
58 assert.Assert(t, strings.Contains(string(raw), expected), "actual=%v", string(raw))
59 })
60
61 t.Run("var inside function is updated when -update=true", func(t *testing.T) {
62 patchUpdate(t)
63 t.Cleanup(func() {
64 resetVariable(t, "expectedInsideFunc", "")
65 })
66
67 actual := `this is the new
68 expected value
69 for var inside function
70 `
71 expectedInsideFunc := ``
72
73 assert.Equal(t, actual, expectedInsideFunc)
74
75 raw, err := os.ReadFile(fileName(t))
76 assert.NilError(t, err)
77
78 expected := "expectedInsideFunc := `this is the new\nexpected value\nfor var inside function\n`"
79 assert.Assert(t, strings.Contains(string(raw), expected), "actual=%v", string(raw))
80 })
81
82 t.Run("const inside function is updated when -update=true", func(t *testing.T) {
83 patchUpdate(t)
84 t.Cleanup(func() {
85 resetVariable(t, "expectedConstInsideFunc", "")
86 })
87
88 actual := `this is the new
89 expected value
90 for const inside function
91 `
92 const expectedConstInsideFunc = ``
93
94 assert.Equal(t, actual, expectedConstInsideFunc)
95
96 raw, err := os.ReadFile(fileName(t))
97 assert.NilError(t, err)
98
99 expected := "const expectedConstInsideFunc = `this is the new\nexpected value\nfor const inside function\n`"
100 assert.Assert(t, strings.Contains(string(raw), expected), "actual=%v", string(raw))
101 })
102 }
103
104
105 var expectedOne = ``
106
107
108 const expectedTwo = ``
109
110 func patchUpdate(t *testing.T) {
111 source.Update = true
112 t.Cleanup(func() {
113 source.Update = false
114 })
115 }
116
117 func fileName(t *testing.T) string {
118 t.Helper()
119 _, filename, _, ok := runtime.Caller(1)
120 assert.Assert(t, ok, "failed to get call stack")
121 return filename
122 }
123
124 func resetVariable(t *testing.T, varName string, value string) {
125 t.Helper()
126 _, filename, _, ok := runtime.Caller(1)
127 assert.Assert(t, ok, "failed to get call stack")
128
129 fileset := token.NewFileSet()
130 astFile, err := parser.ParseFile(fileset, filename, nil, parser.AllErrors|parser.ParseComments)
131 assert.NilError(t, err)
132
133 var ident *ast.Ident
134 ast.Inspect(astFile, func(n ast.Node) bool {
135 switch v := n.(type) {
136 case *ast.AssignStmt:
137 if len(v.Lhs) == 1 {
138 if id, ok := v.Lhs[0].(*ast.Ident); ok {
139 if id.Name == varName {
140 ident = id
141 return false
142 }
143 }
144 }
145
146 case *ast.ValueSpec:
147 for _, id := range v.Names {
148 if id.Name == varName {
149 ident = id
150 return false
151 }
152 }
153 }
154
155 return true
156 })
157 assert.Assert(t, ident != nil, "failed to get ident for %s", varName)
158
159 err = source.UpdateVariable(filename, fileset, astFile, ident, value)
160 assert.NilError(t, err, "failed to reset file")
161 }
162
163 type fakeTestingT struct {
164 failNowed bool
165 failed bool
166 msgs []string
167 }
168
169 func (f *fakeTestingT) FailNow() {
170 f.failNowed = true
171 }
172
173 func (f *fakeTestingT) Fail() {
174 f.failed = true
175 }
176
177 func (f *fakeTestingT) Log(args ...interface{}) {
178 f.msgs = append(f.msgs, args[0].(string))
179 }
180
181 func (f *fakeTestingT) Helper() {}
182
View as plain text