all repos

clerk @ 122b3849cfb7f6cd41be7fcceaeced24df42dae9

missing tooling for ledger/hledger

clerk/internal/lsp/textdocument_definition_test.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
tests: consistent golden.Read placement, 1 month ago
1
package lsp
2
3
import (
4
	"fmt"
5
	"path/filepath"
6
	"strings"
7
	"testing"
8
9
	"go.lsp.dev/protocol"
10
	"go.lsp.dev/uri"
11
12
	"olexsmir.xyz/clerk/internal/lsp/lsputil"
13
	"olexsmir.xyz/clerk/internal/testutil/golden"
14
	"olexsmir.xyz/clerk/journal"
15
)
16
17
func TestServer_Definition_DocumentNotFound(t *testing.T) {
18
	srv := NewServer("test")
19
	res, err := srv.server.Definition(t.Context(), &protocol.DefinitionParams{
20
		TextDocumentPositionParams: protocol.TextDocumentPositionParams{
21
			TextDocument: protocol.TextDocumentIdentifier{URI: uri.URI("file:///nonexistent.journal")},
22
			Position:     protocol.Position{Line: 0, Character: 0},
23
		},
24
	})
25
	if err != nil {
26
		t.Fatal(err)
27
	}
28
	if res != nil {
29
		t.Errorf("got %v, want nil", res)
30
	}
31
}
32
33
func TestGolden_Definition(t *testing.T) {
34
	for _, tt := range []string{"definition-journal", "definition-include"} {
35
		t.Run(tt, func(t *testing.T) {
36
			ar := golden.Read(t, tt)
37
			h := newTxtarHarness(t, ar)
38
39
			var b strings.Builder
40
			for i := range h.cursors {
41
				pos := h.textDocumentPosition(i).Position
42
				res, err := h.srv.Definition(t.Context(), &protocol.DefinitionParams{
43
					TextDocumentPositionParams: h.textDocumentPosition(i),
44
				})
45
				if err != nil {
46
					t.Fatal(err)
47
				}
48
				locs, _ := res.(protocol.LocationSlice)
49
				if len(locs) == 0 {
50
					fmt.Fprintf(&b, "%d:%d <none>\n", pos.Line, pos.Character)
51
					continue
52
				}
53
				r := locs[0].Range
54
				fmt.Fprintf(&b, "%d:%d %s %d:%d-%d:%d\n", pos.Line, pos.Character,
55
					filepath.Base(locs[0].URI.Path()),
56
					r.Start.Line, r.Start.Character, r.End.Line, r.End.Character)
57
			}
58
			golden.Assert(t, ar, b.String())
59
		})
60
	}
61
}
62
63
func BenchmarkDefinition(b *testing.B) {
64
	path := "../../journal/testdata/journals/actual-1ktxns-100accts.journal"
65
	abs, err := filepath.Abs(path)
66
	if err != nil {
67
		b.Fatal(err)
68
	}
69
	rj, err := journal.NewLoader().Resolve(abs)
70
	if err != nil {
71
		b.Fatal(err)
72
	}
73
	content := string(rj.Occurrences[0].Src)
74
75
	srv := NewServer("test")
76
	u := uri.File(abs)
77
	srv.server.openDoc(u, content, 1, "journal")
78
	srv.server.analysisFor(u) // warm the per-doc cache
79
80
	for tname, tt := range map[string]int{
81
		"1k txns, account":   strings.Index(content, "\n  1:2:3 ") + len("\n  ") + 2,
82
		"1k txns, payee":     strings.Index(content, "transaction 1") + len("transaction "),
83
		"1k txns, commodity": strings.Index(content, "2 B @@") + len("2 B"),
84
	} {
85
		b.Run(tname, func(b *testing.B) {
86
			line, col := lsputil.LineCol(content, tt)
87
			params := &protocol.DefinitionParams{
88
				TextDocumentPositionParams: protocol.TextDocumentPositionParams{
89
					TextDocument: protocol.TextDocumentIdentifier{URI: u},
90
					Position:     protocol.Position{Line: uint32(line), Character: uint32(col)},
91
				},
92
			}
93
			// warm up: first request resolves the symbol lazily; assert it found one
94
			res, err := srv.server.Definition(b.Context(), params)
95
			if err != nil {
96
				b.Fatal(err)
97
			}
98
			locs, ok := res.(protocol.LocationSlice)
99
			if !ok || len(locs) == 0 {
100
				b.Fatalf("%s: no definition", tname)
101
			}
102
			b.ReportAllocs()
103
			b.ResetTimer()
104
			for b.Loop() {
105
				if _, err := srv.server.Definition(b.Context(), params); err != nil {
106
					b.Fatal(err)
107
				}
108
			}
109
		})
110
	}
111
}