2020-04-10 07:38:38 -06:00
|
|
|
// Copyright 2020 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 regtest
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"golang.org/x/tools/internal/lsp/fake"
|
2020-04-14 13:16:05 -06:00
|
|
|
"golang.org/x/tools/internal/lsp/protocol"
|
2020-04-10 07:38:38 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
const symbolSetup = `
|
|
|
|
-- go.mod --
|
|
|
|
module mod.com
|
|
|
|
|
|
|
|
go 1.12
|
|
|
|
-- main.go --
|
|
|
|
package main
|
|
|
|
|
2020-04-14 13:16:05 -06:00
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() { // function
|
|
|
|
fmt.Println("Hello")
|
|
|
|
}
|
|
|
|
|
|
|
|
var myvar int // variable
|
|
|
|
|
|
|
|
type myType string // basic type
|
|
|
|
|
|
|
|
type myDecoder json.Decoder // to use the encoding/json import
|
|
|
|
|
|
|
|
func (m *myType) Blahblah() {} // method
|
|
|
|
|
|
|
|
type myStruct struct { // struct type
|
|
|
|
myStructField int // struct field
|
|
|
|
}
|
2020-04-10 07:38:38 -06:00
|
|
|
|
2020-04-14 13:16:05 -06:00
|
|
|
type myInterface interface { // interface
|
|
|
|
DoSomeCoolStuff() string // interface method
|
2020-04-10 07:38:38 -06:00
|
|
|
}
|
2020-04-14 13:16:05 -06:00
|
|
|
-- p/p.go --
|
2020-06-07 19:50:35 -06:00
|
|
|
package p
|
2020-04-10 07:38:38 -06:00
|
|
|
|
2020-04-14 13:16:05 -06:00
|
|
|
const Message = "Hello World." // constant
|
2020-04-10 07:38:38 -06:00
|
|
|
`
|
|
|
|
|
2020-04-14 13:16:05 -06:00
|
|
|
var caseSensitiveSymbolChecks = map[string]*expSymbolInformation{
|
|
|
|
"main": {
|
2020-06-07 19:50:35 -06:00
|
|
|
Name: pString("main.main"),
|
2020-04-14 13:16:05 -06:00
|
|
|
Kind: pKind(protocol.Function),
|
|
|
|
Location: &expLocation{
|
|
|
|
Path: pString("main.go"),
|
|
|
|
Range: &expRange{
|
|
|
|
Start: &expPos{
|
|
|
|
Line: pInt(7),
|
|
|
|
Column: pInt(5),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"Message": {
|
2020-06-07 19:50:35 -06:00
|
|
|
Name: pString("p.Message"),
|
2020-04-14 13:16:05 -06:00
|
|
|
Kind: pKind(protocol.Constant),
|
|
|
|
Location: &expLocation{
|
|
|
|
Path: pString("p/p.go"),
|
|
|
|
Range: &expRange{
|
|
|
|
Start: &expPos{
|
|
|
|
Line: pInt(2),
|
|
|
|
Column: pInt(6),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"myvar": {
|
2020-06-07 19:50:35 -06:00
|
|
|
Name: pString("main.myvar"),
|
2020-04-14 13:16:05 -06:00
|
|
|
Kind: pKind(protocol.Variable),
|
|
|
|
Location: &expLocation{
|
|
|
|
Path: pString("main.go"),
|
|
|
|
Range: &expRange{
|
|
|
|
Start: &expPos{
|
|
|
|
Line: pInt(11),
|
|
|
|
Column: pInt(4),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"myType": {
|
2020-06-07 19:50:35 -06:00
|
|
|
Name: pString("main.myType"),
|
2020-04-14 13:16:05 -06:00
|
|
|
Kind: pKind(protocol.String),
|
|
|
|
Location: &expLocation{
|
|
|
|
Path: pString("main.go"),
|
|
|
|
Range: &expRange{
|
|
|
|
Start: &expPos{
|
|
|
|
Line: pInt(13),
|
|
|
|
Column: pInt(5),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"Blahblah": {
|
2020-06-07 19:50:35 -06:00
|
|
|
Name: pString("main.myType.Blahblah"),
|
2020-04-14 13:16:05 -06:00
|
|
|
Kind: pKind(protocol.Method),
|
|
|
|
Location: &expLocation{
|
|
|
|
Path: pString("main.go"),
|
|
|
|
Range: &expRange{
|
|
|
|
Start: &expPos{
|
|
|
|
Line: pInt(17),
|
|
|
|
Column: pInt(17),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"NewEncoder": {
|
2020-06-07 19:50:35 -06:00
|
|
|
Name: pString("json.NewEncoder"),
|
2020-04-14 13:16:05 -06:00
|
|
|
Kind: pKind(protocol.Function),
|
|
|
|
},
|
|
|
|
"myStruct": {
|
2020-06-07 19:50:35 -06:00
|
|
|
Name: pString("main.myStruct"),
|
2020-04-14 13:16:05 -06:00
|
|
|
Kind: pKind(protocol.Struct),
|
|
|
|
Location: &expLocation{
|
|
|
|
Path: pString("main.go"),
|
|
|
|
Range: &expRange{
|
|
|
|
Start: &expPos{
|
|
|
|
Line: pInt(19),
|
|
|
|
Column: pInt(5),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// TODO: not sure we should be returning struct fields
|
|
|
|
"myStructField": {
|
2020-06-07 19:50:35 -06:00
|
|
|
Name: pString("main.myStruct.myStructField"),
|
2020-04-14 13:16:05 -06:00
|
|
|
Kind: pKind(protocol.Field),
|
|
|
|
Location: &expLocation{
|
|
|
|
Path: pString("main.go"),
|
|
|
|
Range: &expRange{
|
|
|
|
Start: &expPos{
|
|
|
|
Line: pInt(20),
|
|
|
|
Column: pInt(1),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"myInterface": {
|
2020-06-07 19:50:35 -06:00
|
|
|
Name: pString("main.myInterface"),
|
2020-04-14 13:16:05 -06:00
|
|
|
Kind: pKind(protocol.Interface),
|
|
|
|
Location: &expLocation{
|
|
|
|
Path: pString("main.go"),
|
|
|
|
Range: &expRange{
|
|
|
|
Start: &expPos{
|
|
|
|
Line: pInt(23),
|
|
|
|
Column: pInt(5),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// TODO: not sure we should be returning interface methods
|
|
|
|
"DoSomeCoolStuff": {
|
2020-06-07 19:50:35 -06:00
|
|
|
Name: pString("main.myInterface.DoSomeCoolStuff"),
|
2020-04-14 13:16:05 -06:00
|
|
|
Kind: pKind(protocol.Method),
|
|
|
|
Location: &expLocation{
|
|
|
|
Path: pString("main.go"),
|
|
|
|
Range: &expRange{
|
|
|
|
Start: &expPos{
|
|
|
|
Line: pInt(24),
|
|
|
|
Column: pInt(1),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var caseInsensitiveSymbolChecks = map[string]*expSymbolInformation{
|
|
|
|
"Main": caseSensitiveSymbolChecks["main"],
|
|
|
|
}
|
|
|
|
|
|
|
|
var fuzzySymbolChecks = map[string]*expSymbolInformation{
|
2020-06-07 19:50:35 -06:00
|
|
|
"Mn": caseSensitiveSymbolChecks["main"],
|
2020-04-14 13:16:05 -06:00
|
|
|
}
|
|
|
|
|
2020-04-10 07:38:38 -06:00
|
|
|
// TestSymbolPos tests that, at a basic level, we get the correct position
|
|
|
|
// information for symbols matches that are returned.
|
|
|
|
func TestSymbolPos(t *testing.T) {
|
2020-04-14 13:16:05 -06:00
|
|
|
checkChecks(t, "caseSensitive", caseSensitiveSymbolChecks)
|
|
|
|
checkChecks(t, "caseInsensitive", caseInsensitiveSymbolChecks)
|
|
|
|
checkChecks(t, "fuzzy", fuzzySymbolChecks)
|
|
|
|
}
|
|
|
|
|
|
|
|
func checkChecks(t *testing.T, matcher string, checks map[string]*expSymbolInformation) {
|
|
|
|
t.Helper()
|
2020-04-10 07:38:38 -06:00
|
|
|
opts := []RunOption{
|
|
|
|
WithEditorConfig(fake.EditorConfig{SymbolMatcher: &matcher}),
|
|
|
|
}
|
|
|
|
runner.Run(t, symbolSetup, func(t *testing.T, env *Env) {
|
2020-04-14 13:16:05 -06:00
|
|
|
t.Run(matcher, func(t *testing.T) {
|
|
|
|
for query, exp := range checks {
|
|
|
|
t.Run(query, func(t *testing.T) {
|
|
|
|
res := env.Symbol(query)
|
|
|
|
if !exp.matchAgainst(res) {
|
2020-06-07 19:50:35 -06:00
|
|
|
t.Fatalf("failed to find a match against query %q for %v,\ngot: %v", query, exp, res)
|
2020-04-14 13:16:05 -06:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
2020-04-10 07:38:38 -06:00
|
|
|
}, opts...)
|
|
|
|
}
|