1
2
3
4
5
6
7
8
9
10 package eg_test
11
12 import (
13 "bytes"
14 "flag"
15 "go/build"
16 "go/constant"
17 "go/parser"
18 "go/token"
19 "go/types"
20 "os"
21 "os/exec"
22 "path/filepath"
23 "runtime"
24 "strings"
25 "testing"
26
27 "golang.org/x/tools/go/loader"
28 "golang.org/x/tools/internal/testenv"
29 "golang.org/x/tools/refactor/eg"
30 )
31
32
33
34
35
36
37
38 var (
39 updateFlag = flag.Bool("update", false, "update the golden files")
40 verboseFlag = flag.Bool("verbose", false, "show matcher information")
41 )
42
43 func Test(t *testing.T) {
44 testenv.NeedsTool(t, "go")
45
46 switch runtime.GOOS {
47 case "windows":
48 t.Skipf("skipping test on %q (no /usr/bin/diff)", runtime.GOOS)
49 }
50
51 ctx := build.Default
52 ctx.CgoEnabled = false
53 conf := loader.Config{
54 Fset: token.NewFileSet(),
55 ParserMode: parser.ParseComments,
56 Build: &ctx,
57 }
58
59
60
61
62
63 for _, filename := range []string{
64 "testdata/A.template",
65 "testdata/A1.go",
66 "testdata/A2.go",
67
68 "testdata/B.template",
69 "testdata/B1.go",
70
71 "testdata/C.template",
72 "testdata/C1.go",
73
74 "testdata/D.template",
75 "testdata/D1.go",
76
77 "testdata/E.template",
78 "testdata/E1.go",
79
80 "testdata/F.template",
81 "testdata/F1.go",
82
83 "testdata/G.template",
84 "testdata/G1.go",
85
86 "testdata/H.template",
87 "testdata/H1.go",
88
89 "testdata/I.template",
90 "testdata/I1.go",
91
92 "testdata/J.template",
93 "testdata/J1.go",
94
95 "testdata/bad_type.template",
96 "testdata/no_before.template",
97 "testdata/no_after_return.template",
98 "testdata/type_mismatch.template",
99 "testdata/expr_type_mismatch.template",
100 } {
101 pkgname := strings.TrimSuffix(filepath.Base(filename), ".go")
102 conf.CreateFromFilenames(pkgname, filename)
103 }
104 iprog, err := conf.Load()
105 if err != nil {
106 t.Fatal(err)
107 }
108
109 var xform *eg.Transformer
110 for _, info := range iprog.Created {
111 file := info.Files[0]
112 filename := iprog.Fset.File(file.Pos()).Name()
113
114 if strings.HasSuffix(filename, "template") {
115
116 shouldFail, _ := info.Pkg.Scope().Lookup("shouldFail").(*types.Const)
117 xform, err = eg.NewTransformer(iprog.Fset, info.Pkg, file, &info.Info, *verboseFlag)
118 if err != nil {
119 if shouldFail == nil {
120 t.Errorf("NewTransformer(%s): %s", filename, err)
121 } else if want := constant.StringVal(shouldFail.Val()); !strings.Contains(normalizeAny(err.Error()), want) {
122 t.Errorf("NewTransformer(%s): got error %q, want error %q", filename, err, want)
123 }
124 } else if shouldFail != nil {
125 t.Errorf("NewTransformer(%s) succeeded unexpectedly; want error %q",
126 filename, shouldFail.Val())
127 }
128 continue
129 }
130
131 if xform == nil {
132 t.Errorf("%s: no previous template", filename)
133 continue
134 }
135
136
137 n := xform.Transform(&info.Info, info.Pkg, file)
138 if n == 0 {
139 t.Errorf("%s: no matches", filename)
140 continue
141 }
142
143 gotf, err := os.CreateTemp("", filepath.Base(filename)+"t")
144 if err != nil {
145 t.Fatal(err)
146 }
147 got := gotf.Name()
148 golden := filename + "lden"
149
150
151 if err := eg.WriteAST(iprog.Fset, got, file); err != nil {
152 t.Error(err)
153 }
154 defer os.Remove(got)
155
156
157 var cmd *exec.Cmd
158 switch runtime.GOOS {
159 case "plan9":
160 cmd = exec.Command("/bin/diff", "-c", golden, got)
161 default:
162 cmd = exec.Command("/usr/bin/diff", "-u", golden, got)
163 }
164 buf := new(bytes.Buffer)
165 cmd.Stdout = buf
166 cmd.Stderr = os.Stderr
167 if err := cmd.Run(); err != nil {
168 t.Errorf("eg tests for %s failed: %s.\n%s\n", filename, err, buf)
169
170 if *updateFlag {
171 t.Logf("Updating %s...", golden)
172 if err := exec.Command("/bin/cp", got, golden).Run(); err != nil {
173 t.Errorf("Update failed: %s", err)
174 }
175 }
176 }
177 }
178 }
179
180
181
182 func normalizeAny(s string) string {
183 return strings.ReplaceAll(s, "interface{}", "any")
184 }
185
View as plain text