Major changes: - Refactor CLI entry point to Cobra commands (root, setup, scan, doctor, install, update, lsp, mcp, skills, config, version) - Add LSP registry with health checks, auto-install, and editor config generation - Add MCP registry with editor detection, status tracking, and per-editor configuration - Add workflow engine with planner and step execution for automated task chains - Add conversation search, export (Markdown/JSON), and detailed token counting - Add streaming shell chat handler with tool call/result events - Add skill validation, dry-run testing, and export endpoints - Enrich dashboard with Tools/Activity/Status tabs and tool cards grid - Add PRD documentation - Complete i18n for both EN and FR 💘 Generated with Crush Assisted-by: GLM-5.1 via Crush <crush@charm.land>
143 lines
3.4 KiB
Go
143 lines
3.4 KiB
Go
package lsp
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestDefaultLSPRegistry(t *testing.T) {
|
|
reg := DefaultLSPRegistry()
|
|
if reg.SchemaVersion != "v1" {
|
|
t.Errorf("Expected v1, got %s", reg.SchemaVersion)
|
|
}
|
|
if len(reg.Servers) == 0 {
|
|
t.Error("Default LSP registry should have servers")
|
|
}
|
|
|
|
names := map[string]bool{}
|
|
for _, s := range reg.Servers {
|
|
if names[s.Name] {
|
|
t.Errorf("Duplicate server name: %s", s.Name)
|
|
}
|
|
names[s.Name] = true
|
|
if s.Command == "" {
|
|
t.Errorf("Server %s missing command", s.Name)
|
|
}
|
|
if s.Language == "" {
|
|
t.Errorf("Server %s missing language", s.Name)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSaveAndLoadLSPRegistry(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
SetLSPRegistryPath(filepath.Join(tmpDir, "lsp-registry.yaml"))
|
|
|
|
reg := DefaultLSPRegistry()
|
|
if err := SaveLSPRegistry(reg); err != nil {
|
|
t.Fatalf("SaveLSPRegistry failed: %v", err)
|
|
}
|
|
|
|
loaded, err := LoadLSPRegistry()
|
|
if err != nil {
|
|
t.Fatalf("LoadLSPRegistry failed: %v", err)
|
|
}
|
|
if len(loaded.Servers) != len(reg.Servers) {
|
|
t.Errorf("Expected %d servers, got %d", len(reg.Servers), len(loaded.Servers))
|
|
}
|
|
}
|
|
|
|
func TestInitLSPRegistry(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
SetLSPRegistryPath(filepath.Join(tmpDir, "lsp-reg.yaml"))
|
|
|
|
if err := InitLSPRegistry(); err != nil {
|
|
t.Fatalf("InitLSPRegistry failed: %v", err)
|
|
}
|
|
|
|
if _, err := os.Stat(filepath.Join(tmpDir, "lsp-reg.yaml")); os.IsNotExist(err) {
|
|
t.Error("LSP registry file should be created")
|
|
}
|
|
}
|
|
|
|
func TestDetectProjectLanguages(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
|
|
os.WriteFile(filepath.Join(tmpDir, "go.mod"), []byte("module test\ngo 1.24\n"), 0644)
|
|
os.WriteFile(filepath.Join(tmpDir, "package.json"), []byte(`{"name": "test"}`), 0644)
|
|
|
|
languages := DetectProjectLanguages(tmpDir)
|
|
if len(languages) == 0 {
|
|
t.Error("Should detect languages")
|
|
}
|
|
|
|
langSet := map[string]bool{}
|
|
for _, l := range languages {
|
|
langSet[l] = true
|
|
}
|
|
if !langSet["go"] {
|
|
t.Error("Should detect Go")
|
|
}
|
|
if !langSet["typescript"] {
|
|
t.Error("Should detect TypeScript/JS from package.json")
|
|
}
|
|
}
|
|
|
|
func TestDetectProjectLanguagesEmpty(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
languages := DetectProjectLanguages(tmpDir)
|
|
if len(languages) != 0 {
|
|
t.Errorf("Empty dir should detect no languages, got %v", languages)
|
|
}
|
|
}
|
|
|
|
func TestGenerateNeovimConfig(t *testing.T) {
|
|
servers := []RegistryEntry{
|
|
{Name: "gopls", Language: "go", NeovimSetup: "lspconfig.gopls.setup{}"},
|
|
{Name: "pyright", Language: "python", NeovimSetup: "lspconfig.pyright.setup{}"},
|
|
}
|
|
|
|
config := GenerateNeovimConfig(servers)
|
|
if config == "" {
|
|
t.Error("Config should not be empty")
|
|
}
|
|
if len(config) < 50 {
|
|
t.Error("Config seems too short")
|
|
}
|
|
}
|
|
|
|
func TestGenerateHelixConfig(t *testing.T) {
|
|
servers := []RegistryEntry{
|
|
{Name: "gopls", Language: "go", HelixLanguage: "go"},
|
|
}
|
|
|
|
config := GenerateHelixConfig(servers)
|
|
if config == "" {
|
|
t.Error("Config should not be empty")
|
|
}
|
|
}
|
|
|
|
func TestGenerateVSCodeRecommendations(t *testing.T) {
|
|
servers := []RegistryEntry{
|
|
{Name: "gopls", Language: "go"},
|
|
{Name: "pyright", Language: "python"},
|
|
}
|
|
|
|
exts := GenerateVSCodeRecommendations(servers)
|
|
if len(exts) == 0 {
|
|
t.Error("Should return some extensions")
|
|
}
|
|
}
|
|
|
|
func TestHealthCheck(t *testing.T) {
|
|
healthy, detail := HealthCheck("gopls")
|
|
if healthy && detail == "" {
|
|
t.Error("If healthy, should have version detail")
|
|
}
|
|
}
|
|
|
|
func TestHealthCheckUnknown(t *testing.T) {
|
|
_, _ = HealthCheck("nonexistent-server")
|
|
}
|