Files
cleveragents-core/features/lsp_registry.feature

239 lines
11 KiB
Gherkin

@phase2 @domain @lsp @lsp_registry
Feature: LSP Registry and Runtime Stubs
As a system managing LSP server configurations
I want to register, look up, list, and remove LSP servers
And verify that the runtime stub raises in local mode
So that actors can discover language servers and bindings are validated
Background:
Given a clean LSP registry
# ---------------------------------------------------------------------------
# Register LSP server config
# ---------------------------------------------------------------------------
@lsp_reg_create
Scenario: Register a new LSP server config
Given an LSP server config named "local/pyright" for language "python" with command "pyright-langserver"
When the LSP server is registered
Then the LSP registry should contain "local/pyright"
And the LSP registry should have 1 server
@lsp_reg_create
Scenario: Register LSP server with multiple languages
Given an LSP server config named "local/tsserver" for languages "typescript,javascript" with command "typescript-language-server"
When the LSP server is registered
Then the LSP registry should contain "local/tsserver"
And the LSP server "local/tsserver" should support language "typescript"
And the LSP server "local/tsserver" should support language "javascript"
@lsp_reg_create
Scenario: Register LSP server with capabilities
Given an LSP server config named "local/pyright" for language "python" with command "pyright-langserver"
And the LSP server config has capabilities "diagnostics,completions,type_info"
When the LSP server is registered
Then the LSP server "local/pyright" should have 3 capabilities
@lsp_reg_create @error_handling
Scenario: Registering a duplicate server name is rejected
Given an LSP server config named "local/pyright" for language "python" with command "pyright-langserver"
And the LSP server is registered
When a second LSP server with the same name "local/pyright" is registered
Then a ValueError should be raised mentioning "already registered"
# ---------------------------------------------------------------------------
# Lookup by name
# ---------------------------------------------------------------------------
@lsp_reg_get
Scenario: Lookup a registered server by name
Given an LSP server config named "local/pyright" for language "python" with command "pyright-langserver"
And the LSP server is registered
When I look up LSP server "local/pyright"
Then the LSP lookup result should not be None
And the LSP lookup result name should be "local/pyright"
@lsp_reg_get
Scenario: Lookup a non-existent server returns None
When I look up LSP server "local/nonexistent"
Then the LSP lookup result should be None
@lsp_reg_get @error_handling
Scenario: Lookup with get_or_raise for missing server raises error
When I look up LSP server "local/missing" with get_or_raise
Then an LspServerNotFoundError should be raised for "local/missing"
# ---------------------------------------------------------------------------
# List with namespace filter
# ---------------------------------------------------------------------------
@lsp_reg_list
Scenario: List all registered servers
Given the following LSP servers are registered:
| name | language | command |
| local/pyright | python | pyright-langserver |
| local/tsserver | typescript | typescript-language-server |
| devops/clangd | c | clangd |
When I list all LSP servers
Then the LSP server list should contain 3 servers
@lsp_reg_list
Scenario: List servers filtered by namespace
Given the following LSP servers are registered:
| name | language | command |
| local/pyright | python | pyright-langserver |
| local/tsserver | typescript | typescript-language-server |
| devops/clangd | c | clangd |
When I list LSP servers with namespace "local"
Then the LSP server list should contain 2 servers
# ---------------------------------------------------------------------------
# List with language filter
# ---------------------------------------------------------------------------
@lsp_reg_list
Scenario: List servers filtered by language
Given the following LSP servers are registered:
| name | language | command |
| local/pyright | python | pyright-langserver |
| local/tsserver | typescript | typescript-language-server |
| devops/pylsp | python | pylsp |
When I list LSP servers with language "python"
Then the LSP server list should contain 2 servers
# ---------------------------------------------------------------------------
# Remove server
# ---------------------------------------------------------------------------
@lsp_reg_remove
Scenario: Remove a registered server
Given an LSP server config named "local/pyright" for language "python" with command "pyright-langserver"
And the LSP server is registered
When I remove LSP server "local/pyright"
Then the LSP removal result should be True
And the LSP registry should have 0 servers
@lsp_reg_remove
Scenario: Remove a non-existent server returns False
When I remove LSP server "local/nonexistent"
Then the LSP removal result should be False
# ---------------------------------------------------------------------------
# Runtime stub raises LspNotAvailableError
# ---------------------------------------------------------------------------
@lsp_runtime
Scenario: Runtime start_server raises LspNotAvailableError
Given a local-mode LSP runtime
When I call start_server on the runtime with name "local/pyright" and workspace "/tmp"
Then an LspNotAvailableError should be raised
And the LSP error message should mention "local mode"
@lsp_runtime
Scenario: Runtime stop_server raises LspNotAvailableError
Given a local-mode LSP runtime
When I call stop_server on the runtime with name "local/pyright"
Then an LspNotAvailableError should be raised
@lsp_runtime
Scenario: Runtime get_diagnostics raises LspNotAvailableError
Given a local-mode LSP runtime
When I call get_diagnostics on the runtime with name "local/pyright" and file "/tmp/test.py"
Then an LspNotAvailableError should be raised
@lsp_runtime
Scenario: Runtime get_completions raises LspNotAvailableError
Given a local-mode LSP runtime
When I call get_completions on the runtime with name "local/pyright" file "/tmp/test.py" line 1 column 1
Then an LspNotAvailableError should be raised
# ---------------------------------------------------------------------------
# Tool adapter generates tool specs from capabilities
# ---------------------------------------------------------------------------
@lsp_tool_adapter
Scenario: Tool adapter generates specs for each capability
Given an LSP server config named "local/pyright" for language "python" with command "pyright-langserver"
And the LSP server config has capabilities "diagnostics,completions"
When I generate tool specs from the adapter
Then the tool spec list should contain 2 specs
And the tool spec names should include "local/pyright/diagnostics"
And the tool spec names should include "local/pyright/completions"
@lsp_tool_adapter
Scenario: Tool adapter handler raises LspNotAvailableError in local mode
Given an LSP server config named "local/pyright" for language "python" with command "pyright-langserver"
And the LSP server config has capabilities "diagnostics"
When I generate tool specs from the adapter
And I invoke the first tool spec handler
Then an LspNotAvailableError should be raised
# ---------------------------------------------------------------------------
# Binding validation (valid/invalid references)
# ---------------------------------------------------------------------------
@lsp_binding
Scenario: Valid binding with registered server passes
Given an LSP server config named "local/pyright" for language "python" with command "pyright-langserver"
And the LSP server is registered
When I create a binding for node "code-editor" to server "local/pyright"
Then the binding should be valid
And the binding node_name should be "code-editor"
And the binding lsp_server_name should be "local/pyright"
@lsp_binding @error_handling
Scenario: Binding with non-namespaced server name is rejected
When I create a binding for node "code-editor" to server "pyright"
Then a ValidationError should be raised mentioning "namespaced"
@lsp_binding
Scenario: Binding auto_detect defaults to True
Given an LSP server config named "local/pyright" for language "python" with command "pyright-langserver"
And the LSP server is registered
When I create a binding for node "code-editor" to server "local/pyright"
Then the binding auto_detect should be True
# ---------------------------------------------------------------------------
# Model validation
# ---------------------------------------------------------------------------
@lsp_model_validation
Scenario: LspServerConfig rejects non-namespaced name
When I try to create an LSP server config with name "pyright" and command "pyright-langserver"
Then a ValidationError should be raised mentioning "namespaced"
@lsp_model_validation
Scenario: LspServerConfig normalizes language strings to lowercase
Given an LSP server config named "local/pyright" for language "Python" with command "pyright-langserver"
Then the LSP server config language "python" should be present
@lsp_model_validation
Scenario: LspServerConfig namespace property extracts prefix
Given an LSP server config named "local/pyright" for language "python" with command "pyright-langserver"
Then the LSP server config namespace should be "local"
And the LSP server config short_name should be "pyright"
# ---------------------------------------------------------------------------
# Error hierarchy
# ---------------------------------------------------------------------------
@lsp_errors
Scenario: LspError inherits from CleverAgentsError
Then LspError should be a subclass of CleverAgentsError
@lsp_errors
Scenario: LspNotAvailableError has default message
When I create an LspNotAvailableError with default message
Then the LSP error message should contain "not available in local mode"
@lsp_errors
Scenario: LspServerNotFoundError includes server name
When I create an LspServerNotFoundError for server "local/pyright"
Then the LSP error message should contain "local/pyright"
And the error server_name should be "local/pyright"
@lsp_errors @error_handling
Scenario: LspServerNotFoundError rejects empty server name
When I try to create an LspServerNotFoundError with empty name
Then a ValueError should be raised