Files
filepuff-mcp/internal/parser/ast_test.go
T
lukaszraczylo 98a499ab20 fix(parser): guard FindNodeAtPosition against position underflow
line/col are 1-indexed and converted via uint32(line-1); a caller passing 0
wrapped to 4294967295, feeding a garbage Point into tree-sitter. Reachable from
the LSP-down AST fallback with caller-supplied coordinates. Reject non-positive
positions up front. Adds tests (the function was previously 0% covered).
2026-06-21 02:01:50 +01:00

46 lines
1.3 KiB
Go

package parser
import (
"context"
"testing"
)
func TestFindNodeAtPosition(t *testing.T) {
r := NewRegistry()
content := []byte("package main\n\nfunc Hello() string { return \"hi\" }\n")
res, err := r.Parse(context.Background(), "test.go", content)
if err != nil {
t.Fatalf("parse: %v", err)
}
t.Run("nil tree", func(t *testing.T) {
if FindNodeAtPosition(nil, 3, 6) != nil {
t.Error("nil tree must return nil")
}
})
// Guard against the uint32 underflow: non-positive coordinates must return
// nil, never wrap to a huge Row/Column.
t.Run("non-positive coordinates", func(t *testing.T) {
for _, c := range []struct{ line, col int }{{0, 0}, {0, 5}, {3, 0}, {-1, 4}} {
if got := FindNodeAtPosition(res.Tree, c.line, c.col); got != nil {
t.Errorf("FindNodeAtPosition(tree, %d, %d) = %v, want nil", c.line, c.col, got.Type())
}
}
})
t.Run("out of range line returns nil", func(t *testing.T) {
if got := FindNodeAtPosition(res.Tree, 99999, 1); got != nil {
t.Errorf("far-out-of-range line should return nil, got %v", got.Type())
}
})
t.Run("valid position returns a node", func(t *testing.T) {
// Line 3, column 6 lands inside "Hello".
got := FindNodeAtPosition(res.Tree, 3, 6)
if got == nil {
t.Fatal("expected a node at a valid in-range position, got nil")
}
})
}