mirror of
https://github.com/gogrlx/grlx-lsp.git
synced 2026-04-02 03:18:47 -07:00
- Add completion_test.go: tests for top-level, ingredient.method, property, requisite type, and step ID completions - Add hover_test.go: tests for markdown generation, word extraction, and edge cases - Add diagnostics_test.go: tests for nil recipe, parse errors, empty ingredient, requisite validation, range helpers - Update all dependencies to latest versions - Add target/ to .gitignore (stale Rust build artifacts)
129 lines
2.9 KiB
Go
129 lines
2.9 KiB
Go
package lsp
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/gogrlx/grlx-lsp/internal/schema"
|
|
)
|
|
|
|
func TestBuildMethodMarkdown(t *testing.T) {
|
|
m := &schema.Method{
|
|
Name: "managed",
|
|
Description: "Download and manage a file from a source",
|
|
Properties: []schema.Property{
|
|
{Key: "name", Type: "string", Required: true, Description: "The file path"},
|
|
{Key: "source", Type: "string", Required: true, Description: "Source URL"},
|
|
{Key: "mode", Type: "string", Required: false, Description: "File permissions"},
|
|
},
|
|
}
|
|
|
|
md := buildMethodMarkdown("file", m)
|
|
|
|
// Should contain header
|
|
if !contains(md, "### file.managed") {
|
|
t.Error("expected markdown header with ingredient.method")
|
|
}
|
|
|
|
// Should contain description
|
|
if !contains(md, "Download and manage a file") {
|
|
t.Error("expected description in markdown")
|
|
}
|
|
|
|
// Should contain properties table
|
|
if !contains(md, "| Property |") {
|
|
t.Error("expected properties table")
|
|
}
|
|
if !contains(md, "| `name` |") {
|
|
t.Error("expected name property in table")
|
|
}
|
|
if !contains(md, "| `source` |") {
|
|
t.Error("expected source property in table")
|
|
}
|
|
|
|
// Required properties should show "yes"
|
|
if !contains(md, "| yes |") {
|
|
t.Error("expected 'yes' for required properties")
|
|
}
|
|
}
|
|
|
|
func TestBuildMethodMarkdownNoProperties(t *testing.T) {
|
|
m := &schema.Method{
|
|
Name: "cleaned",
|
|
Description: "Clean package cache",
|
|
}
|
|
|
|
md := buildMethodMarkdown("pkg", m)
|
|
if !contains(md, "### pkg.cleaned") {
|
|
t.Error("expected header")
|
|
}
|
|
// Should not contain a table
|
|
if contains(md, "| Property |") {
|
|
t.Error("should not have property table for method with no properties")
|
|
}
|
|
}
|
|
|
|
func TestBuildMethodMarkdownNoDescription(t *testing.T) {
|
|
m := &schema.Method{
|
|
Name: "test",
|
|
Properties: []schema.Property{
|
|
{Key: "name", Type: "string", Required: true},
|
|
},
|
|
}
|
|
|
|
md := buildMethodMarkdown("foo", m)
|
|
if !contains(md, "### foo.test") {
|
|
t.Error("expected header")
|
|
}
|
|
if !contains(md, "| `name` |") {
|
|
t.Error("expected name property")
|
|
}
|
|
}
|
|
|
|
func TestIsWordChar(t *testing.T) {
|
|
tests := []struct {
|
|
b byte
|
|
want bool
|
|
}{
|
|
{'a', true},
|
|
{'z', true},
|
|
{'A', true},
|
|
{'Z', true},
|
|
{'0', true},
|
|
{'9', true},
|
|
{'_', true},
|
|
{'.', true},
|
|
{'-', true},
|
|
{' ', false},
|
|
{':', false},
|
|
{'\t', false},
|
|
{'(', false},
|
|
}
|
|
for _, tt := range tests {
|
|
got := isWordChar(tt.b)
|
|
if got != tt.want {
|
|
t.Errorf("isWordChar(%q) = %v, want %v", tt.b, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestWordAtPositionEdgeCases(t *testing.T) {
|
|
tests := []struct {
|
|
line string
|
|
col int
|
|
want string
|
|
}{
|
|
{"", 0, ""},
|
|
{"hello", 100, "hello"}, // col beyond line length
|
|
{" file.managed:", 2, "file.managed"}, // col 2 is start of word
|
|
{"file.managed:", 12, "file.managed"}, // just before colon
|
|
{"a", 0, "a"},
|
|
{"a", 1, "a"},
|
|
}
|
|
for _, tt := range tests {
|
|
got := wordAtPosition(tt.line, tt.col)
|
|
if got != tt.want {
|
|
t.Errorf("wordAtPosition(%q, %d) = %q, want %q", tt.line, tt.col, got, tt.want)
|
|
}
|
|
}
|
|
}
|