tests

package
v0.10.0-pre.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 28, 2022 License: BSD-3-Clause Imports: 30 Imported by: 0

README

Testing

LSP has "marker tests" defined in internal/lsp/testdata, as well as traditional tests.

Marker tests

Marker tests have a standard input file, like internal/lsp/testdata/foo/bar.go, and some may have a corresponding golden file, like internal/lsp/testdata/foo/bar.go.golden. The former is the "input" and the latter is the expected output.

Each input file contains annotations like //@suggestedfix("}", "refactor.rewrite", "Fill anonymous struct"). These annotations are interpreted by test runners to perform certain actions. The expected output after those actions is encoded in the golden file.

When tests are run, each annotation results in a new subtest, which is encoded in the golden file with a heading like,

-- suggestedfix_bar_11_21 --
// expected contents go here
-- suggestedfix_bar_13_20 --
// expected contents go here

The format of these headings vary: they are defined by the Golden function for each annotation. In the case above, the format is: annotation name, file name, annotation line location, annotation character location.

So, if internal/lsp/testdata/foo/bar.go has three suggestedfix annotations, the golden file should have three headers with suggestedfix_bar_xx_yy headings.

To see a list of all available annotations, see the exported "expectations" in tests.go.

To run marker tests,

cd /path/to/tools

# The marker tests are located in "internal/lsp", "internal/lsp/cmd, and
# "internal/lsp/source".
go test ./internal/lsp/...

There are quite a lot of marker tests, so to run one individually, pass the test path and heading into a -run argument:

cd /path/to/tools
go test ./internal/lsp/... -v -run TestLSP/Modules/SuggestedFix/bar_11_21

Resetting marker tests

Sometimes, a change is made to lsp that requires a change to multiple golden files. When this happens, you can run,

cd /path/to/tools
./internal/lsp/reset_golden.sh

Documentation

Overview

Package tests exports functionality to be used across a variety of gopls tests.

Index

Constants

View Source
const (
	// Default runs the standard completion tests.
	CompletionDefault = CompletionTestType(iota)

	// Unimported tests the autocompletion of unimported packages.
	CompletionUnimported

	// Deep tests deep completion.
	CompletionDeep

	// Fuzzy tests deep completion and fuzzy matching.
	CompletionFuzzy

	// CaseSensitive tests case sensitive completion.
	CompletionCaseSensitive

	// CompletionRank candidates in test must be valid and in the right relative order.
	CompletionRank
)
View Source
const (
	// Default runs the standard workspace symbols tests.
	WorkspaceSymbolsDefault = WorkspaceSymbolsTestType(iota)

	// Fuzzy tests workspace symbols with fuzzy matching.
	WorkspaceSymbolsFuzzy

	// CaseSensitive tests workspace symbols with case sensitive.
	WorkspaceSymbolsCaseSensitive
)

Variables

View Source
var UpdateGolden = flag.Bool("golden", false, "Update golden files")

Functions

func CheckCompletionOrder

func CheckCompletionOrder(want, got []protocol.CompletionItem, strictScores bool) string

func CheckSameMarkdown

func CheckSameMarkdown(t *testing.T, got, want string)

The markdown in the golden files matches the converter in comment.go, but for go1.19 and later the conversion is done using go/doc/comment. Compared to the newer version, the older version has extra escapes, and treats code blocks slightly differently.

func CompareDiagnostics

func CompareDiagnostics(t *testing.T, uri span.URI, want, got []*source.Diagnostic)

CompareDiagnostics reports testing errors to t when the diagnostic set got does not match want. If the sole expectation has source "no_diagnostics", the test expects that no diagnostics were received for the given document.

func Context

func Context(t testing.TB) context.Context

func CopyFolderToTempDir

func CopyFolderToTempDir(folder string) (string, error)

func DefaultOptions

func DefaultOptions(o *source.Options)

func DiffCallHierarchyItems

func DiffCallHierarchyItems(gotCalls []protocol.CallHierarchyItem, expectedCalls []protocol.CallHierarchyItem) string

DiffCallHierarchyItems returns the diff between expected and actual call locations for incoming/outgoing call hierarchies

func DiffCodeLens

func DiffCodeLens(uri span.URI, want, got []protocol.CodeLens) string

func DiffCompletionItems

func DiffCompletionItems(want, got []protocol.CompletionItem) string

DiffCompletionItems prints the diff between expected and actual completion test results.

func DiffLinks(mapper *protocol.ColumnMapper, wantLinks []Link, gotLinks []protocol.DocumentLink) string

DiffLinks takes the links we got and checks if they are located within the source or a Note. If the link is within a Note, the link is removed. Returns an diff comment if there are differences and empty string if no diffs.

func DiffSignatures

func DiffSignatures(spn span.Span, want, got *protocol.SignatureHelp) string

func DiffSnippets

func DiffSnippets(want string, got *protocol.CompletionItem) string

func EnableAllAnalyzers

func EnableAllAnalyzers(view source.View, opts *source.Options)

func EnableAllInlayHints

func EnableAllInlayHints(view source.View, opts *source.Options)

func FilterBuiltins

func FilterBuiltins(src span.Span, items []protocol.CompletionItem) []protocol.CompletionItem

func Normalize

func Normalize(s string, normalizers []Normalizer) string

Normalize replaces all paths present in s with just the fragment portion this is used to make golden files not depend on the temporary paths of the files

func NormalizeAny

func NormalizeAny(input string) string

NormalizeAny replaces occurrences of interface{} in input with any.

In Go 1.18, standard library functions were changed to use the 'any' alias in place of interface{}, which affects their type string.

func NormalizePrefix

func NormalizePrefix(s string, normalizers []Normalizer) string

NormalizePrefix normalizes a single path at the front of the input string.

func Run

func Run(t *testing.T, tests Tests, data *Data)

func RunTests

func RunTests(t *testing.T, dataDir string, includeMultiModule bool, f func(*testing.T, *Data))

func SpanName

func SpanName(spn span.Span) string

TODO(golang/go#54845): improve the formatting here to match standard line:column position formatting.

func StripSubscripts

func StripSubscripts(s string) string

StripSubscripts removes type parameter id subscripts.

TODO(rfindley): remove this function once subscripts are removed from the type parameter type string.

func ToProtocolCompletionItem

func ToProtocolCompletionItem(item completion.CompletionItem) protocol.CompletionItem

func ToProtocolCompletionItems

func ToProtocolCompletionItems(items []completion.CompletionItem) []protocol.CompletionItem

func WorkspaceSymbolsString

func WorkspaceSymbolsString(ctx context.Context, data *Data, queryURI span.URI, symbols []protocol.SymbolInformation) (string, error)

func WorkspaceSymbolsTestTypeToMatcher

func WorkspaceSymbolsTestTypeToMatcher(typ WorkspaceSymbolsTestType) source.SymbolMatcher

Types

type AddImport

type AddImport = map[span.URI]string

type CallHierarchy

type CallHierarchy = map[span.Span]*CallHierarchyResult

These type names apparently avoid the need to repeat the type in the field name and the make() expression.

type CallHierarchyResult

type CallHierarchyResult struct {
	IncomingCalls, OutgoingCalls []protocol.CallHierarchyItem
}

type CaseSensitiveCompletions

type CaseSensitiveCompletions = map[span.Span][]Completion

type CodeLens

type CodeLens = map[span.URI][]protocol.CodeLens

type Completion

type Completion struct {
	CompletionItems []token.Pos
}

type CompletionItems

type CompletionItems = map[token.Pos]*completion.CompletionItem

type CompletionSnippet

type CompletionSnippet struct {
	CompletionItem     token.Pos
	PlainSnippet       string
	PlaceholderSnippet string
}

type CompletionSnippets

type CompletionSnippets = map[span.Span][]CompletionSnippet

type CompletionTestType

type CompletionTestType int

type Completions

type Completions = map[span.Span][]Completion

type Data

type Data struct {
	Config                   packages.Config
	Exported                 *packagestest.Exported
	CallHierarchy            CallHierarchy
	CodeLens                 CodeLens
	Diagnostics              Diagnostics
	CompletionItems          CompletionItems
	Completions              Completions
	CompletionSnippets       CompletionSnippets
	UnimportedCompletions    UnimportedCompletions
	DeepCompletions          DeepCompletions
	FuzzyCompletions         FuzzyCompletions
	CaseSensitiveCompletions CaseSensitiveCompletions
	RankCompletions          RankCompletions
	FoldingRanges            FoldingRanges
	Formats                  Formats
	Imports                  Imports
	SemanticTokens           SemanticTokens
	SuggestedFixes           SuggestedFixes
	FunctionExtractions      FunctionExtractions
	MethodExtractions        MethodExtractions
	Definitions              Definitions
	Implementations          Implementations
	Highlights               Highlights
	References               References
	Renames                  Renames
	InlayHints               InlayHints
	PrepareRenames           PrepareRenames
	Symbols                  Symbols
	WorkspaceSymbols         WorkspaceSymbols
	Signatures               Signatures
	Links                    Links
	AddImport                AddImport
	Hovers                   Hovers

	ModfileFlagAvailable bool
	// contains filtered or unexported fields
}

func (*Data) Golden

func (data *Data) Golden(t *testing.T, tag, target string, update func() ([]byte, error)) []byte

func (*Data) Mapper

func (data *Data) Mapper(uri span.URI) (*protocol.ColumnMapper, error)

type DeepCompletions

type DeepCompletions = map[span.Span][]Completion

type Definition

type Definition struct {
	Name      string
	IsType    bool
	OnlyHover bool
	Src, Def  span.Span
}

type Definitions

type Definitions = map[span.Span]Definition

type Diagnostics

type Diagnostics = map[span.URI][]*source.Diagnostic

type FoldingRanges

type FoldingRanges = []span.Span

type Formats

type Formats = []span.Span

type FunctionExtractions

type FunctionExtractions = map[span.Span]span.Span

type FuzzyCompletions

type FuzzyCompletions = map[span.Span][]Completion

type Golden

type Golden struct {
	Filename string
	Archive  *txtar.Archive
	Modified bool
}

type Highlights

type Highlights = map[span.Span][]span.Span

type Hovers

type Hovers = map[span.Span]string

type Implementations

type Implementations = map[span.Span][]span.Span

type Imports

type Imports = []span.Span

type InlayHints

type InlayHints = []span.Span
type Link struct {
	Src          span.Span
	Target       string
	NotePosition token.Position
}
type Links = map[span.URI][]Link

type MethodExtractions

type MethodExtractions = map[span.Span]span.Span

type Normalizer

type Normalizer struct {
	// contains filtered or unexported fields
}

func CollectNormalizers

func CollectNormalizers(exported *packagestest.Exported) []Normalizer

type PrepareRenames

type PrepareRenames = map[span.Span]*source.PrepareItem

type RankCompletions

type RankCompletions = map[span.Span][]Completion

type References

type References = map[span.Span][]span.Span

type Renames

type Renames = map[span.Span]string

type SemanticTokens

type SemanticTokens = []span.Span

type Signatures

type Signatures = map[span.Span]*protocol.SignatureHelp

type SuggestedFix

type SuggestedFix struct {
	ActionKind, Title string
}

type SuggestedFixes

type SuggestedFixes = map[span.Span][]SuggestedFix

type Symbols

type Symbols = map[span.URI][]*symbol

type Tests

type Tests interface {
	CallHierarchy(*testing.T, span.Span, *CallHierarchyResult)
	CodeLens(*testing.T, span.URI, []protocol.CodeLens)
	Diagnostics(*testing.T, span.URI, []*source.Diagnostic)
	Completion(*testing.T, span.Span, Completion, CompletionItems)
	CompletionSnippet(*testing.T, span.Span, CompletionSnippet, bool, CompletionItems)
	UnimportedCompletion(*testing.T, span.Span, Completion, CompletionItems)
	DeepCompletion(*testing.T, span.Span, Completion, CompletionItems)
	FuzzyCompletion(*testing.T, span.Span, Completion, CompletionItems)
	CaseSensitiveCompletion(*testing.T, span.Span, Completion, CompletionItems)
	RankCompletion(*testing.T, span.Span, Completion, CompletionItems)
	FoldingRanges(*testing.T, span.Span)
	Format(*testing.T, span.Span)
	Import(*testing.T, span.Span)
	SemanticTokens(*testing.T, span.Span)
	SuggestedFix(*testing.T, span.Span, []SuggestedFix, int)
	FunctionExtraction(*testing.T, span.Span, span.Span)
	MethodExtraction(*testing.T, span.Span, span.Span)
	Definition(*testing.T, span.Span, Definition)
	Implementation(*testing.T, span.Span, []span.Span)
	Highlight(*testing.T, span.Span, []span.Span)
	InlayHints(*testing.T, span.Span)
	References(*testing.T, span.Span, []span.Span)
	Rename(*testing.T, span.Span, string)
	PrepareRename(*testing.T, span.Span, *source.PrepareItem)
	Symbols(*testing.T, span.URI, []protocol.DocumentSymbol)
	WorkspaceSymbols(*testing.T, span.URI, string, WorkspaceSymbolsTestType)
	SignatureHelp(*testing.T, span.Span, *protocol.SignatureHelp)
	Link(*testing.T, span.URI, []Link)
	AddImport(*testing.T, span.URI, string)
	Hover(*testing.T, span.Span, string)
}

TODO(adonovan): there are multiple implementations of this (undocumented) interface, each of which must implement similar semantics. For example: - *runner in ../cmd/test/check.go - *runner in ../source/source_test.go - *runner in ../lsp_test.go Can we avoid this duplication?

type UnimportedCompletions

type UnimportedCompletions = map[span.Span][]Completion

type WorkspaceSymbols

type WorkspaceSymbols = map[WorkspaceSymbolsTestType]map[span.URI][]string

type WorkspaceSymbolsTestType

type WorkspaceSymbolsTestType int

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL