gotools/gopls/internal/test/marker/marker_test.go

var update

func TestMain(m *testing.M) {}

// Test runs the marker tests from the testdata directory.
//
// See package documentation for details on how marker tests work.
//
// These tests were inspired by (and in many places copied from) a previous
// iteration of the marker tests built on top of the packagestest framework.
// Key design decisions motivating this reimplementation are as follows:
//   - The old tests had a single global session, causing interaction at a
//     distance and several awkward workarounds.
//   - The old tests could not be safely parallelized, because certain tests
//     manipulated the server options
//   - Relatedly, the old tests did not have a logic grouping of assertions into
//     a single unit, resulting in clusters of files serving clusters of
//     entangled assertions.
//   - The old tests used locations in the source as test names and as the
//     identity of golden content, meaning that a single edit could change the
//     name of an arbitrary number of subtests, and making it difficult to
//     manually edit golden content.
//   - The old tests did not hew closely to LSP concepts, resulting in, for
//     example, each marker implementation doing its own position
//     transformations, and inventing its own mechanism for configuration.
//   - The old tests had an ad-hoc session initialization process. The integration
//     test environment has had more time devoted to its initialization, and has a
//     more convenient API.
//   - The old tests lacked documentation, and often had failures that were hard
//     to understand. By starting from scratch, we can revisit these aspects.
func Test(t *testing.T) {}

type marker

// ctx returns the mark context.
func (m marker) ctx() context.Context {}

// T returns the testing.TB for this mark.
func (m marker) T() testing.TB {}

// server returns the LSP server for the marker test run.
func (m marker) editor() *fake.Editor {}

// server returns the LSP server for the marker test run.
func (m marker) server() protocol.Server {}

// uri returns the URI of the file containing the marker.
func (mark marker) uri() protocol.DocumentURI {}

// document returns a protocol.TextDocumentIdentifier for the current file.
func (mark marker) document() protocol.TextDocumentIdentifier {}

// path returns the relative path to the file containing the marker.
func (mark marker) path() string {}

// mapper returns a *protocol.Mapper for the current file.
func (mark marker) mapper() *protocol.Mapper {}

// error reports an error with a prefix indicating the position of the marker
// note.
func (mark marker) error(args ...any) {}

// errorf reports a formatted error with a prefix indicating the position of
// the marker note.
//
// It formats the error message using mark.sprintf.
func (mark marker) errorf(format string, args ...any) {}

// valueMarkerFunc returns a wrapper around a function that allows it to be
// called during the processing of value markers (e.g. @value(v, 123)) with marker
// arguments converted to function parameters. The provided function's first
// parameter must be of type 'marker', and it must return a value.
//
// Unlike action markers, which are executed for actions such as test
// assertions, value markers are all evaluated first, and each computes
// a value that is recorded by its identifier, which is the marker's first
// argument. These values may be referred to from an action marker by
// this identifier, e.g. @action(... , v, ...).
//
// For example, given a fn with signature
//
//	func(mark marker, label, details, kind string) CompletionItem
//
// The result of valueMarkerFunc can associated with @item notes, and invoked
// as follows:
//
//	//@item(FooCompletion, "Foo", "func() int", "func")
//
// The provided fn should not mutate the test environment.
func valueMarkerFunc(fn any) func(marker) {}

// actionMarkerFunc returns a wrapper around a function that allows it to be
// called during the processing of action markers (e.g. @action("abc", 123))
// with marker arguments converted to function parameters. The provided
// function's first parameter must be of type 'marker', and it must not return
// any values. Any named arguments that may be used by the marker func must be
// listed in allowedNames.
//
// The provided fn should not mutate the test environment.
func actionMarkerFunc(fn any, allowedNames ...string) func(marker) {}

func convertArgs(mark marker, ftype reflect.Type, args []any) ([]reflect.Value, error) {}

// namedArg returns the named argument for name, or the default value.
func namedArg[T any](mark marker, name string, dflt T) T {}

func namedArgFunc[T any](mark marker, name string, f func(marker, any) (T, error), dflt T) T {}

func exactlyOneNamedArg(mark marker, names ...string) bool {}

// is reports whether arg is a T.
func is[T any](arg any) bool {}

var valueMarkerFuncs

var actionMarkerFuncs

type markerTest

// flagSet returns the flagset used for parsing the special "flags" file in the
// test archive.
func (t *markerTest) flagSet() *flag.FlagSet {}

type stringListValue

func (l *stringListValue) Set(s string) error {}

func (l stringListValue) String() string {}

func (mark *marker) getGolden(id expect.Identifier) *Golden {}

type Golden

// Get returns golden content for the given name, which corresponds to the
// relative path following the golden prefix @<name>/. For example, to access
// the content of @foo/path/to/result.json from the Golden associated with
// @foo, name should be "path/to/result.json".
//
// If -update is set, the given update function will be called to get the
// updated golden content that should be written back to testdata.
//
// Marker functions must use this method instead of accessing data entries
// directly otherwise the -update operation will delete those entries.
//
// TODO(rfindley): rethink the logic here. We may want to separate Get and Set,
// and not delete golden content that isn't set.
func (g *Golden) Get(t testing.TB, name string, updated []byte) ([]byte, bool) {}

// loadMarkerTests walks the given dir looking for .txt files, which it
// interprets as a txtar archive.
//
// See the documentation for RunMarkerTests for more details on the test data
// archive.
func loadMarkerTests(dir string) ([]*markerTest, error) {}

func loadMarkerTest(name string, content []byte) (*markerTest, error) {}

// formatTest formats the test as a txtar archive.
func formatTest(test *markerTest) ([]byte, error) {}

// newEnv creates a new environment for a marker test.
//
// TODO(rfindley): simplify and refactor the construction of testing
// environments across integration tests, marker tests, and benchmarks.
func newEnv(t *testing.T, cache *cache.Cache, files, proxyFiles map[string][]byte, writeGoSum []string, config fake.EditorConfig) *integration.Env {}

type markerTestRun

// sprintf returns a formatted string after applying pre-processing to
// arguments of the following types:
//   - token.Pos: formatted using (*markerTestRun).fmtPos
//   - protocol.Location: formatted using (*markerTestRun).fmtLoc
func (c *marker) sprintf(format string, args ...any) string {}

// fmtPos formats the given pos in the context of the test, using
// archive-relative paths for files and including the line number in the full
// archive file.
func (run *markerTestRun) fmtPos(pos token.Pos) string {}

// fmtLoc formats the given location in the context of the test, using
// archive-relative paths for files and including the line number in the full
// archive file.
func (run *markerTestRun) fmtLoc(loc protocol.Location) string {}

// mapLocation returns the relative path and utf8 span of the corresponding
// location, which must be a valid location in an archive file.
func (run *markerTestRun) mapLocation(loc protocol.Location) (name string, startLine, startCol, endLine, endCol int) {}

// fmtLocForGolden is like fmtLoc, but chooses more succinct and stable
// formatting, such as would be used for formatting locations in Golden
// content.
func (run *markerTestRun) fmtLocForGolden(loc protocol.Location) string {}

// summarizeLoc formats a summary of the given location, in the form
//
//	<name>:<startLine>:<startCol>[-[<endLine>:]endCol]
func summarizeLoc(name string, startLine, startCol, endLine, endCol int) string {}

var goldenType

var markerType

var stringMatcherType

var customConverters

// converter transforms a typed argument conversion function to an untyped
// conversion function.
func converter[T any](f func(marker, any) (T, error)) func(marker, any) (any, error) {}

func convert(mark marker, arg any, paramType reflect.Type) (any, error) {}

// convertNamedArgLocation is a workaround for converting locations referenced
// by a named argument. See the TODO in [convert]: this wouldn't be necessary
// if we flattened the namespace such that golden content lived in the same
// namespace as values.
func convertNamedArgLocation(mark marker, arg any) (protocol.Location, error) {}

// convertLocation converts a string or regexp argument into the protocol
// location corresponding to the first position of the string (or first match
// of the regexp) in the line preceding the note.
func convertLocation(mark marker, arg any) (protocol.Location, error) {}

type completionLabel

// convertCompletionLabel coerces an argument to a [completionLabel] parameter
// type.
//
// If the arg is a string, it is trivially converted. If the arg is a
// completionItem, its label is extracted.
//
// This allows us to stage a migration of the "snippet" marker to a simpler
// model where the completion label can just be listed explicitly.
func convertCompletionLabel(mark marker, arg any) (completionLabel, error) {}

// convertStringMatcher converts a string, regexp, or identifier
// argument into a stringMatcher. The string is a substring of the
// expected error, the regexp is a pattern than matches the expected
// error, and the identifier is a golden file containing the expected
// error.
func convertStringMatcher(mark marker, arg any) (stringMatcher, error) {}

type stringMatcher

// empty reports whether the receiver is an empty stringMatcher.
func (sm stringMatcher) empty() bool {}

func (sm stringMatcher) String() string {}

// checkErr asserts that the given error matches the stringMatcher's expectations.
func (sm stringMatcher) checkErr(mark marker, err error) {}

// check asserts that the given content matches the stringMatcher's expectations.
func (sm stringMatcher) check(mark marker, got string) {}

// checkChangedFiles compares the files changed by an operation with their expected (golden) state.
func checkChangedFiles(mark marker, changed map[string][]byte, golden *Golden) {}

// checkDiffs computes unified diffs for each changed file, and compares with
// the diff content stored in the given golden directory.
func checkDiffs(mark marker, changed map[string][]byte, golden *Golden) {}

type completionItem

func completionItemMarker(mark marker, label string, other ...string) completionItem {}

func rankMarker(mark marker, src protocol.Location, items ...completionLabel) {}

func snippetMarker(mark marker, src protocol.Location, label completionLabel, want string) {}

// completeMarker implements the @complete marker, running
// textDocument/completion at the given src location and asserting that the
// results match the expected results.
func completeMarker(mark marker, src protocol.Location, want ...completionItem) {}

// filterBuiltinsAndKeywords filters out builtins and keywords from completion
// results.
//
// It over-approximates, and does not detect if builtins are shadowed.
func filterBuiltinsAndKeywords(mark marker, items []protocol.CompletionItem) []protocol.CompletionItem {}

// acceptCompletionMarker implements the @acceptCompletion marker, running
// textDocument/completion at the given src location and accepting the
// candidate with the given label. The resulting source must match the provided
// golden content.
func acceptCompletionMarker(mark marker, src protocol.Location, label string, golden *Golden) {}

// defMarker implements the @def marker, running textDocument/definition at
// the given src location and asserting that there is exactly one resulting
// location, matching dst.
//
// TODO(rfindley): support a variadic destination set.
func defMarker(mark marker, src, dst protocol.Location) {}

func typedefMarker(mark marker, src, dst protocol.Location) {}

func foldingRangeMarker(mark marker, g *Golden) {}

// formatMarker implements the @format marker.
func formatMarker(mark marker, golden *Golden) {}

func highlightLocationMarker(mark marker, loc protocol.Location, kindName expect.Identifier) protocol.DocumentHighlight {}

func sortDocumentHighlights(s []protocol.DocumentHighlight) {}

// highlightAllMarker makes textDocument/highlight
// requests at locations of equivalence classes. Given input
// highlightall(X1, X2, ..., Xn), the marker checks
// highlight(X1) = highlight(X2) = ... = highlight(Xn) = {X1, X2, ..., Xn}.
// It is not the general rule for all highlighting, and use @highlight
// for asymmetric cases.
//
// TODO(b/288111111): this is a bit of a hack. We should probably
// have a more general way of testing that a function is idempotent.
func highlightAllMarker(mark marker, all ...protocol.DocumentHighlight) {}

func highlightMarker(mark marker, src protocol.DocumentHighlight, dsts ...protocol.DocumentHighlight) {}

func hoverMarker(mark marker, src, dst protocol.Location, sc stringMatcher) {}

func hoverErrMarker(mark marker, src protocol.Location, em stringMatcher) {}

// locMarker implements the @loc marker.
func locMarker(mark marker, loc protocol.Location) protocol.Location {}

// defLocMarker implements the @defloc marker, which binds a location to the
// (first) result of a jump-to-definition request.
func defLocMarker(mark marker, loc protocol.Location) protocol.Location {}

// diagMarker implements the @diag marker. It eliminates diagnostics from
// the observed set in mark.test.
func diagMarker(mark marker, loc protocol.Location, re *regexp.Regexp) {}

// removeDiagnostic looks for a diagnostic matching loc at the given position.
//
// If found, it returns (diag, true), and eliminates the matched diagnostic
// from the unmatched set.
//
// If not found, it returns (protocol.Diagnostic{}, false).
func removeDiagnostic(mark marker, loc protocol.Location, matchEnd bool, re *regexp.Regexp) (protocol.Diagnostic, bool) {}

// renameMarker implements the @rename(location, new, golden) marker.
func renameMarker(mark marker, loc protocol.Location, newName string, golden *Golden) {}

// renameErrMarker implements the @renamererr(location, new, error) marker.
func renameErrMarker(mark marker, loc protocol.Location, newName string, wantErr stringMatcher) {}

func selectionRangeMarker(mark marker, loc protocol.Location, g *Golden) {}

func tokenMarker(mark marker, loc protocol.Location, tokenType, mod string) {}

func signatureMarker(mark marker, src protocol.Location, label string, active int64) {}

// rename returns the new contents of the files that would be modified
// by renaming the identifier at loc to newName.
func rename(env *integration.Env, loc protocol.Location, newName string) (map[string][]byte, error) {}

// changedFiles applies the given sequence of document changes to the
// editor buffer content, recording the final contents in the returned map.
// The actual editor state is not changed.
// Deleted files are indicated by a content of []byte(nil).
//
// See also:
//   - Editor.applyWorkspaceEdit ../integration/fake/editor.go for the
//     implementation of this operation used in normal testing.
//   - cmdClient.applyWorkspaceEdit in ../../../cmd/cmd.go for the
//     CLI variant.
func changedFiles(env *integration.Env, changes []protocol.DocumentChange) (map[string][]byte, error) {}

func codeActionMarker(mark marker, loc protocol.Location, kind string) {}

// codeLensesMarker runs the @codelenses() marker, collecting @codelens marks
// in the current file and comparing with the result of the
// textDocument/codeLens RPC.
func codeLensesMarker(mark marker) {}

func documentLinkMarker(mark marker, g *Golden) {}

// consumeExtraNotes runs the provided func for each extra note with the given
// name, and deletes all matching notes.
func (mark marker) consumeExtraNotes(name string, f func(marker)) {}

// quickfixMarker implements the @quickfix(location, regexp,
// kind, golden) marker. It acts like @diag(location, regexp), to set
// the expectation of a diagnostic, but then it applies the "quickfix"
// code action (which must be unique) suggested by the matched diagnostic.
func quickfixMarker(mark marker, loc protocol.Location, re *regexp.Regexp, golden *Golden) {}

func quickfixErrMarker(mark marker, loc protocol.Location, re *regexp.Regexp, wantErr stringMatcher) {}

// codeAction executes a textDocument/codeAction request for the specified
// location and kind. If diag is non-nil, it is used as the code action
// context.
//
// The resulting map contains resulting file contents after the code action is
// applied. Currently, this function does not support code actions that return
// edits directly; it only supports code action commands.
func codeAction(env *integration.Env, uri protocol.DocumentURI, rng protocol.Range, kind protocol.CodeActionKind, diag *protocol.Diagnostic) (map[string][]byte, error) {}

// codeActionChanges executes a textDocument/codeAction request for the
// specified location and kind, and captures the resulting document changes.
// If diag is non-nil, it is used as the code action context.
func codeActionChanges(env *integration.Env, uri protocol.DocumentURI, rng protocol.Range, kind protocol.CodeActionKind, diag *protocol.Diagnostic) ([]protocol.DocumentChange, error) {}

// refsMarker implements the @refs marker.
func refsMarker(mark marker, src protocol.Location, want ...protocol.Location) {}

// implementationMarker implements the @implementation marker.
func implementationMarker(mark marker, src protocol.Location, want ...protocol.Location) {}

func itemLocation(item protocol.CallHierarchyItem) protocol.Location {}

func incomingCallsMarker(mark marker, src protocol.Location, want ...protocol.Location) {}

func outgoingCallsMarker(mark marker, src protocol.Location, want ...protocol.Location) {}

type callHierarchyFunc

func callHierarchy(mark marker, src protocol.Location, getCalls callHierarchyFunc, want []protocol.Location) {}

func inlayhintsMarker(mark marker, g *Golden) {}

func prepareRenameMarker(mark marker, src protocol.Location, placeholder string) {}

// symbolMarker implements the @symbol marker.
func symbolMarker(mark marker, golden *Golden) {}

// compareLocations returns an error message if got and want are not
// the same set of locations. The marker is used only for fmtLoc.
func compareLocations(mark marker, got, want []protocol.Location) error {}

func workspaceSymbolMarker(mark marker, query string, golden *Golden) {}

// compareGolden compares the content of got with that of g.Get(""), reporting
// errors on any mismatch.
//
// TODO(rfindley): use this helper in more places.
func compareGolden(mark marker, got []byte, g *Golden) {}