tsl-devkit/lsp-server/test/test_provider/provider_surface_test.cppm

386 lines
24 KiB
C++

module;
export module lsp.test.provider.surface;
import std;
import lsp.test.framework;
import lsp.codec.facade;
import lsp.protocol;
import lsp.core.dispacther;
import lsp.manager.manager_hub;
import lsp.scheduler.async_executor;
import lsp.test.provider.fixtures;
import lsp.provider.cancel_request.cancel_request;
import lsp.provider.client.register_capability;
import lsp.provider.client.unregister_capability;
import lsp.provider.code_action.resolve;
import lsp.provider.code_lens.resolve;
import lsp.provider.completion_item.resolve;
import lsp.provider.document_link.resolve;
import lsp.provider.exit.exit;
import lsp.provider.initialize.initialize;
import lsp.provider.initialized.initialized;
import lsp.provider.inlay_hint.resolve;
import lsp.provider.shutdown.shutdown;
import lsp.provider.telemetry.event;
import lsp.provider.trace.set_trace;
import lsp.provider.call_hierarchy.incoming_calls;
import lsp.provider.call_hierarchy.outgoing_calls;
import lsp.provider.type_hierarchy.supertypes;
import lsp.provider.type_hierarchy.subtypes;
import lsp.provider.window.log_message;
import lsp.provider.window.show_document;
import lsp.provider.window.show_message;
import lsp.provider.window.show_message_request;
import lsp.provider.window.work_done_progress_create;
import lsp.provider.workspace.apply_edit;
import lsp.provider.workspace.code_lens_refresh;
import lsp.provider.workspace.configuration;
import lsp.provider.workspace.diagnostic;
import lsp.provider.workspace.diagnostic_refresh;
import lsp.provider.workspace.did_change_configuration;
import lsp.provider.workspace.did_change_watched_files;
import lsp.provider.workspace.did_change_workspace_folders;
import lsp.provider.workspace.did_create_files;
import lsp.provider.workspace.did_delete_files;
import lsp.provider.workspace.did_rename_files;
import lsp.provider.workspace.execute_command;
import lsp.provider.workspace.inlay_hint_refresh;
import lsp.provider.workspace.inline_value_refresh;
import lsp.provider.workspace.semantic_tokens_refresh;
import lsp.provider.workspace.symbol;
import lsp.provider.workspace.will_create_files;
import lsp.provider.workspace.will_delete_files;
import lsp.provider.workspace.will_rename_files;
import lsp.provider.workspace.workspace_folders;
import lsp.provider.workspace_symbol.resolve;
import lsp.provider.text_document.code_action;
import lsp.provider.text_document.code_lens;
import lsp.provider.text_document.color_presentation;
import lsp.provider.text_document.completion;
import lsp.provider.text_document.definition;
import lsp.provider.text_document.diagnostic;
import lsp.provider.text_document.did_change;
import lsp.provider.text_document.did_close;
import lsp.provider.text_document.did_open;
import lsp.provider.text_document.document_color;
import lsp.provider.text_document.document_highlight;
import lsp.provider.text_document.document_link;
import lsp.provider.text_document.document_symbol;
import lsp.provider.text_document.folding_range;
import lsp.provider.text_document.formatting;
import lsp.provider.text_document.hover;
import lsp.provider.text_document.implementation;
import lsp.provider.text_document.inlay_hint;
import lsp.provider.text_document.inline_value;
import lsp.provider.text_document.linked_editing_range;
import lsp.provider.text_document.moniker;
import lsp.provider.text_document.on_type_formatting;
import lsp.provider.text_document.prepare_call_hierarchy;
import lsp.provider.text_document.prepare_rename;
import lsp.provider.text_document.prepare_type_hierarchy;
import lsp.provider.text_document.publish_diagnostics;
import lsp.provider.text_document.range_formatting;
import lsp.provider.text_document.references;
import lsp.provider.text_document.rename;
import lsp.provider.text_document.selection_range;
import lsp.provider.text_document.semantic_tokens;
import lsp.provider.text_document.signature_help;
import lsp.provider.text_document.type_definition;
export namespace lsp::test::provider
{
class ProviderSurfaceTests
{
public:
static void Register(TestRunner& runner);
private:
static TestResult TestProviderMetadata();
static TestResult TestRequestProviderResponses();
static TestResult TestNotificationProviderHandlers();
};
}
namespace lsp::test::provider
{
namespace
{
namespace codec = lsp::codec;
namespace provider = lsp::provider;
struct ProviderEnv
{
scheduler::AsyncExecutor scheduler{ 1 };
manager::ManagerHub hub{};
core::ExecutionContext context;
ProviderEnv()
: context([](core::ServerLifecycleEvent) {}, scheduler, hub)
{
hub.Initialize();
}
};
template<typename Provider>
void CheckProviderMetadata(const std::string& expected_method,
const std::string& expected_name)
{
Provider provider;
assertEqual(expected_method, provider.GetMethod(),
"GetMethod mismatch for " + expected_name);
assertEqual(expected_name, provider.GetProviderName(),
"GetProviderName mismatch for " + expected_name);
}
template<typename Provider>
void CheckRequestResponse()
{
ProviderEnv env;
Provider provider;
protocol::RequestMessage request;
request.id = "probe";
request.method = provider.GetMethod();
request.params = std::nullopt;
auto json = provider.ProvideResponse(request, env.context);
assertTrue(!json.empty(), "ProvideResponse should return JSON for " + provider.GetProviderName());
auto parsed = codec::Deserialize<protocol::LSPAny>(json);
assertTrue(parsed.has_value(), "ProvideResponse should return valid JSON for " + provider.GetProviderName());
}
template<typename Provider>
void CheckNotificationHandler(const std::optional<protocol::LSPAny>& params)
{
ProviderEnv env;
Provider provider;
protocol::NotificationMessage notification;
notification.method = provider.GetMethod();
notification.params = params;
provider.HandleNotification(notification, env.context);
}
}
void ProviderSurfaceTests::Register(TestRunner& runner)
{
runner.addTest("provider metadata", TestProviderMetadata);
runner.addTest("provider request responses", TestRequestProviderResponses);
runner.addTest("provider notification handlers", TestNotificationProviderHandlers);
}
TestResult ProviderSurfaceTests::TestProviderMetadata()
{
TestResult result{ "", true, "ok" };
CheckProviderMetadata<provider::Initialize>("initialize", "Initialize");
CheckProviderMetadata<provider::Shutdown>("shutdown", "Shutdown");
CheckProviderMetadata<provider::completion_item::Resolve>("completionItem/resolve", "CompletionItemResolve");
CheckProviderMetadata<provider::text_document::Completion>("textDocument/completion", "TextDocumentCompletion");
CheckProviderMetadata<provider::text_document::Definition>("textDocument/definition", "TextDocumentDefinition");
CheckProviderMetadata<provider::text_document::Rename>("textDocument/rename", "TextDocumentRename");
CheckProviderMetadata<provider::text_document::References>("textDocument/references", "TextDocumentReferences");
CheckProviderMetadata<provider::text_document::SemanticTokensRange>("textDocument/semanticTokens/range",
"TextDocumentSemanticTokensRange");
CheckProviderMetadata<provider::text_document::SemanticTokensFull>("textDocument/semanticTokens/full",
"SemanticTokensFull");
CheckProviderMetadata<provider::text_document::SemanticTokensFullDelta>("textDocument/semanticTokens/full/delta",
"SemanticTokensFullDelta");
CheckProviderMetadata<provider::text_document::Hover>("textDocument/hover", "TextDocumentHover");
CheckProviderMetadata<provider::text_document::Formatting>("textDocument/formatting", "TextDocumentFormatting");
CheckProviderMetadata<provider::text_document::RangeFormatting>("textDocument/rangeFormatting",
"TextDocumentRangeFormatting");
CheckProviderMetadata<provider::text_document::OnTypeFormatting>("textDocument/onTypeFormatting",
"TextDocumentOnTypeFormatting");
CheckProviderMetadata<provider::text_document::DocumentSymbol>("textDocument/documentSymbol",
"TextDocumentDocumentSymbol");
CheckProviderMetadata<provider::text_document::DocumentLink>("textDocument/documentLink",
"TextDocumentDocumentLink");
CheckProviderMetadata<provider::text_document::DocumentHighlight>("textDocument/documentHighlight",
"TextDocumentDocumentHighlight");
CheckProviderMetadata<provider::text_document::DocumentColor>("textDocument/documentColor",
"TextDocumentDocumentColor");
CheckProviderMetadata<provider::text_document::ColorPresentation>("textDocument/colorPresentation",
"TextDocumentColorPresentation");
CheckProviderMetadata<provider::text_document::CodeLens>("textDocument/codeLens", "TextDocumentCodeLens");
CheckProviderMetadata<provider::text_document::CodeAction>("textDocument/codeAction", "TextDocumentCodeAction");
CheckProviderMetadata<provider::text_document::PrepareTypeHierarchy>("textDocument/prepareTypeHierarchy",
"TextDocumentPrepareTypeHierarchy");
CheckProviderMetadata<provider::text_document::PrepareRename>("textDocument/prepareRename",
"TextDocumentPrepareRename");
CheckProviderMetadata<provider::text_document::PrepareCallHierarchy>("textDocument/prepareCallHierarchy",
"TextDocumentPrepareCallHierarchy");
CheckProviderMetadata<provider::text_document::TypeDefinition>("textDocument/typeDefinition",
"TextDocumentTypeDefinition");
CheckProviderMetadata<provider::text_document::Implementation>("textDocument/implementation",
"TextDocumentImplementation");
CheckProviderMetadata<provider::text_document::SelectionRange>("textDocument/selectionRange",
"TextDocumentSelectionRange");
CheckProviderMetadata<provider::text_document::SignatureHelp>("textDocument/signatureHelp",
"TextDocumentSignatureHelp");
CheckProviderMetadata<provider::text_document::InlayHint>("textDocument/inlayHint", "TextDocumentInlayHint");
CheckProviderMetadata<provider::text_document::InlineValue>("textDocument/inlineValue",
"TextDocumentInlineValue");
CheckProviderMetadata<provider::text_document::LinkedEditingRange>("textDocument/linkedEditingRange",
"TextDocumentLinkedEditingRange");
CheckProviderMetadata<provider::text_document::Moniker>("textDocument/moniker", "TextDocumentMoniker");
CheckProviderMetadata<provider::text_document::Diagnostic>("textDocument/diagnostic",
"TextDocumentDiagnostic");
CheckProviderMetadata<provider::text_document::FoldingRange>("textDocument/foldingRange",
"TextDocumentFoldingRange");
CheckProviderMetadata<provider::code_action::Resolve>("codeAction/resolve", "CodeActionResolve");
CheckProviderMetadata<provider::code_lens::Resolve>("codeLens/resolve", "CodeLensResolve");
CheckProviderMetadata<provider::document_link::Resolve>("documentLink/resolve", "DocumentLinkResolve");
CheckProviderMetadata<provider::inlay_hint::Resolve>("inlayHint/resolve", "InlayHintResolve");
CheckProviderMetadata<provider::workspace_symbol::Resolve>("workspaceSymbol/resolve", "WorkspaceSymbResolve");
CheckProviderMetadata<provider::type_hierarchy::Supertypes>("typeHierarchy/supertypes", "TypeHierarchySupertypes");
CheckProviderMetadata<provider::type_hierarchy::Subtypes>("typeHierarchy/subtypes", "WorkspaceSubtypes");
CheckProviderMetadata<provider::call_hierarchy::IncomingCalls>("callHierarchy/incomingCalls",
"CallHierarchyIncomingCalls");
CheckProviderMetadata<provider::call_hierarchy::OutgoingCalls>("callHierarchy/outgoingCalls",
"CallHierarchyOutgoingCalls");
CheckProviderMetadata<provider::workspace::ApplyEdit>("workspace/applyEdit", "WorkspaceApplyEdit");
CheckProviderMetadata<provider::workspace::Configuration>("workspace/configuration", "WorkspaceConfiguration");
CheckProviderMetadata<provider::workspace::Diagnostic>("workspace/diagnostic", "WorkspaceDiagnostic");
CheckProviderMetadata<provider::workspace::DiagnosticRefresh>("workspace/diagnostic/refresh",
"WorkspaceDiagnosticRefresh");
CheckProviderMetadata<provider::workspace::ExecuteCommand>("workspace/executeCommand",
"WorkspaceExecuteCommand");
CheckProviderMetadata<provider::workspace::WorkspaceFolders>("workspace/workspaceFolders",
"WorkspaceWorkspaceFolders");
CheckProviderMetadata<provider::workspace::WillCreateFiles>("workspace/willCreateFiles", "WorkspaceWillCreateFiles");
CheckProviderMetadata<provider::workspace::WillDeleteFiles>("workspace/willDeleteFiles", "WorkspaceWillDeleteFiles");
CheckProviderMetadata<provider::workspace::WillRenameFiles>("workspace/willRenameFiles", "WorkspaceWillRenameFiles");
CheckProviderMetadata<provider::workspace::Symbol>("workspace/symbol", "WorkSpaceSymbol");
CheckProviderMetadata<provider::workspace::SemanticTokensRefresh>("workspace/semanticTokens/refresh",
"WorkspaceSemanticTokensRefresh");
CheckProviderMetadata<provider::workspace::InlineValueRefresh>("workspace/inlineValue/refresh",
"WorkspaceInlineValueRefresh");
CheckProviderMetadata<provider::workspace::InlayHintRefresh>("workspace/inlayHint/refresh",
"WorkspaceInlayHintRefresh");
CheckProviderMetadata<provider::workspace::CodeLensRefresh>("workspace/codeLens/refresh",
"WorkspaceCodeLensRefresh");
CheckProviderMetadata<provider::workspace::DidChangeConfiguration>("workspace/didChangeConfiguration",
"WorkspaceDidChangeConfiguration");
CheckProviderMetadata<provider::workspace::DidChangeWatchedFiles>("workspace/didChangeWatchedFiles",
"WorkspaceDidChangeWatchedFiles");
CheckProviderMetadata<provider::workspace::DidChangeWorkspaceFolders>("workspace/didChangeWorkspaceFolders",
"WorkspaceDidChangeWorkspaceFolders");
CheckProviderMetadata<provider::workspace::DidCreateFiles>("workspace/didCreateFiles", "WorkspaceDidCreateFiles");
CheckProviderMetadata<provider::workspace::DidDeleteFiles>("workspace/didDeleteFiles", "WorkspaceDidDeleteFiles");
CheckProviderMetadata<provider::workspace::DidRenameFiles>("workspace/didRenameFiles", "WorkspaceDidRenameFiles");
CheckProviderMetadata<provider::window::ShowMessageRequest>("window/showMessageRequest",
"WindowShowMessageRequest");
CheckProviderMetadata<provider::window::ShowDocument>("window/showDocument", "WindowShowDocument");
CheckProviderMetadata<provider::window::WorkDoneProgressCreate>("window/workDoneProgress/create",
"WindowWorkDoneProgressCreate");
CheckProviderMetadata<provider::client::RegisterCapability>("client/registerCapability",
"ClientRegisterCapability");
CheckProviderMetadata<provider::client::UnregisterCapability>("client/unregisterCapability",
"ClientUnregisterCapability");
CheckProviderMetadata<provider::Initialized>("initialized", "Initialized");
CheckProviderMetadata<provider::Exit>("exit", "Exit");
CheckProviderMetadata<provider::CancelRequest>("$/cancelRequest", "CancelRequest");
CheckProviderMetadata<provider::SetTrace>("$/setTrace", "SetTrace");
CheckProviderMetadata<provider::text_document::DidOpen>("textDocument/didOpen", "TextDocumentDidOpen");
CheckProviderMetadata<provider::text_document::DidChange>("textDocument/didChange", "TextDocumentDidChange");
CheckProviderMetadata<provider::text_document::DidClose>("textDocument/didClose", "TextDocumentDidClose");
CheckProviderMetadata<provider::text_document::PublishDiagnostics>("textDocument/publishDiagnostics",
"TextDocumentPublishDiagnostics");
CheckProviderMetadata<provider::window::ShowMessage>("window/showMessage", "WindowShowMessage");
CheckProviderMetadata<provider::window::LogMessage>("window/logMessage", "WindowLogMessage");
CheckProviderMetadata<provider::telemetry::Event>("telemetry/event", "TelemetryEvent");
return result;
}
TestResult ProviderSurfaceTests::TestRequestProviderResponses()
{
TestResult result{ "", true, "ok" };
CheckRequestResponse<provider::Shutdown>();
CheckRequestResponse<provider::completion_item::Resolve>();
CheckRequestResponse<provider::text_document::Completion>();
CheckRequestResponse<provider::text_document::Definition>();
CheckRequestResponse<provider::text_document::Rename>();
CheckRequestResponse<provider::text_document::References>();
CheckRequestResponse<provider::text_document::SemanticTokensRange>();
CheckRequestResponse<provider::text_document::SemanticTokensFull>();
CheckRequestResponse<provider::text_document::SemanticTokensFullDelta>();
CheckRequestResponse<provider::text_document::Hover>();
CheckRequestResponse<provider::text_document::Formatting>();
CheckRequestResponse<provider::text_document::RangeFormatting>();
CheckRequestResponse<provider::text_document::OnTypeFormatting>();
CheckRequestResponse<provider::text_document::DocumentSymbol>();
CheckRequestResponse<provider::text_document::DocumentLink>();
CheckRequestResponse<provider::text_document::DocumentHighlight>();
CheckRequestResponse<provider::text_document::DocumentColor>();
CheckRequestResponse<provider::text_document::ColorPresentation>();
CheckRequestResponse<provider::text_document::CodeLens>();
CheckRequestResponse<provider::text_document::CodeAction>();
CheckRequestResponse<provider::text_document::PrepareTypeHierarchy>();
CheckRequestResponse<provider::text_document::PrepareRename>();
CheckRequestResponse<provider::text_document::PrepareCallHierarchy>();
CheckRequestResponse<provider::text_document::TypeDefinition>();
CheckRequestResponse<provider::text_document::Implementation>();
CheckRequestResponse<provider::text_document::SelectionRange>();
CheckRequestResponse<provider::text_document::SignatureHelp>();
CheckRequestResponse<provider::text_document::InlayHint>();
CheckRequestResponse<provider::text_document::InlineValue>();
CheckRequestResponse<provider::text_document::LinkedEditingRange>();
CheckRequestResponse<provider::text_document::Moniker>();
CheckRequestResponse<provider::text_document::Diagnostic>();
CheckRequestResponse<provider::text_document::FoldingRange>();
CheckRequestResponse<provider::code_action::Resolve>();
CheckRequestResponse<provider::code_lens::Resolve>();
CheckRequestResponse<provider::document_link::Resolve>();
CheckRequestResponse<provider::inlay_hint::Resolve>();
CheckRequestResponse<provider::workspace_symbol::Resolve>();
CheckRequestResponse<provider::type_hierarchy::Supertypes>();
CheckRequestResponse<provider::type_hierarchy::Subtypes>();
CheckRequestResponse<provider::call_hierarchy::IncomingCalls>();
CheckRequestResponse<provider::call_hierarchy::OutgoingCalls>();
CheckRequestResponse<provider::workspace::ApplyEdit>();
CheckRequestResponse<provider::workspace::Configuration>();
CheckRequestResponse<provider::workspace::Diagnostic>();
CheckRequestResponse<provider::workspace::DiagnosticRefresh>();
CheckRequestResponse<provider::workspace::ExecuteCommand>();
CheckRequestResponse<provider::workspace::WorkspaceFolders>();
CheckRequestResponse<provider::workspace::WillCreateFiles>();
CheckRequestResponse<provider::workspace::WillDeleteFiles>();
CheckRequestResponse<provider::workspace::WillRenameFiles>();
CheckRequestResponse<provider::workspace::Symbol>();
CheckRequestResponse<provider::workspace::SemanticTokensRefresh>();
CheckRequestResponse<provider::workspace::InlineValueRefresh>();
CheckRequestResponse<provider::workspace::InlayHintRefresh>();
CheckRequestResponse<provider::workspace::CodeLensRefresh>();
CheckRequestResponse<provider::window::ShowMessageRequest>();
CheckRequestResponse<provider::window::ShowDocument>();
CheckRequestResponse<provider::window::WorkDoneProgressCreate>();
CheckRequestResponse<provider::client::RegisterCapability>();
CheckRequestResponse<provider::client::UnregisterCapability>();
return result;
}
TestResult ProviderSurfaceTests::TestNotificationProviderHandlers()
{
TestResult result{ "", true, "ok" };
CheckNotificationHandler<provider::Initialized>(std::nullopt);
CheckNotificationHandler<provider::Exit>(std::nullopt);
CheckNotificationHandler<provider::text_document::PublishDiagnostics>(std::nullopt);
CheckNotificationHandler<provider::window::ShowMessage>(std::nullopt);
CheckNotificationHandler<provider::window::LogMessage>(std::nullopt);
CheckNotificationHandler<provider::telemetry::Event>(std::nullopt);
CheckNotificationHandler<provider::workspace::DidChangeConfiguration>(std::nullopt);
CheckNotificationHandler<provider::workspace::DidChangeWatchedFiles>(std::nullopt);
CheckNotificationHandler<provider::workspace::DidChangeWorkspaceFolders>(std::nullopt);
CheckNotificationHandler<provider::workspace::DidCreateFiles>(std::nullopt);
CheckNotificationHandler<provider::workspace::DidDeleteFiles>(std::nullopt);
CheckNotificationHandler<provider::workspace::DidRenameFiles>(std::nullopt);
return result;
}
}