mirror of
https://github.com/golang/go
synced 2024-11-18 20:54:40 -07:00
0268d3dd07
This upgrades the current gopls query definition tests to use the main testdata folder. This considerably increases the coverage and also sets us up to better test the other command line features as we add them. Change-Id: If722f3f6d0270104000f1451d20851daf0757874 Reviewed-on: https://go-review.googlesource.com/c/tools/+/169159 Run-TryBot: Ian Cottrell <iancottrell@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
190 lines
4.9 KiB
Go
190 lines
4.9 KiB
Go
// Copyright 2019 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package cmd_test
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"regexp"
|
|
"runtime"
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
|
|
"golang.org/x/tools/go/packages/packagestest"
|
|
"golang.org/x/tools/internal/lsp/cmd"
|
|
"golang.org/x/tools/internal/span"
|
|
"golang.org/x/tools/internal/tool"
|
|
)
|
|
|
|
const (
|
|
expectedDefinitionsCount = 25
|
|
expectedTypeDefinitionsCount = 2
|
|
)
|
|
|
|
type definition struct {
|
|
src span.Span
|
|
flags string
|
|
def span.Span
|
|
match string
|
|
}
|
|
|
|
type definitions map[span.Span]definition
|
|
|
|
var verifyGuru = flag.Bool("verify-guru", false, "Check that the guru compatability matches")
|
|
|
|
func TestDefinitionHelpExample(t *testing.T) {
|
|
if runtime.GOOS == "android" {
|
|
t.Skip("not all source files are available on android")
|
|
}
|
|
dir, err := os.Getwd()
|
|
if err != nil {
|
|
t.Errorf("could not get wd: %v", err)
|
|
return
|
|
}
|
|
thisFile := filepath.Join(dir, "definition.go")
|
|
baseArgs := []string{"query", "definition"}
|
|
expect := regexp.MustCompile(`^[\w/\\:_-]+flag[/\\]flag.go:\d+:\d+-\d+: defined here as type flag.FlagSet struct{.*}$`)
|
|
for _, query := range []string{
|
|
fmt.Sprintf("%v:%v:%v", thisFile, cmd.ExampleLine, cmd.ExampleColumn),
|
|
fmt.Sprintf("%v:#%v", thisFile, cmd.ExampleOffset)} {
|
|
args := append(baseArgs, query)
|
|
got := captureStdOut(t, func() {
|
|
tool.Main(context.Background(), &cmd.Application{}, args)
|
|
})
|
|
if !expect.MatchString(got) {
|
|
t.Errorf("test with %v\nexpected:\n%s\ngot:\n%s", args, expect, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (l definitions) godef(src, def span.Span) {
|
|
l[src] = definition{
|
|
src: src,
|
|
def: def,
|
|
}
|
|
}
|
|
|
|
func (l definitions) typdef(src, def span.Span) {
|
|
l[src] = definition{
|
|
src: src,
|
|
def: 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,
|
|
}
|
|
}
|
|
|
|
func (l definitions) testDefinitions(t *testing.T, e *packagestest.Exported) {
|
|
if len(l) != expectedDefinitionsCount {
|
|
t.Errorf("got %v definitions expected %v", len(l), expectedDefinitionsCount)
|
|
}
|
|
for _, d := range l {
|
|
args := []string{"query"}
|
|
if d.flags != "" {
|
|
args = append(args, strings.Split(d.flags, " ")...)
|
|
}
|
|
args = append(args, "definition")
|
|
src := span.New(d.src.URI(), span.NewPoint(0, 0, d.src.Start().Offset()), span.Point{})
|
|
args = append(args, fmt.Sprint(src))
|
|
app := &cmd.Application{}
|
|
app.Config = *e.Config
|
|
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 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)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (l definitions) testTypeDefinitions(t *testing.T, e *packagestest.Exported) {
|
|
if len(l) != expectedTypeDefinitionsCount {
|
|
t.Errorf("got %v definitions expected %v", len(l), expectedTypeDefinitionsCount)
|
|
}
|
|
//TODO: add command line type definition tests when it works
|
|
}
|