// Copyright 2018 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 source_test

import (
	"context"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"sort"
	"strings"
	"testing"

	"golang.org/x/tools/go/packages/packagestest"
	"golang.org/x/tools/internal/lsp/cache"
	"golang.org/x/tools/internal/lsp/diff"
	"golang.org/x/tools/internal/lsp/fuzzy"
	"golang.org/x/tools/internal/lsp/protocol"
	"golang.org/x/tools/internal/lsp/source"
	"golang.org/x/tools/internal/lsp/tests"
	"golang.org/x/tools/internal/span"
	"golang.org/x/tools/internal/testenv"
	errors "golang.org/x/xerrors"
)

func TestMain(m *testing.M) {
	testenv.ExitIfSmallMachine()
	os.Exit(m.Run())
}

func TestSource(t *testing.T) {
	packagestest.TestAll(t, testSource)
}

type runner struct {
	view source.View
	data *tests.Data
	ctx  context.Context
}

func testSource(t *testing.T, exporter packagestest.Exporter) {
	ctx := tests.Context(t)
	data := tests.Load(t, exporter, "../testdata")
	for _, datum := range data {
		defer datum.Exported.Cleanup()

		cache := cache.New(ctx, nil)
		session := cache.NewSession(ctx)
		options := tests.DefaultOptions()
		options.Env = datum.Config.Env
		view, snapshot, err := session.NewView(ctx, "source_test", span.URIFromPath(datum.Config.Dir), options)
		if err != nil {
			t.Fatal(err)
		}
		// Enable type error analyses for tests.
		// TODO(golang/go#38212): Delete this once they are enabled by default.
		tests.EnableAllAnalyzers(snapshot, &options)
		view.SetOptions(ctx, options)
		r := &runner{
			view: view,
			data: datum,
			ctx:  ctx,
		}
		var modifications []source.FileModification
		for filename, content := range datum.Config.Overlay {
			kind := source.DetectLanguage("", filename)
			if kind != source.Go {
				continue
			}
			modifications = append(modifications, source.FileModification{
				URI:        span.URIFromPath(filename),
				Action:     source.Open,
				Version:    -1,
				Text:       content,
				LanguageID: "go",
			})
		}
		if _, err := session.DidModifyFiles(ctx, modifications); err != nil {
			t.Fatal(err)
		}
		t.Run(tests.FormatFolderName(datum.Folder), func(t *testing.T) {
			t.Helper()
			tests.Run(t, r, datum)
		})
	}
}

func (r *runner) Diagnostics(t *testing.T, uri span.URI, want []source.Diagnostic) {
	snapshot := r.view.Snapshot()

	fileID, got, err := source.FileDiagnostics(r.ctx, snapshot, uri)
	if err != nil {
		t.Fatal(err)
	}
	// A special case to test that there are no diagnostics for a file.
	if len(want) == 1 && want[0].Source == "no_diagnostics" {
		if len(got) != 0 {
			t.Errorf("expected no diagnostics for %s, got %v", uri, got)
		}
		return
	}
	if diff := tests.DiffDiagnostics(fileID.URI, want, got); diff != "" {
		t.Error(diff)
	}
}

func (r *runner) Completion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
	var want []protocol.CompletionItem
	for _, pos := range test.CompletionItems {
		want = append(want, tests.ToProtocolCompletionItem(*items[pos]))
	}
	_, got := r.callCompletion(t, src, func(opts *source.Options) {
		opts.Matcher = source.CaseInsensitive
		opts.DeepCompletion = false
		opts.UnimportedCompletion = false
		opts.InsertTextFormat = protocol.PlainTextTextFormat
		// Only enable literal completions if in the completion literals tests.
		// TODO(rstambler): Separate out literal completion tests.
		if strings.Contains(string(src.URI()), "literal") {
			opts.InsertTextFormat = protocol.SnippetTextFormat
		}
	})
	got = tests.FilterBuiltins(src, got)
	if diff := tests.DiffCompletionItems(want, got); diff != "" {
		t.Errorf("%s: %s", src, diff)
	}
}

func (r *runner) CompletionSnippet(t *testing.T, src span.Span, expected tests.CompletionSnippet, placeholders bool, items tests.CompletionItems) {
	_, list := r.callCompletion(t, src, func(opts *source.Options) {
		opts.Placeholders = placeholders
		opts.DeepCompletion = true
	})
	got := tests.FindItem(list, *items[expected.CompletionItem])
	want := expected.PlainSnippet
	if placeholders {
		want = expected.PlaceholderSnippet
	}
	if diff := tests.DiffSnippets(want, got); diff != "" {
		t.Errorf("%s: %s", src, diff)
	}
}

func (r *runner) UnimportedCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
	var want []protocol.CompletionItem
	for _, pos := range test.CompletionItems {
		want = append(want, tests.ToProtocolCompletionItem(*items[pos]))
	}
	_, got := r.callCompletion(t, src, func(opts *source.Options) {})
	got = tests.FilterBuiltins(src, got)
	if diff := tests.CheckCompletionOrder(want, got, false); diff != "" {
		t.Errorf("%s: %s", src, diff)
	}
}

func (r *runner) DeepCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
	var want []protocol.CompletionItem
	for _, pos := range test.CompletionItems {
		want = append(want, tests.ToProtocolCompletionItem(*items[pos]))
	}
	prefix, list := r.callCompletion(t, src, func(opts *source.Options) {
		opts.DeepCompletion = true
		opts.Matcher = source.CaseInsensitive
		opts.UnimportedCompletion = false
	})
	list = tests.FilterBuiltins(src, list)
	fuzzyMatcher := fuzzy.NewMatcher(prefix)
	var got []protocol.CompletionItem
	for _, item := range list {
		if fuzzyMatcher.Score(item.Label) <= 0 {
			continue
		}
		got = append(got, item)
	}
	if msg := tests.DiffCompletionItems(want, got); msg != "" {
		t.Errorf("%s: %s", src, msg)
	}
}

func (r *runner) FuzzyCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
	var want []protocol.CompletionItem
	for _, pos := range test.CompletionItems {
		want = append(want, tests.ToProtocolCompletionItem(*items[pos]))
	}
	_, got := r.callCompletion(t, src, func(opts *source.Options) {
		opts.DeepCompletion = true
		opts.Matcher = source.Fuzzy
		opts.UnimportedCompletion = false
	})
	got = tests.FilterBuiltins(src, got)
	if msg := tests.DiffCompletionItems(want, got); msg != "" {
		t.Errorf("%s: %s", src, msg)
	}
}

func (r *runner) CaseSensitiveCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
	var want []protocol.CompletionItem
	for _, pos := range test.CompletionItems {
		want = append(want, tests.ToProtocolCompletionItem(*items[pos]))
	}
	_, list := r.callCompletion(t, src, func(opts *source.Options) {
		opts.Matcher = source.CaseSensitive
		opts.UnimportedCompletion = false
	})
	list = tests.FilterBuiltins(src, list)
	if diff := tests.DiffCompletionItems(want, list); diff != "" {
		t.Errorf("%s: %s", src, diff)
	}
}

func (r *runner) RankCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
	var want []protocol.CompletionItem
	for _, pos := range test.CompletionItems {
		want = append(want, tests.ToProtocolCompletionItem(*items[pos]))
	}
	_, got := r.callCompletion(t, src, func(opts *source.Options) {
		opts.DeepCompletion = true
		opts.Matcher = source.Fuzzy
	})
	if msg := tests.CheckCompletionOrder(want, got, true); msg != "" {
		t.Errorf("%s: %s", src, msg)
	}
}

func (r *runner) callCompletion(t *testing.T, src span.Span, options func(*source.Options)) (string, []protocol.CompletionItem) {
	fh, err := r.view.Snapshot().GetFile(src.URI())
	if err != nil {
		t.Fatal(err)
	}
	original := r.view.Options()
	modified := original
	options(&modified)
	view, err := r.view.SetOptions(r.ctx, modified)
	if err != nil {
		t.Fatal(err)
	}
	defer r.view.SetOptions(r.ctx, original)

	list, surrounding, err := source.Completion(r.ctx, view.Snapshot(), fh, protocol.Position{
		Line:      float64(src.Start().Line() - 1),
		Character: float64(src.Start().Column() - 1),
	})
	if err != nil && !errors.As(err, &source.ErrIsDefinition{}) {
		t.Fatalf("failed for %v: %v", src, err)
	}
	var prefix string
	if surrounding != nil {
		prefix = strings.ToLower(surrounding.Prefix())
	}

	var numDeepCompletionsSeen int
	var items []source.CompletionItem
	// Apply deep completion filtering.
	for _, item := range list {
		if item.Depth > 0 {
			if !modified.DeepCompletion {
				continue
			}
			if numDeepCompletionsSeen >= source.MaxDeepCompletions {
				continue
			}
			numDeepCompletionsSeen++
		}
		items = append(items, item)
	}
	return prefix, tests.ToProtocolCompletionItems(items)
}

func (r *runner) FoldingRanges(t *testing.T, spn span.Span) {
	uri := spn.URI()

	fh, err := r.view.Snapshot().GetFile(spn.URI())
	if err != nil {
		t.Fatal(err)
	}
	data, _, err := fh.Read(r.ctx)
	if err != nil {
		t.Error(err)
		return
	}

	// Test all folding ranges.
	ranges, err := source.FoldingRange(r.ctx, r.view.Snapshot(), fh, false)
	if err != nil {
		t.Error(err)
		return
	}
	r.foldingRanges(t, "foldingRange", uri, string(data), ranges)

	// Test folding ranges with lineFoldingOnly
	ranges, err = source.FoldingRange(r.ctx, r.view.Snapshot(), fh, true)
	if err != nil {
		t.Error(err)
		return
	}
	r.foldingRanges(t, "foldingRange-lineFolding", uri, string(data), ranges)
}

func (r *runner) foldingRanges(t *testing.T, prefix string, uri span.URI, data string, ranges []*source.FoldingRangeInfo) {
	t.Helper()
	// Fold all ranges.
	nonOverlapping := nonOverlappingRanges(t, ranges)
	for i, rngs := range nonOverlapping {
		got, err := foldRanges(string(data), rngs)
		if err != nil {
			t.Error(err)
			continue
		}
		tag := fmt.Sprintf("%s-%d", prefix, i)
		want := string(r.data.Golden(tag, uri.Filename(), func() ([]byte, error) {
			return []byte(got), nil
		}))

		if want != got {
			t.Errorf("%s: foldingRanges failed for %s, expected:\n%v\ngot:\n%v", tag, uri.Filename(), want, got)
		}
	}

	// Filter by kind.
	kinds := []protocol.FoldingRangeKind{protocol.Imports, protocol.Comment}
	for _, kind := range kinds {
		var kindOnly []*source.FoldingRangeInfo
		for _, fRng := range ranges {
			if fRng.Kind == kind {
				kindOnly = append(kindOnly, fRng)
			}
		}

		nonOverlapping := nonOverlappingRanges(t, kindOnly)
		for i, rngs := range nonOverlapping {
			got, err := foldRanges(string(data), rngs)
			if err != nil {
				t.Error(err)
				continue
			}
			tag := fmt.Sprintf("%s-%s-%d", prefix, kind, i)
			want := string(r.data.Golden(tag, uri.Filename(), func() ([]byte, error) {
				return []byte(got), nil
			}))

			if want != got {
				t.Errorf("%s: failed for %s, expected:\n%v\ngot:\n%v", tag, uri.Filename(), want, got)
			}
		}

	}
}

func nonOverlappingRanges(t *testing.T, ranges []*source.FoldingRangeInfo) (res [][]*source.FoldingRangeInfo) {
	for _, fRng := range ranges {
		setNum := len(res)
		for i := 0; i < len(res); i++ {
			canInsert := true
			for _, rng := range res[i] {
				if conflict(t, rng, fRng) {
					canInsert = false
					break
				}
			}
			if canInsert {
				setNum = i
				break
			}
		}
		if setNum == len(res) {
			res = append(res, []*source.FoldingRangeInfo{})
		}
		res[setNum] = append(res[setNum], fRng)
	}
	return res
}

func conflict(t *testing.T, a, b *source.FoldingRangeInfo) bool {
	arng, err := a.Range()
	if err != nil {
		t.Fatal(err)
	}
	brng, err := b.Range()
	if err != nil {
		t.Fatal(err)
	}
	// a start position is <= b start positions
	return protocol.ComparePosition(arng.Start, brng.Start) <= 0 && protocol.ComparePosition(arng.End, brng.Start) > 0
}

func foldRanges(contents string, ranges []*source.FoldingRangeInfo) (string, error) {
	foldedText := "<>"
	res := contents
	// Apply the folds from the end of the file forward
	// to preserve the offsets.
	for i := len(ranges) - 1; i >= 0; i-- {
		fRange := ranges[i]
		spn, err := fRange.Span()
		if err != nil {
			return "", err
		}
		start := spn.Start().Offset()
		end := spn.End().Offset()

		tmp := res[0:start] + foldedText
		res = tmp + res[end:]
	}
	return res, nil
}

func (r *runner) Format(t *testing.T, spn span.Span) {
	gofmted := string(r.data.Golden("gofmt", spn.URI().Filename(), func() ([]byte, error) {
		cmd := exec.Command("gofmt", spn.URI().Filename())
		out, _ := cmd.Output() // ignore error, sometimes we have intentionally ungofmt-able files
		return out, nil
	}))
	fh, err := r.view.Snapshot().GetFile(spn.URI())
	if err != nil {
		t.Fatal(err)
	}
	edits, err := source.Format(r.ctx, r.view.Snapshot(), fh)
	if err != nil {
		if gofmted != "" {
			t.Error(err)
		}
		return
	}
	data, _, err := fh.Read(r.ctx)
	if err != nil {
		t.Fatal(err)
	}
	m, err := r.data.Mapper(spn.URI())
	if err != nil {
		t.Fatal(err)
	}
	diffEdits, err := source.FromProtocolEdits(m, edits)
	if err != nil {
		t.Error(err)
	}
	got := diff.ApplyEdits(string(data), diffEdits)
	if gofmted != got {
		t.Errorf("format failed for %s, expected:\n%v\ngot:\n%v", spn.URI().Filename(), gofmted, got)
	}
}

func (r *runner) Import(t *testing.T, spn span.Span) {
	fh, err := r.view.Snapshot().GetFile(spn.URI())
	if err != nil {
		t.Fatal(err)
	}
	edits, _, err := source.AllImportsFixes(r.ctx, r.view.Snapshot(), fh)
	if err != nil {
		t.Error(err)
	}
	data, _, err := fh.Read(r.ctx)
	if err != nil {
		t.Fatal(err)
	}
	m, err := r.data.Mapper(fh.Identity().URI)
	if err != nil {
		t.Fatal(err)
	}
	diffEdits, err := source.FromProtocolEdits(m, edits)
	if err != nil {
		t.Error(err)
	}
	got := diff.ApplyEdits(string(data), diffEdits)
	want := string(r.data.Golden("goimports", spn.URI().Filename(), func() ([]byte, error) {
		return []byte(got), nil
	}))
	if want != got {
		t.Errorf("import failed for %s, expected:\n%v\ngot:\n%v", spn.URI().Filename(), want, got)
	}
}

func (r *runner) SuggestedFix(t *testing.T, spn span.Span, actionKinds []string) {}

func (r *runner) Definition(t *testing.T, spn span.Span, d tests.Definition) {
	_, srcRng, err := spanToRange(r.data, d.Src)
	if err != nil {
		t.Fatal(err)
	}
	fh, err := r.view.Snapshot().GetFile(spn.URI())
	if err != nil {
		t.Fatal(err)
	}
	ident, err := source.Identifier(r.ctx, r.view.Snapshot(), fh, srcRng.Start)
	if err != nil {
		t.Fatalf("failed for %v: %v", d.Src, err)
	}
	h, err := ident.Hover(r.ctx)
	if err != nil {
		t.Fatalf("failed for %v: %v", d.Src, err)
	}
	hover, err := source.FormatHover(h, r.view.Options())
	if err != nil {
		t.Fatal(err)
	}
	rng, err := ident.Declaration.MappedRange[0].Range()
	if err != nil {
		t.Fatal(err)
	}
	if d.IsType {
		rng, err = ident.Type.Range()
		if err != nil {
			t.Fatal(err)
		}
		hover = ""
	}
	didSomething := false
	if hover != "" {
		didSomething = true
		tag := fmt.Sprintf("%s-hover", d.Name)
		expectHover := string(r.data.Golden(tag, d.Src.URI().Filename(), func() ([]byte, error) {
			return []byte(hover), nil
		}))
		if hover != expectHover {
			t.Errorf("for %v got %q want %q", d.Src, hover, expectHover)
		}
	}
	if !d.OnlyHover {
		didSomething = true
		if _, defRng, err := spanToRange(r.data, d.Def); err != nil {
			t.Fatal(err)
		} else if rng != defRng {
			t.Errorf("for %v got %v want %v", d.Src, rng, defRng)
		}
	}
	if !didSomething {
		t.Errorf("no tests ran for %s", d.Src.URI())
	}
}

func (r *runner) Implementation(t *testing.T, spn span.Span, impls []span.Span) {
	sm, err := r.data.Mapper(spn.URI())
	if err != nil {
		t.Fatal(err)
	}
	loc, err := sm.Location(spn)
	if err != nil {
		t.Fatalf("failed for %v: %v", spn, err)
	}
	fh, err := r.view.Snapshot().GetFile(spn.URI())
	if err != nil {
		t.Fatal(err)
	}
	locs, err := source.Implementation(r.ctx, r.view.Snapshot(), fh, loc.Range.Start)
	if err != nil {
		t.Fatalf("failed for %v: %v", spn, err)
	}
	if len(locs) != len(impls) {
		t.Fatalf("got %d locations for implementation, expected %d", len(locs), len(impls))
	}
	var results []span.Span
	for i := range locs {
		locURI := locs[i].URI.SpanURI()
		lm, err := r.data.Mapper(locURI)
		if err != nil {
			t.Fatal(err)
		}
		imp, err := lm.Span(locs[i])
		if err != nil {
			t.Fatalf("failed for %v: %v", locs[i], err)
		}
		results = append(results, imp)
	}
	// Sort results and expected to make tests deterministic.
	sort.SliceStable(results, func(i, j int) bool {
		return span.Compare(results[i], results[j]) == -1
	})
	sort.SliceStable(impls, func(i, j int) bool {
		return span.Compare(impls[i], impls[j]) == -1
	})
	for i := range results {
		if results[i] != impls[i] {
			t.Errorf("for %dth implementation of %v got %v want %v", i, spn, results[i], impls[i])
		}
	}
}

func (r *runner) Highlight(t *testing.T, src span.Span, locations []span.Span) {
	ctx := r.ctx
	m, srcRng, err := spanToRange(r.data, src)
	if err != nil {
		t.Fatal(err)
	}
	fh, err := r.view.Snapshot().GetFile(src.URI())
	if err != nil {
		t.Fatal(err)
	}
	highlights, err := source.Highlight(ctx, r.view.Snapshot(), fh, srcRng.Start)
	if err != nil {
		t.Errorf("highlight failed for %s: %v", src.URI(), err)
	}
	if len(highlights) != len(locations) {
		t.Errorf("got %d highlights for highlight at %v:%v:%v, expected %d", len(highlights), src.URI().Filename(), src.Start().Line(), src.Start().Column(), len(locations))
	}
	// Check to make sure highlights have a valid range.
	var results []span.Span
	for i := range highlights {
		h, err := m.RangeSpan(highlights[i])
		if err != nil {
			t.Fatalf("failed for %v: %v", highlights[i], err)
		}
		results = append(results, h)
	}
	// Sort results to make tests deterministic since DocumentHighlight uses a map.
	sort.SliceStable(results, func(i, j int) bool {
		return span.Compare(results[i], results[j]) == -1
	})
	// Check to make sure all the expected highlights are found.
	for i := range results {
		if results[i] != locations[i] {
			t.Errorf("want %v, got %v\n", locations[i], results[i])
		}
	}
}

func (r *runner) References(t *testing.T, src span.Span, itemList []span.Span) {
	ctx := r.ctx
	_, srcRng, err := spanToRange(r.data, src)
	if err != nil {
		t.Fatal(err)
	}
	snapshot := r.view.Snapshot()
	fh, err := snapshot.GetFile(src.URI())
	if err != nil {
		t.Fatal(err)
	}
	for _, includeDeclaration := range []bool{true, false} {
		t.Run(fmt.Sprintf("refs-declaration-%v", includeDeclaration), func(t *testing.T) {
			want := make(map[span.Span]bool)
			for i, pos := range itemList {
				// We don't want the first result if we aren't including the declaration.
				if i == 0 && !includeDeclaration {
					continue
				}
				want[pos] = true
			}
			refs, err := source.References(ctx, snapshot, fh, srcRng.Start, includeDeclaration)
			if err != nil {
				t.Fatalf("failed for %s: %v", src, err)
			}
			got := make(map[span.Span]bool)
			for _, refInfo := range refs {
				refSpan, err := refInfo.Span()
				if err != nil {
					t.Fatal(err)
				}
				got[refSpan] = true
			}
			if len(got) != len(want) {
				t.Errorf("references failed: different lengths got %v want %v", len(got), len(want))
			}
			for spn := range got {
				if !want[spn] {
					t.Errorf("references failed: incorrect references got %v want locations %v", got, want)
				}
			}
		})
	}
}

func (r *runner) Rename(t *testing.T, spn span.Span, newText string) {
	ctx := r.ctx
	tag := fmt.Sprintf("%s-rename", newText)

	_, srcRng, err := spanToRange(r.data, spn)
	if err != nil {
		t.Fatal(err)
	}
	fh, err := r.view.Snapshot().GetFile(spn.URI())
	if err != nil {
		t.Fatal(err)
	}
	changes, err := source.Rename(r.ctx, r.view.Snapshot(), fh, srcRng.Start, newText)
	if err != nil {
		renamed := string(r.data.Golden(tag, spn.URI().Filename(), func() ([]byte, error) {
			return []byte(err.Error()), nil
		}))
		if err.Error() != renamed {
			t.Errorf("rename failed for %s, expected:\n%v\ngot:\n%v\n", newText, renamed, err)
		}
		return
	}

	var res []string
	for editURI, edits := range changes {
		fh, err := r.view.Snapshot().GetFile(editURI)
		if err != nil {
			t.Fatal(err)
		}
		data, _, err := fh.Read(ctx)
		if err != nil {
			t.Fatal(err)
		}
		m, err := r.data.Mapper(fh.Identity().URI)
		if err != nil {
			t.Fatal(err)
		}
		diffEdits, err := source.FromProtocolEdits(m, edits)
		if err != nil {
			t.Fatal(err)
		}
		contents := applyEdits(string(data), diffEdits)
		if len(changes) > 1 {
			filename := filepath.Base(editURI.Filename())
			contents = fmt.Sprintf("%s:\n%s", filename, contents)
		}
		res = append(res, contents)
	}

	// Sort on filename
	sort.Strings(res)

	var got string
	for i, val := range res {
		if i != 0 {
			got += "\n"
		}
		got += val
	}

	renamed := string(r.data.Golden(tag, spn.URI().Filename(), func() ([]byte, error) {
		return []byte(got), nil
	}))

	if renamed != got {
		t.Errorf("rename failed for %s, expected:\n%v\ngot:\n%v", newText, renamed, got)
	}
}

func applyEdits(contents string, edits []diff.TextEdit) string {
	res := contents

	// Apply the edits from the end of the file forward
	// to preserve the offsets
	for i := len(edits) - 1; i >= 0; i-- {
		edit := edits[i]
		start := edit.Span.Start().Offset()
		end := edit.Span.End().Offset()
		tmp := res[0:start] + edit.NewText
		res = tmp + res[end:]
	}
	return res
}

func (r *runner) PrepareRename(t *testing.T, src span.Span, want *source.PrepareItem) {
	_, srcRng, err := spanToRange(r.data, src)
	if err != nil {
		t.Fatal(err)
	}
	// Find the identifier at the position.
	fh, err := r.view.Snapshot().GetFile(src.URI())
	if err != nil {
		t.Fatal(err)
	}
	item, err := source.PrepareRename(r.ctx, r.view.Snapshot(), fh, srcRng.Start)
	if err != nil {
		if want.Text != "" { // expected an ident.
			t.Errorf("prepare rename failed for %v: got error: %v", src, err)
		}
		return
	}
	if item == nil {
		if want.Text != "" {
			t.Errorf("prepare rename failed for %v: got nil", src)
		}
		return
	}
	if want.Text == "" {
		t.Errorf("prepare rename failed for %v: expected nil, got %v", src, item)
		return
	}
	if item.Range.Start == item.Range.End {
		// Special case for 0-length ranges. Marks can't specify a 0-length range,
		// so just compare the start.
		if item.Range.Start != want.Range.Start {
			t.Errorf("prepare rename failed: incorrect point, got %v want %v", item.Range.Start, want.Range.Start)
		}
	} else {
		if protocol.CompareRange(item.Range, want.Range) != 0 {
			t.Errorf("prepare rename failed: incorrect range got %v want %v", item.Range, want.Range)
		}
	}
}

func (r *runner) Symbols(t *testing.T, uri span.URI, expectedSymbols []protocol.DocumentSymbol) {
	fh, err := r.view.Snapshot().GetFile(uri)
	if err != nil {
		t.Fatal(err)
	}
	symbols, err := source.DocumentSymbols(r.ctx, r.view.Snapshot(), fh)
	if err != nil {
		t.Errorf("symbols failed for %s: %v", uri, err)
	}
	if len(symbols) != len(expectedSymbols) {
		t.Errorf("want %d top-level symbols in %v, got %d", len(expectedSymbols), uri, len(symbols))
		return
	}
	if diff := tests.DiffSymbols(t, uri, expectedSymbols, symbols); diff != "" {
		t.Error(diff)
	}
}

func (r *runner) WorkspaceSymbols(t *testing.T, query string, expectedSymbols []protocol.SymbolInformation, dirs map[string]struct{}) {
	got := r.callWorkspaceSymbols(t, query, func(opts *source.Options) {
		opts.Matcher = source.CaseInsensitive
	})
	got = tests.FilterWorkspaceSymbols(got, dirs)
	if len(got) != len(expectedSymbols) {
		t.Errorf("want %d symbols, got %d", len(expectedSymbols), len(got))
		return
	}
	if diff := tests.DiffWorkspaceSymbols(expectedSymbols, got); diff != "" {
		t.Error(diff)
	}
}

func (r *runner) FuzzyWorkspaceSymbols(t *testing.T, query string, expectedSymbols []protocol.SymbolInformation, dirs map[string]struct{}) {
	got := r.callWorkspaceSymbols(t, query, func(opts *source.Options) {
		opts.Matcher = source.Fuzzy
	})
	got = tests.FilterWorkspaceSymbols(got, dirs)
	if len(got) != len(expectedSymbols) {
		t.Errorf("want %d symbols, got %d", len(expectedSymbols), len(got))
		return
	}
	if diff := tests.DiffWorkspaceSymbols(expectedSymbols, got); diff != "" {
		t.Error(diff)
	}
}

func (r *runner) CaseSensitiveWorkspaceSymbols(t *testing.T, query string, expectedSymbols []protocol.SymbolInformation, dirs map[string]struct{}) {
	got := r.callWorkspaceSymbols(t, query, func(opts *source.Options) {
		opts.Matcher = source.CaseSensitive
	})
	got = tests.FilterWorkspaceSymbols(got, dirs)
	if len(got) != len(expectedSymbols) {
		t.Errorf("want %d symbols, got %d", len(expectedSymbols), len(got))
		return
	}
	if diff := tests.DiffWorkspaceSymbols(expectedSymbols, got); diff != "" {
		t.Error(diff)
	}
}

func (r *runner) callWorkspaceSymbols(t *testing.T, query string, options func(*source.Options)) []protocol.SymbolInformation {
	t.Helper()

	original := r.view.Options()
	modified := original
	options(&modified)
	view, err := r.view.SetOptions(r.ctx, modified)
	if err != nil {
		t.Fatal(err)
	}
	defer r.view.SetOptions(r.ctx, original)

	got, err := source.WorkspaceSymbols(r.ctx, []source.View{view}, query)
	if err != nil {
		t.Fatal(err)
	}
	return got
}

func (r *runner) SignatureHelp(t *testing.T, spn span.Span, want *protocol.SignatureHelp) {
	_, rng, err := spanToRange(r.data, spn)
	if err != nil {
		t.Fatal(err)
	}
	fh, err := r.view.Snapshot().GetFile(spn.URI())
	if err != nil {
		t.Fatal(err)
	}
	gotSignature, gotActiveParameter, err := source.SignatureHelp(r.ctx, r.view.Snapshot(), fh, rng.Start)
	if err != nil {
		// Only fail if we got an error we did not expect.
		if want != nil {
			t.Fatalf("failed for %v: %v", spn, err)
		}
		return
	}
	if gotSignature == nil {
		if want != nil {
			t.Fatalf("got nil signature, but expected %v", want)
		}
		return
	}
	got := &protocol.SignatureHelp{
		Signatures:      []protocol.SignatureInformation{*gotSignature},
		ActiveParameter: float64(gotActiveParameter),
	}
	if diff := tests.DiffSignatures(spn, got, want); diff != "" {
		t.Error(diff)
	}
}

func (r *runner) Link(t *testing.T, uri span.URI, wantLinks []tests.Link) {
	// This is a pure LSP feature, no source level functionality to be tested.
}

func (r *runner) CodeLens(t *testing.T, uri span.URI, want []protocol.CodeLens) {
	fh, err := r.view.Snapshot().GetFile(uri)
	if err != nil {
		t.Fatal(err)
	}
	got, err := source.CodeLens(r.ctx, r.view.Snapshot(), fh)
	if err != nil {
		t.Fatal(err)
	}
	if diff := tests.DiffCodeLens(uri, want, got); diff != "" {
		t.Error(diff)
	}
}

func spanToRange(data *tests.Data, spn span.Span) (*protocol.ColumnMapper, protocol.Range, error) {
	m, err := data.Mapper(spn.URI())
	if err != nil {
		return nil, protocol.Range{}, err
	}
	srcRng, err := m.Range(spn)
	if err != nil {
		return nil, protocol.Range{}, err
	}
	return m, srcRng, nil
}
