mirror of
https://github.com/golang/go
synced 2024-11-19 02:54:42 -07:00
4ca280b5bd
specifically it uses them for the guru compatability tests This change radically increases the test coverage of the godef tests as it now works for all the jump to definition tests not just the specialized ones. Change-Id: I63547138566ac3de56344dcfddb758ed5f362a06 Reviewed-on: https://go-review.googlesource.com/c/tools/+/174937 Run-TryBot: Ian Cottrell <iancottrell@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
162 lines
4.6 KiB
Go
162 lines
4.6 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"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"regexp"
|
|
"runtime"
|
|
"strings"
|
|
"testing"
|
|
|
|
"golang.org/x/tools/internal/lsp/cmd"
|
|
"golang.org/x/tools/internal/lsp/tests"
|
|
"golang.org/x/tools/internal/span"
|
|
"golang.org/x/tools/internal/tool"
|
|
)
|
|
|
|
const (
|
|
expectedDefinitionsCount = 28
|
|
expectedTypeDefinitionsCount = 2
|
|
)
|
|
|
|
type godefMode int
|
|
|
|
const (
|
|
plainGodef = godefMode(1 << iota)
|
|
jsonGoDef
|
|
guruGoDef
|
|
)
|
|
|
|
var godefModes = []godefMode{
|
|
plainGodef,
|
|
jsonGoDef,
|
|
guruGoDef,
|
|
jsonGoDef | guruGoDef,
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
}
|
|
|
|
var brokenDefinitionTests = map[string]bool{
|
|
// The following tests all have extra information in the description
|
|
"A-definition-json-guru": true,
|
|
"err-definition-json-guru": true,
|
|
"myUnclosedIf-definition-json-guru": true,
|
|
"Other-definition-json-guru": true,
|
|
"RandomParamY-definition-json-guru": true,
|
|
"S1-definition-json-guru": true,
|
|
"S2-definition-json-guru": true,
|
|
"Stuff-definition-json-guru": true,
|
|
"Thing-definition-json-guru": true,
|
|
"Things-definition-json-guru": true,
|
|
}
|
|
|
|
func (r *runner) Definition(t *testing.T, data tests.Definitions) {
|
|
for _, d := range data {
|
|
if d.IsType {
|
|
// TODO: support type definition queries
|
|
continue
|
|
}
|
|
d.Src = span.New(d.Src.URI(), span.NewPoint(0, 0, d.Src.Start().Offset()), span.Point{})
|
|
for _, mode := range godefModes {
|
|
args := []string{"-remote=internal", "query"}
|
|
tag := d.Name + "-definition"
|
|
if mode&jsonGoDef != 0 {
|
|
tag += "-json"
|
|
args = append(args, "-json")
|
|
}
|
|
if mode&guruGoDef != 0 {
|
|
if r.exporter.Name() != "GOPATH" {
|
|
//only run guru compatability tests in GOPATH mode
|
|
continue
|
|
}
|
|
if d.Name == "PackageFoo" {
|
|
//guru does not support definition on packages
|
|
continue
|
|
}
|
|
tag += "-guru"
|
|
args = append(args, "-emulate=guru")
|
|
}
|
|
if _, found := brokenDefinitionTests[tag]; found {
|
|
continue
|
|
}
|
|
args = append(args, "definition")
|
|
uri := d.Src.URI()
|
|
filename, err := uri.Filename()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
args = append(args, fmt.Sprint(d.Src))
|
|
got := captureStdOut(t, func() {
|
|
tool.Main(context.Background(), r.app, args)
|
|
})
|
|
got = normalizePaths(r.data, got)
|
|
if mode&jsonGoDef != 0 && runtime.GOOS == "windows" {
|
|
got = strings.Replace(got, "file:///", "file://", -1)
|
|
}
|
|
if mode&guruGoDef == 0 {
|
|
expect := string(r.data.Golden(tag, filename, func() ([]byte, error) {
|
|
return []byte(got), nil
|
|
}))
|
|
if got != expect {
|
|
t.Errorf("definition %v failed with %#v expected:\n%s\ngot:\n%s", tag, args, expect, got)
|
|
}
|
|
continue
|
|
}
|
|
guruArgs := []string{}
|
|
if mode&jsonGoDef != 0 {
|
|
guruArgs = append(guruArgs, "-json")
|
|
}
|
|
guruArgs = append(guruArgs, "definition", fmt.Sprint(d.Src))
|
|
expect := strings.TrimSpace(string(r.data.Golden(tag, filename, func() ([]byte, error) {
|
|
cmd := exec.Command("guru", guruArgs...)
|
|
cmd.Env = r.data.Exported.Config.Env
|
|
out, _ := cmd.Output()
|
|
if err != nil {
|
|
if _, ok := err.(*exec.ExitError); !ok {
|
|
return nil, fmt.Errorf("Could not run guru %v: %v\n%s", guruArgs, err, out)
|
|
}
|
|
}
|
|
result := normalizePaths(r.data, string(out))
|
|
// guru sometimes puts the full package path in type names, but we don't
|
|
if mode&jsonGoDef == 0 && d.Name != "AImport" {
|
|
result = strings.Replace(result, "golang.org/x/tools/internal/lsp/godef/", "", -1)
|
|
}
|
|
return []byte(result), nil
|
|
})))
|
|
if expect != "" && !strings.HasPrefix(got, expect) {
|
|
t.Errorf("definition %v failed with %#v expected:\n%q\ngot:\n%q", tag, args, expect, got)
|
|
}
|
|
}
|
|
}
|
|
}
|