forked from cleveragents/cleveragents-core
239 lines
11 KiB
Gherkin
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
|