Skip to content

Commit c6f2f8e

Browse files
adonovangopherbot
authored andcommitted
refactor/eg: rewrite test without go/loader
Now, each template, its inputs and outputs are all packages within a single .txtar archive. Updates golang/go#69556 Change-Id: I95285487597df985a16879ea1f5cb6a75c77fa12 Reviewed-on: https://go-review.googlesource.com/c/tools/+/616215 LUCI-TryBot-Result: Go LUCI <[email protected]> Auto-Submit: Alan Donovan <[email protected]> Reviewed-by: Tim King <[email protected]>
1 parent 8b6849d commit c6f2f8e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+745
-610
lines changed

refactor/eg/eg_test.go

Lines changed: 112 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,22 @@ package eg_test
1212
import (
1313
"bytes"
1414
"flag"
15-
"go/build"
15+
"fmt"
1616
"go/constant"
17-
"go/parser"
18-
"go/token"
17+
"go/format"
1918
"go/types"
2019
"os"
21-
"os/exec"
2220
"path/filepath"
2321
"runtime"
2422
"strings"
2523
"testing"
2624

27-
"golang.org/x/tools/go/loader"
25+
"github.com/google/go-cmp/cmp"
26+
"golang.org/x/tools/go/packages"
2827
"golang.org/x/tools/internal/testenv"
28+
"golang.org/x/tools/internal/testfiles"
2929
"golang.org/x/tools/refactor/eg"
30+
"golang.org/x/tools/txtar"
3031
)
3132

3233
// TODO(adonovan): more tests:
@@ -41,80 +42,64 @@ var (
4142
)
4243

4344
func Test(t *testing.T) {
44-
testenv.NeedsTool(t, "go")
45+
testenv.NeedsGoPackages(t)
4546

4647
switch runtime.GOOS {
4748
case "windows":
4849
t.Skipf("skipping test on %q (no /usr/bin/diff)", runtime.GOOS)
4950
}
5051

51-
ctx := build.Default // copy
52-
ctx.CgoEnabled = false // don't use cgo
53-
conf := loader.Config{
54-
Fset: token.NewFileSet(),
55-
ParserMode: parser.ParseComments,
56-
Build: &ctx,
57-
}
58-
59-
// Each entry is a single-file package.
60-
// (Multi-file packages aren't interesting for this test.)
61-
// Order matters: each non-template package is processed using
62-
// the preceding template package.
52+
// Each txtar defines a package example.com/template and zero
53+
// or more input packages example.com/in/... on which to apply
54+
// it. The outputs are compared with the corresponding files
55+
// in example.com/out/...
6356
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",
57+
"testdata/a.txtar",
58+
"testdata/b.txtar",
59+
"testdata/c.txtar",
60+
"testdata/d.txtar",
61+
"testdata/e.txtar",
62+
"testdata/f.txtar",
63+
"testdata/g.txtar",
64+
"testdata/h.txtar",
65+
"testdata/i.txtar",
66+
"testdata/j.txtar",
67+
"testdata/bad_type.txtar",
68+
"testdata/no_before.txtar",
69+
"testdata/no_after_return.txtar",
70+
"testdata/type_mismatch.txtar",
71+
"testdata/expr_type_mismatch.txtar",
10072
} {
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() // foo.go
73+
t.Run(filename, func(t *testing.T) {
74+
// Extract and load packages from test archive.
75+
dir := testfiles.ExtractTxtarFileToTmp(t, filename)
76+
cfg := packages.Config{
77+
Mode: packages.LoadAllSyntax,
78+
Dir: dir,
79+
}
80+
pkgs, err := packages.Load(&cfg, "example.com/template", "example.com/in/...")
81+
if err != nil {
82+
t.Fatal(err)
83+
}
84+
if packages.PrintErrors(pkgs) > 0 {
85+
t.Fatal("Load: there were errors")
86+
}
11387

114-
if strings.HasSuffix(filename, "template") {
115-
// a new template
116-
shouldFail, _ := info.Pkg.Scope().Lookup("shouldFail").(*types.Const)
117-
xform, err = eg.NewTransformer(iprog.Fset, info.Pkg, file, &info.Info, *verboseFlag)
88+
// Find and compile the template.
89+
var template *packages.Package
90+
var inputs []*packages.Package
91+
for _, pkg := range pkgs {
92+
if pkg.Types.Name() == "template" {
93+
template = pkg
94+
} else {
95+
inputs = append(inputs, pkg)
96+
}
97+
}
98+
if template == nil {
99+
t.Fatal("no template package")
100+
}
101+
shouldFail, _ := template.Types.Scope().Lookup("shouldFail").(*types.Const)
102+
xform, err := eg.NewTransformer(template.Fset, template.Types, template.Syntax[0], template.TypesInfo, *verboseFlag)
118103
if err != nil {
119104
if shouldFail == nil {
120105
t.Errorf("NewTransformer(%s): %s", filename, err)
@@ -125,55 +110,67 @@ func Test(t *testing.T) {
125110
t.Errorf("NewTransformer(%s) succeeded unexpectedly; want error %q",
126111
filename, shouldFail.Val())
127112
}
128-
continue
129-
}
130-
131-
if xform == nil {
132-
t.Errorf("%s: no previous template", filename)
133-
continue
134-
}
135-
136-
// apply previous template to this package
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() // foo.got
148-
golden := filename + "lden" // foo.golden
149-
150-
// Write actual output to foo.got.
151-
if err := eg.WriteAST(iprog.Fset, got, file); err != nil {
152-
t.Error(err)
153-
}
154-
defer os.Remove(got)
155-
156-
// Compare foo.got with foo.golden.
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)
169113

114+
// Apply template to each input package.
115+
updated := make(map[string][]byte)
116+
for _, pkg := range inputs {
117+
for _, file := range pkg.Syntax {
118+
filename, err := filepath.Rel(dir, pkg.Fset.File(file.FileStart).Name())
119+
if err != nil {
120+
t.Fatalf("can't relativize filename: %v", err)
121+
}
122+
123+
// Apply the transform and reformat.
124+
n := xform.Transform(pkg.TypesInfo, pkg.Types, file)
125+
if n == 0 {
126+
t.Fatalf("%s: no replacements", filename)
127+
}
128+
var got []byte
129+
{
130+
var out bytes.Buffer
131+
format.Node(&out, pkg.Fset, file) // ignore error
132+
got = out.Bytes()
133+
}
134+
135+
// Compare formatted output with out/<filename>
136+
// Errors here are not fatal, so we can proceed to -update.
137+
outfile := strings.Replace(filename, "in", "out", 1)
138+
updated[outfile] = got
139+
want, err := os.ReadFile(filepath.Join(dir, outfile))
140+
if err != nil {
141+
t.Errorf("can't read output file: %v", err)
142+
} else if diff := cmp.Diff(want, got); diff != "" {
143+
t.Errorf("Unexpected output:\n%s\n\ngot %s:\n%s\n\nwant %s:\n%s",
144+
diff,
145+
filename, got, outfile, want)
146+
}
147+
}
148+
}
149+
150+
// -update: replace the .txtar.
170151
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)
152+
ar, err := txtar.ParseFile(filename)
153+
if err != nil {
154+
t.Fatal(err)
155+
}
156+
157+
var new bytes.Buffer
158+
new.Write(ar.Comment)
159+
for _, file := range ar.Files {
160+
data, ok := updated[file.Name]
161+
if !ok {
162+
data = file.Data
163+
}
164+
fmt.Fprintf(&new, "-- %s --\n%s", file.Name, data)
165+
}
166+
t.Logf("Updating %s...", filename)
167+
os.Remove(filename + ".bak") // ignore error
168+
os.Rename(filename, filename+".bak") // ignore error
169+
if err := os.WriteFile(filename, new.Bytes(), 0666); err != nil {
170+
t.Fatal(err)
174171
}
175172
}
176-
}
173+
})
177174
}
178175
}
179176

refactor/eg/testdata/A.template

Lines changed: 0 additions & 11 deletions
This file was deleted.

refactor/eg/testdata/A1.go

Lines changed: 0 additions & 49 deletions
This file was deleted.

refactor/eg/testdata/A1.golden

Lines changed: 0 additions & 50 deletions
This file was deleted.

refactor/eg/testdata/A2.go

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)