internal/lsp: make the guru emulation tests slightly looser with a different matching system
We now match only the things we realy need to, to allow the description to vary more.
Change-Id: Ib3591c41ed5a5c725f2a3efb180ba17f808de51a
Reviewed-on: https://go-review.googlesource.com/c/tools/+/170341
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
diff --git a/internal/lsp/cmd/definition_test.go b/internal/lsp/cmd/definition_test.go
index 0c10737..06951a5 100644
--- a/internal/lsp/cmd/definition_test.go
+++ b/internal/lsp/cmd/definition_test.go
@@ -29,10 +29,10 @@
)
type definition struct {
- src span.Span
- flags string
- def span.Span
- match string
+ src span.Span
+ flags string
+ def span.Span
+ pattern pattern
}
type definitions map[span.Span]definition
@@ -66,24 +66,26 @@
func (l definitions) godef(src, def span.Span) {
l[src] = definition{
- src: src,
- def: def,
+ src: src,
+ def: def,
+ pattern: newPattern("", def),
}
}
func (l definitions) typdef(src, def span.Span) {
l[src] = definition{
- src: src,
- def: def,
+ src: src,
+ def: def,
+ pattern: newPattern("", def),
}
}
func (l definitions) definition(src span.Span, flags string, def span.Span, match string) {
l[src] = definition{
- src: src,
- flags: flags,
- def: def,
- match: match,
+ src: src,
+ flags: flags,
+ def: def,
+ pattern: newPattern(match, def),
}
}
@@ -104,76 +106,41 @@
got := captureStdOut(t, func() {
tool.Main(context.Background(), app, args)
})
- if d.match == "" {
- expect := fmt.Sprint(d.def)
- if !strings.HasPrefix(got, expect) {
- t.Errorf("definition %v\nexpected:\n%s\ngot:\n%s", args, expect, got)
- }
- } else {
- expect := os.Expand(d.match, func(name string) string {
- switch name {
- case "file":
- fname, _ := d.def.URI().Filename()
- return fname
- case "efile":
- fname, _ := d.def.URI().Filename()
- qfile := strconv.Quote(fname)
- return qfile[1 : len(qfile)-1]
- case "euri":
- quri := strconv.Quote(string(d.def.URI()))
- return quri[1 : len(quri)-1]
- case "line":
- return fmt.Sprint(d.def.Start().Line())
- case "col":
- return fmt.Sprint(d.def.Start().Column())
- case "offset":
- return fmt.Sprint(d.def.Start().Offset())
- case "eline":
- return fmt.Sprint(d.def.End().Line())
- case "ecol":
- return fmt.Sprint(d.def.End().Column())
- case "eoffset":
- return fmt.Sprint(d.def.End().Offset())
- default:
- return name
- }
- })
- if expect != got {
- t.Errorf("definition %v\nexpected:\n%s\ngot:\n%s", args, expect, got)
- }
- if *verifyGuru {
- moduleMode := e.File(e.Modules[0].Name, "go.mod") != ""
- var guruArgs []string
- runGuru := false
- if !moduleMode {
- for _, arg := range args {
- switch {
- case arg == "query":
- // just ignore this one
- case arg == "-json":
- guruArgs = append(guruArgs, arg)
- case arg == "-emulate=guru":
- // if we don't see this one we should not run guru
- runGuru = true
- case strings.HasPrefix(arg, "-"):
- // unknown flag, ignore it
- break
- default:
- guruArgs = append(guruArgs, arg)
- }
+ if !d.pattern.matches(got) {
+ t.Errorf("definition %v\nexpected:\n%s\ngot:\n%s", args, d.pattern, got)
+ }
+ if *verifyGuru {
+ moduleMode := e.File(e.Modules[0].Name, "go.mod") != ""
+ var guruArgs []string
+ runGuru := false
+ if !moduleMode {
+ for _, arg := range args {
+ switch {
+ case arg == "query":
+ // just ignore this one
+ case arg == "-json":
+ guruArgs = append(guruArgs, arg)
+ case arg == "-emulate=guru":
+ // if we don't see this one we should not run guru
+ runGuru = true
+ case strings.HasPrefix(arg, "-"):
+ // unknown flag, ignore it
+ break
+ default:
+ guruArgs = append(guruArgs, arg)
}
}
- if runGuru {
- cmd := exec.Command("guru", guruArgs...)
- cmd.Env = e.Config.Env
- out, err := cmd.CombinedOutput()
- if err != nil {
- t.Errorf("Could not run guru %v: %v\n%s", guruArgs, err, out)
- } else {
- guru := strings.TrimSpace(string(out))
- if !strings.HasPrefix(expect, guru) {
- t.Errorf("definition %v\nexpected:\n%s\nguru gave:\n%s", args, expect, guru)
- }
+ }
+ if runGuru {
+ cmd := exec.Command("guru", guruArgs...)
+ cmd.Env = e.Config.Env
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Errorf("Could not run guru %v: %v\n%s", guruArgs, err, out)
+ } else {
+ guru := strings.TrimSpace(string(out))
+ if !d.pattern.matches(guru) {
+ t.Errorf("definition %v\nexpected:\n%s\nguru gave:\n%s", args, d.pattern, guru)
}
}
}
@@ -187,3 +154,74 @@
}
//TODO: add command line type definition tests when it works
}
+
+type pattern struct {
+ raw string
+ expanded []string
+ matchAll bool
+}
+
+func newPattern(s string, def span.Span) pattern {
+ p := pattern{raw: s}
+ if s == "" {
+ p.expanded = []string{fmt.Sprintf("%v: ", def)}
+ return p
+ }
+ p.matchAll = strings.HasSuffix(s, "$$")
+ for _, fragment := range strings.Split(s, "$$") {
+ p.expanded = append(p.expanded, os.Expand(fragment, func(name string) string {
+ switch name {
+ case "file":
+ fname, _ := def.URI().Filename()
+ return fname
+ case "efile":
+ fname, _ := def.URI().Filename()
+ qfile := strconv.Quote(fname)
+ return qfile[1 : len(qfile)-1]
+ case "euri":
+ quri := strconv.Quote(string(def.URI()))
+ return quri[1 : len(quri)-1]
+ case "line":
+ return fmt.Sprint(def.Start().Line())
+ case "col":
+ return fmt.Sprint(def.Start().Column())
+ case "offset":
+ return fmt.Sprint(def.Start().Offset())
+ case "eline":
+ return fmt.Sprint(def.End().Line())
+ case "ecol":
+ return fmt.Sprint(def.End().Column())
+ case "eoffset":
+ return fmt.Sprint(def.End().Offset())
+ default:
+ return name
+ }
+ }))
+ }
+ return p
+}
+
+func (p pattern) String() string {
+ return strings.Join(p.expanded, "$$")
+}
+
+func (p pattern) matches(s string) bool {
+ if len(p.expanded) == 0 {
+ return false
+ }
+ if !strings.HasPrefix(s, p.expanded[0]) {
+ return false
+ }
+ remains := s[len(p.expanded[0]):]
+ for _, fragment := range p.expanded[1:] {
+ i := strings.Index(remains, fragment)
+ if i < 0 {
+ return false
+ }
+ remains = remains[i+len(fragment):]
+ }
+ if !p.matchAll {
+ return true
+ }
+ return len(remains) == 0
+}
diff --git a/internal/lsp/testdata/godef/a/d.go b/internal/lsp/testdata/godef/a/d.go
index d4516ae..0b1498e 100644
--- a/internal/lsp/testdata/godef/a/d.go
+++ b/internal/lsp/testdata/godef/a/d.go
@@ -1,5 +1,7 @@
package a
+import "fmt"
+
type Thing struct { //@Thing
Member string //@Member
}
@@ -33,7 +35,7 @@
definition(aVar, "-emulate=guru", Other, "$file:$line:$col: defined here as var Other")
definition(aFunc, "", Things, "$file:$line:$col-$ecol: defined here as func Things(val []string) []Thing")
-definition(aFunc, "-emulate=guru", Things, "$file:$line:$col: defined here as func Things(val []string) []Thing")
+definition(aFunc, "-emulate=guru", Things, "$file:$line:$col: defined here as func Things")
definition(aMethod, "", Method, "$file:$line:$col-$ecol: defined here as func (Thing).Method(i int) string")
definition(aMethod, "-emulate=guru", Method, "$file:$line:$col: defined here as func (Thing).Method(i int) string")
@@ -63,6 +65,6 @@
}`)
definition(aStructType, "-json -emulate=guru", Thing, `{
"objpos": "$efile:$line:$col",
- "desc": "type Thing"
+ "desc": "type Thing$$"
}`)
*/
diff --git a/internal/lsp/testdata/godef/b/e.go b/internal/lsp/testdata/godef/b/e.go
index 7e0c417..6b2337a 100644
--- a/internal/lsp/testdata/godef/b/e.go
+++ b/internal/lsp/testdata/godef/b/e.go
@@ -15,14 +15,14 @@
/*@
definition(bStructType, "", Thing, "$file:$line:$col-$ecol: defined here as type a.Thing struct{Member string}")
-definition(bStructType, "-emulate=guru", Thing, "$file:$line:$col: defined here as type golang.org/x/tools/internal/lsp/godef/a.Thing")
+definition(bStructType, "-emulate=guru", Thing, "$file:$line:$col: defined here as type $$a.Thing")
definition(bMember, "", Member, "$file:$line:$col-$ecol: defined here as field Member string")
definition(bMember, "-emulate=guru", Member, "$file:$line:$col: defined here as field Member string")
definition(bVar, "", Other, "$file:$line:$col-$ecol: defined here as var a.Other a.Thing")
-definition(bVar, "-emulate=guru", Other, "$file:$line:$col: defined here as var golang.org/x/tools/internal/lsp/godef/a.Other")
+definition(bVar, "-emulate=guru", Other, "$file:$line:$col: defined here as var $$a.Other")
definition(bFunc, "", Things, "$file:$line:$col-$ecol: defined here as func a.Things(val []string) []a.Thing")
-definition(bFunc, "-emulate=guru", Things, "$file:$line:$col: defined here as func golang.org/x/tools/internal/lsp/godef/a.Things(val []string) []golang.org/x/tools/internal/lsp/godef/a.Thing")
+definition(bFunc, "-emulate=guru", Things, "$file:$line:$col: defined here as func $$a.Things")
*/