Skip to content

Commit 5f8fc40

Browse files
committed
Leverage go/packages/packagestest for testing
1 parent 1fd4a45 commit 5f8fc40

File tree

29 files changed

+1760
-484
lines changed

29 files changed

+1760
-484
lines changed

go.sum

-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,2 @@
1-
golang.org/x/tools v0.0.0-20181008205924-a2b3f7f249e9 h1:T3nuFyXXDj5KXX9CqQm/r/YEL4Gua01s/ZEdfdLyJ2c=
2-
golang.org/x/tools v0.0.0-20181008205924-a2b3f7f249e9/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
3-
golang.org/x/tools v0.0.0-20181019005945-6adeb8aab2de h1:kT+Ec4AyesVdjJuyBnwnKai/sOSk8JMYn9jetb8bO5s=
4-
golang.org/x/tools v0.0.0-20181019005945-6adeb8aab2de/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
51
golang.org/x/tools v0.0.0-20181207195948-8634b1ecd393 h1:0P8IF6+RwCumULxvjp9EtJryUs46MgLIgeHbCt7NU4Q=
62
golang.org/x/tools v0.0.0-20181207195948-8634b1ecd393/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

ident_test.go

+84-212
Original file line numberDiff line numberDiff line change
@@ -1,244 +1,116 @@
11
package main
22

33
import (
4-
"fmt"
5-
"os"
4+
"go/token"
65
"path/filepath"
76
"strings"
87
"testing"
98

10-
"golang.org/x/tools/go/buildutil"
9+
"golang.org/x/tools/go/packages/packagestest"
1110
)
1211

1312
func TestIdent(t *testing.T) {
14-
cleanup := setGopath(filepath.Join(".", "testdata", "package"), t)
15-
defer cleanup()
16-
filename := filepath.Join(".", "testdata", "package", "src", "somepkg", "idents.go")
17-
18-
tests := []struct {
19-
Pos int
20-
Doc string
21-
Decl string
22-
}{
23-
{Pos: 146, Doc: "IsNaN reports whether f is an IEEE 754 ``not-a-number'' value.\n", Decl: "func IsNaN(f float64) (is bool)"}, // std func call (alias import)
24-
{Pos: 190, Doc: "SayHello says hello.\n", Decl: "func (X) SayHello()"}, // method call
25-
{Pos: 202, Doc: "SayGoodbye says goodbye.\n", Decl: "func SayGoodbye() (string, error)"}, // function call
26-
{Pos: 319, Doc: "Message is a message.\n", Decl: "var Message string"}, // var (use)
27-
{Pos: 415, Doc: "Message is a message.\n"}, // var (definition)
28-
{Pos: 329, Doc: "Sprintf formats according to a format specifier and returns the resulting string.\n"}, // std func
29-
{Pos: 358, Doc: "Answer is the answer to life the universe and everything.\n\nConstant Value: 42", Decl: "const Answer untyped int"}, // const (use)
30-
{Pos: 510, Doc: "Answer is the answer to life the universe and everything.\n\nConstant Value: 42"}, // const (definition)
31-
32-
// field doc/comment precedence
33-
{Pos: 656, Doc: "FieldA has doc\n", Decl: "field FieldA string"},
34-
{Pos: 665, Doc: "FieldB has a comment\n"},
35-
36-
// GenDecl doc/comment precedence
37-
{Pos: 1017, Doc: "Alpha doc", Decl: "var Alpha int"},
38-
{Pos: 1032, Doc: "Bravo comment", Decl: "var Bravo int"},
39-
40-
// builtins
41-
{Pos: 975, Doc: "The error built-in interface type is the conventional"},
42-
{Pos: 735, Doc: "The append built-in function appends elements to the end", Decl: "func append(slice []Type, elems ...Type) []Type"},
43-
{Pos: 762, Doc: "float32 is the set of all IEEE-754 32-bit floating-point numbers."},
44-
{Pos: 821, Doc: "iota is a predeclared identifier representing the untyped integer ordinal"},
45-
{Pos: 864, Doc: "nil is a predeclared identifier representing the zero"},
46-
{Pos: 914, Doc: "The len built-in function returns the length of v"},
47-
{Pos: 950, Doc: "The close built-in function closes a channel, which must"},
48-
49-
// type spec
50-
{Pos: 53, Decl: "type X struct{}"},
51-
{Pos: 1222, Decl: "type NewString string"},
13+
dir := filepath.Join(".", "testdata", "package")
14+
mods := []packagestest.Module{
15+
{Name: "somepkg", Files: packagestest.MustCopyFileTree(dir)},
5216
}
5317

54-
for _, test := range tests {
55-
t.Run(fmt.Sprintf("ident pos %d", test.Pos), func(t *testing.T) {
56-
doc, err := Run(filename, test.Pos, nil)
57-
if err != nil {
58-
t.Fatal(err)
59-
}
60-
if !strings.HasPrefix(doc.Doc, test.Doc) {
61-
t.Errorf("Want %q, got %q\n", test.Doc, doc.Doc)
62-
}
63-
if test.Decl != "" && doc.Decl != test.Decl {
64-
t.Errorf("Decl: want %q, got %q\n", test.Decl, doc.Decl)
65-
}
66-
})
67-
}
68-
}
69-
70-
func TestModified(t *testing.T) {
71-
cleanup := setGopath(filepath.Join(".", "testdata", "package"), t)
72-
defer cleanup()
73-
74-
filename := filepath.Join(".", "testdata", "package", "src", "somepkg", "const.go")
75-
path, err := filepath.Abs(filename)
76-
if err != nil {
77-
t.Fatal(err)
78-
}
79-
contents := `package somepkg
80-
81-
import "fmt"
82-
83-
const (
84-
Zero = iota
85-
One
86-
Two
87-
)
88-
89-
const Three = 3
90-
91-
func main() {
92-
fmt.Println(Zero, Three, Two, Three)
93-
}
94-
`
95-
archive := fmt.Sprintf("%s\n%d\n%s", path, len(contents), contents)
96-
overlay, err := buildutil.ParseOverlayArchive(strings.NewReader(archive))
97-
if err != nil {
98-
t.Fatalf("couldn't parse overlay: %v", err)
99-
}
100-
101-
d, err := Run(path, 118, overlay)
102-
if err != nil {
103-
t.Fatal(err)
104-
}
105-
if n := d.Name; n != "Three" {
106-
t.Errorf("got const %s, want Three", n)
107-
}
108-
}
109-
110-
func TestConstantValue(t *testing.T) {
111-
cleanup := setGopath(filepath.Join(".", "testdata", "package"), t)
112-
defer cleanup()
113-
filename := filepath.Join(".", "testdata", "package", "src", "somepkg", "const.go")
114-
115-
for _, offset := range []int{111, 116, 121, 128} {
116-
doc, err := Run(filename, offset, nil)
117-
if err != nil {
118-
t.Error(err)
18+
packagestest.TestAll(t, func(t *testing.T, exporter packagestest.Exporter) {
19+
if exporter == packagestest.Modules {
20+
return // TODO get working with Modules and GOPATH
11921
}
120-
if !strings.Contains(doc.Doc, "Constant Value:") {
121-
t.Errorf("Expected doc to contain constant value: %q", doc.Doc)
122-
}
123-
}
124-
}
22+
exported := packagestest.Export(t, exporter, mods)
23+
defer exported.Cleanup()
12524

126-
func TestUnexportedFields(t *testing.T) {
127-
cleanup := setGopath(filepath.Join(".", "testdata", "package"), t)
128-
defer cleanup()
129-
filename := filepath.Join(".", "testdata", "package", "src", "somepkg", "idents.go")
25+
teardown := setup(exported.Config)
26+
defer teardown()
13027

131-
for _, showUnexported := range []bool{true, false} {
132-
*showUnexportedFields = showUnexported
133-
doc, err := Run(filename, 1085, nil)
134-
if err != nil {
135-
t.Fatalf("showUnexportedFields=%v: %v", showUnexported, err)
136-
}
137-
hasUnexportedField := strings.Contains(doc.Decl, "notVisible")
138-
if hasUnexportedField != *showUnexportedFields {
139-
t.Errorf("show unexported fields is %v, but got %q", showUnexported, doc.Decl)
140-
}
141-
}
142-
}
143-
144-
func TestEmbeddedTypes(t *testing.T) {
145-
cleanup := setGopath(filepath.Join(".", "testdata", "package"), t)
146-
defer cleanup()
147-
filename := filepath.Join(".", "testdata", "package", "src", "somepkg", "embed.go")
148-
149-
tests := []struct {
150-
description string
151-
offset int
152-
want string
153-
}{
154-
{"embedded value", 77, "foo doc\n"},
155-
{"embedded pointer", 113, "foo doc\n"},
156-
}
157-
158-
for _, test := range tests {
159-
t.Run(test.description, func(t *testing.T) {
160-
doc, err := Run(filename, test.offset, nil)
161-
if err != nil {
162-
t.Fatal(err)
163-
}
164-
if doc.Doc != test.want {
165-
t.Errorf("want %q, got %q", test.want, doc.Doc)
28+
getDoc := func(p token.Position) *Doc {
29+
t.Helper()
30+
doc, docErr := Run(p.Filename, p.Offset, nil)
31+
if docErr != nil {
32+
t.Fatal(docErr)
16633
}
167-
if doc.Pkg != "somepkg" {
168-
t.Errorf("want package somepkg, got %q", doc.Pkg)
169-
}
170-
})
171-
}
172-
}
173-
174-
func TestIssue20(t *testing.T) {
175-
cleanup := setGopath(filepath.Join(".", "testdata", "package"), t)
176-
defer cleanup()
177-
filename := filepath.Join(".", "testdata", "package", "src", "somepkg", "issue20.go")
34+
return doc
35+
}
17836

179-
tests := []struct {
180-
desc string
181-
want string
182-
offset int
183-
}{
184-
{"named type", "var words []string", 116},
185-
{"unnamed type", "var tests []struct{Name string; args string}", 283},
186-
}
187-
for _, test := range tests {
188-
t.Run(test.desc, func(t *testing.T) {
189-
doc, err := Run(filename, test.offset, nil)
190-
if err != nil {
191-
t.Fatal(err)
37+
pcmp := func(want, got string) {
38+
t.Helper()
39+
if !strings.HasPrefix(got, want) {
40+
if len(got) > 64 {
41+
got = got[:64]
42+
}
43+
t.Errorf("expected prefix %q in %q", want, got)
19244
}
45+
}
19346

194-
if doc.Decl != test.want {
195-
t.Errorf("want %s, got %s", test.want, doc.Decl)
47+
cmp := func(want, got string) {
48+
t.Helper()
49+
if got != want {
50+
t.Errorf("want %q, got %q", want, got)
19651
}
52+
}
19753

198-
if doc.Doc != "" {
199-
t.Errorf("expect doc to be empty, but got %q", doc.Doc)
200-
}
201-
})
202-
}
54+
if expectErr := exported.Expect(map[string]interface{}{
55+
"doc": func(p token.Position, doc string) { pcmp(doc, getDoc(p).Doc) },
56+
"pkg": func(p token.Position, pkg string) { cmp(pkg, getDoc(p).Pkg) },
57+
"decl": func(p token.Position, decl string) { cmp(decl, getDoc(p).Decl) },
58+
"const": func(p token.Position, val string) {
59+
d := getDoc(p)
60+
needle := "Constant Value: " + val
61+
if !strings.Contains(d.Doc, needle) {
62+
t.Errorf("Expected %q in %q", needle, d.Doc)
63+
}
64+
},
65+
"exported": func(p token.Position) {
66+
for _, showUnexported := range []bool{true, false} {
67+
*showUnexportedFields = showUnexported
68+
d := getDoc(p)
69+
hasUnexportedField := strings.Contains(d.Decl, "notVisible")
70+
if hasUnexportedField != *showUnexportedFields {
71+
t.Errorf("show unexported fields is %v, but got %q", showUnexported, d.Decl)
72+
}
73+
}
74+
},
75+
}); expectErr != nil {
76+
t.Fatal(expectErr)
77+
}
78+
})
20379
}
20480

205-
func TestVendoredIdent(t *testing.T) {
206-
cleanup := setGopath(filepath.Join(".", "testdata", "withvendor"), t)
207-
defer cleanup()
208-
209-
filename := filepath.Join(".", "testdata", "withvendor", "src", "main", "main.go")
210-
doc, err := Run(filename, 76, nil)
211-
if err != nil {
212-
t.Fatal(err)
81+
func TestVendoredCode(t *testing.T) {
82+
dir := filepath.Join(".", "testdata", "withvendor")
83+
mods := []packagestest.Module{
84+
{Name: "main", Files: packagestest.MustCopyFileTree(dir)},
21385
}
21486

215-
want := "github.com/zmb3/vp"
216-
if doc.Import != want {
217-
t.Errorf("want %s, got %s", want, doc.Import)
218-
}
219-
if doc.Doc != "Hello says hello.\n" {
220-
t.Errorf("want 'Hello says hello.\n', got %q", doc.Doc)
221-
}
87+
exported := packagestest.Export(t, packagestest.GOPATH, mods)
88+
defer exported.Cleanup()
22289

223-
doc, err = Run(filename, 99, nil)
224-
if err != nil {
225-
t.Fatal(err)
226-
}
90+
teardown := setup(exported.Config)
91+
defer teardown()
22792

228-
decl := `const Foo untyped string`
229-
if decl != doc.Decl {
230-
t.Errorf("invalid decl: want %q, got %q", decl, doc.Decl)
93+
filename := exported.File("main", "main.go")
94+
getDoc := func(p token.Position) *Doc {
95+
t.Helper()
96+
doc, docErr := Run(filename, p.Offset, nil)
97+
if docErr != nil {
98+
t.Fatal(docErr)
99+
}
100+
return doc
231101
}
232-
}
233102

234-
func setGopath(path string, t *testing.T) func() {
235-
t.Helper()
103+
compare := func(want, got string) {
104+
if want != got {
105+
t.Errorf("want %q, got %q", want, got)
106+
}
107+
}
236108

237-
orig := os.Getenv("GOPATH")
238-
abs, err := filepath.Abs(path)
239-
if err != nil {
240-
t.Fatal(err)
109+
if expectErr := exported.Expect(map[string]interface{}{
110+
"import": func(p token.Position, path string) { compare(path, getDoc(p).Import) },
111+
"decl": func(p token.Position, decl string) { compare(decl, getDoc(p).Decl) },
112+
"doc": func(p token.Position, doc string) { compare(doc, getDoc(p).Doc) },
113+
}); expectErr != nil {
114+
t.Fatal(expectErr)
241115
}
242-
os.Setenv("GOPATH", abs)
243-
return func() { os.Setenv("GOPATH", orig) }
244116
}

0 commit comments

Comments
 (0)