Files
MonocoEditor-With-Lsp-Backend/backend/internal/completion/manager_test.go
meowrain 57afb90bc0 feat: enhance completion service with session management and language support
- Introduced session management using Redis for tracking active sessions.
- Added session claiming and releasing functionality in the completion manager.
- Enhanced HTTP and WebSocket completion endpoints to support multiple languages.
- Implemented request timeout and maximum body size configurations for API routes.
- Updated client-side code to handle session IDs and language parameters in completion requests.
- Improved error handling for unsupported languages and session conflicts.
- Added tests for the completion manager to ensure proper session handling and cleanup.
2026-02-15 16:22:01 +08:00

126 lines
3.0 KiB
Go

package completion
import (
"context"
"errors"
"fmt"
"testing"
"time"
)
type fakeRuntimeClient struct {
closed bool
}
func (f *fakeRuntimeClient) DidOpen(_ context.Context, _ string, _ string, _ int) error {
return nil
}
func (f *fakeRuntimeClient) DidChange(_ context.Context, _ string, _ string, _ int) error {
return nil
}
func (f *fakeRuntimeClient) Completion(_ context.Context, _ string, _ int, _ int) (Response, error) {
return Response{
Items: []Item{{Label: "ok"}},
}, nil
}
func (f *fakeRuntimeClient) Close() error {
f.closed = true
return nil
}
func TestManagerCompleteSelectsLanguageAndSession(t *testing.T) {
createCount := 0
factory := func(_ context.Context, spec LanguageServerSpec, _ string) (RuntimeClient, error) {
createCount++
if spec.Language != "go" {
return nil, fmt.Errorf("unexpected language: %s", spec.Language)
}
return &fakeRuntimeClient{}, nil
}
m := NewManager(ManagerConfig{WorkspaceDir: "."}, []LanguageServerSpec{
{Language: "go", LanguageID: "go", Command: "gopls"},
}, factory)
defer m.Close()
for i := 0; i < 2; i++ {
resp, err := m.Complete(context.Background(), Request{
Language: "go",
SessionID: "s1",
URI: "file:///main.go",
Text: "package main",
Line: 0,
Character: 0,
})
if err != nil {
t.Fatalf("Complete() error = %v", err)
}
if len(resp.Items) != 1 || resp.Items[0].Label != "ok" {
t.Fatalf("unexpected response: %+v", resp)
}
}
if createCount != 1 {
t.Fatalf("expected one client creation, got %d", createCount)
}
}
func TestManagerCompleteUnsupportedLanguage(t *testing.T) {
m := NewManager(ManagerConfig{}, []LanguageServerSpec{
{Language: "go", LanguageID: "go", Command: "gopls"},
}, func(_ context.Context, _ LanguageServerSpec, _ string) (RuntimeClient, error) {
return &fakeRuntimeClient{}, nil
})
defer m.Close()
_, err := m.Complete(context.Background(), Request{
Language: "python",
URI: "file:///main.py",
Text: "print('hi')",
Line: 0,
Character: 0,
})
if !errors.Is(err, ErrUnsupportedLanguage) {
t.Fatalf("expected ErrUnsupportedLanguage, got %v", err)
}
}
func TestManagerCleanupIdleSession(t *testing.T) {
client := &fakeRuntimeClient{}
m := NewManager(ManagerConfig{
WorkspaceDir: ".",
SessionTTL: 30 * time.Millisecond,
CleanupInterval: 10 * time.Millisecond,
}, []LanguageServerSpec{
{Language: "go", LanguageID: "go", Command: "gopls"},
}, func(_ context.Context, _ LanguageServerSpec, _ string) (RuntimeClient, error) {
return client, nil
})
defer m.Close()
_, err := m.Complete(context.Background(), Request{
Language: "go",
SessionID: "s2",
URI: "file:///main.go",
Text: "package main",
Line: 0,
Character: 0,
})
if err != nil {
t.Fatalf("Complete() error = %v", err)
}
time.Sleep(90 * time.Millisecond)
sessions := m.ActiveSessions()
if sessions["go"] != 0 {
t.Fatalf("expected session cleanup, got %+v", sessions)
}
if !client.closed {
t.Fatal("expected client to be closed by cleanup")
}
}