clerk/internal/lsp/lsputil/lineindex_test.go (view raw)
Oleksandr Smirnov
Oleksandr Smirnov
olexsmir@gmail.com perf: lsp: resolve positions and entries via cached line index..., 1 month ago
olexsmir@gmail.com perf: lsp: resolve positions and entries via cached line index..., 1 month ago
| 1 | package lsputil |
| 2 | |
| 3 | import ( |
| 4 | "testing" |
| 5 | |
| 6 | "olexsmir.xyz/clerk/journal/token" |
| 7 | ) |
| 8 | |
| 9 | // TestLineIndexParity asserts Offset/Position agree with the standalone |
| 10 | // converters, including clamped out-of-range positions. |
| 11 | func TestLineIndexParity(t *testing.T) { |
| 12 | contents := []string{"abc\ndef\n", "abc\ndef", "abc", "a\nb\nc", "", "один\nдва\n"} |
| 13 | for _, content := range contents { |
| 14 | li := NewLineIndex(content) |
| 15 | for _, line := range []int{0, 1, 2, 3, 100} { |
| 16 | for _, col := range []int{0, 1, 5} { |
| 17 | off := li.Offset(line, col) |
| 18 | if want := Offset(content, line, col); off != want { |
| 19 | t.Errorf("content %q: Offset(%d,%d) = %d, want %d", content, line, col, off, want) |
| 20 | } |
| 21 | pos := li.Position(off) |
| 22 | if want := Position(content, off); pos != want { |
| 23 | t.Errorf("content %q: Position(%d) = %+v, want %+v", content, off, pos, want) |
| 24 | } |
| 25 | } |
| 26 | } |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | func TestLineIndexSpanRange(t *testing.T) { |
| 31 | content := "2024-01-15 grocery\n expenses:food $50\n assets:cash\n" |
| 32 | li := NewLineIndex(content) |
| 33 | // span ending at the start of the next line clamps to the line end |
| 34 | span := token.Span{ |
| 35 | Start: token.Pos{Offset: 11, Line: 1, Col: 12}, |
| 36 | End: token.Pos{Offset: 18, Line: 2, Col: 0}, |
| 37 | } |
| 38 | rng := li.SpanRange(span) |
| 39 | if rng.Start.Line != 0 || rng.Start.Character != 11 || rng.End.Line != 0 || rng.End.Character != 18 { |
| 40 | t.Errorf("grocery span = %+v, want 0:11-0:18", rng) |
| 41 | } |
| 42 | } |