public async Task ShouldRouteToCorrect_Notification()
        {
            var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"));

            textDocumentSyncHandler.Handle(Arg.Any <DidSaveTextDocumentParams>()).Returns(Task.CompletedTask);

            var collection = new HandlerCollection {
                textDocumentSyncHandler
            };
            var handlerMatcherCollection = new HandlerMatcherCollection {
                new TextDocumentMatcher(_testLoggerFactory.CreateLogger <TextDocumentMatcher>(), collection.TextDocumentSyncHandlers)
            };
            var mediator = new LspRequestRouter(collection, _testLoggerFactory, handlerMatcherCollection, new Serializer());

            var @params = new DidSaveTextDocumentParams()
            {
                TextDocument = new TextDocumentIdentifier(new Uri("file:///c:/test/123.cs"))
            };

            var request = new Notification(DocumentNames.DidSave, JObject.Parse(JsonConvert.SerializeObject(@params, new Serializer(ClientVersion.Lsp3).Settings)));

            await mediator.RouteNotification(mediator.GetDescriptor(request), request);

            await textDocumentSyncHandler.Received(1).Handle(Arg.Any <DidSaveTextDocumentParams>());
        }
        public async Task TriggersStartedTask()
        {
            var startedDelegate = Substitute.For <StartedDelegate>();

            startedDelegate(Arg.Any <InitializeResult>()).Returns(Task.CompletedTask);
            var process = new NamedPipeServerProcess(Guid.NewGuid().ToString("N"), LoggerFactory);
            await process.Start();

            var client = new LanguageClient(LoggerFactory, process);
            var cts    = new CancellationTokenSource();

            cts.CancelAfter(TimeSpan.FromSeconds(15));
            var serverStart = LanguageServer.From(x => x
                                                  .OnStarted(startedDelegate)
                                                  .OnStarted(startedDelegate)
                                                  .OnStarted(startedDelegate)
                                                  .OnStarted(startedDelegate)
                                                  .WithInput(process.ClientOutputStream)
                                                  .WithOutput(process.ClientInputStream)
                                                  .ConfigureLogging(z => z.Services.AddSingleton(LoggerFactory))
                                                  .AddHandlers(TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp"))
                                                  , cts.Token);

            await Task.WhenAll(
                client.Initialize(
                    Directory.GetCurrentDirectory(),
                    new object(),
                    cts.Token),
                serverStart
                );

            using var server = await serverStart;

            _ = startedDelegate.Received(4)(Arg.Any <InitializeResult>());
        }
        public void GH162_TextDocumentSync_Should_Work_With_WillSave_Or_WillSaveWaitUntil()
        {
            var textDocumentSyncHandler =
                TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp");
            var willSaveTextDocumentHandler          = Substitute.For <IWillSaveTextDocumentHandler>();
            var willSaveWaitUntilTextDocumentHandler = Substitute.For <IWillSaveWaitUntilTextDocumentHandler>();
            var didSaveTextDocumentHandler           = Substitute.For <IDidSaveTextDocumentHandler>();

            var collection =
                new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), new ServiceCollection().BuildServiceProvider())
            {
                textDocumentSyncHandler, willSaveTextDocumentHandler, willSaveWaitUntilTextDocumentHandler,
                didSaveTextDocumentHandler
            };
            var provider     = new ClientCapabilityProvider(collection, true);
            var capabilities = new ClientCapabilities {
                TextDocument = new TextDocumentClientCapabilities {
                    Synchronization = new SynchronizationCapability {
                        DidSave             = true,
                        DynamicRegistration = false,
                        WillSave            = true,
                        WillSaveWaitUntil   = true
                    },
                }
            };

            provider.HasStaticHandler(capabilities.TextDocument.Synchronization).Should().BeTrue();
        }
        public void Should_Handle_Mixed_Capabilities()
        {
            var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"));

            var codeActionHandler     = Substitute.For <ICodeActionHandler>();
            var definitionHandler     = Substitute.For <IDefinitionHandler>();
            var typeDefinitionHandler = Substitute.For <ITypeDefinitionHandler>();

            var collection = new HandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue)
            {
                textDocumentSyncHandler, codeActionHandler, definitionHandler, typeDefinitionHandler
            };
            var provider     = new ClientCapabilityProvider(collection);
            var capabilities = new ClientCapabilities()
            {
                TextDocument = new TextDocumentClientCapabilities()
                {
                    CodeAction = new Supports <CodeActionCapability>(true, new CodeActionCapability()
                    {
                        DynamicRegistration = false,
                    }),
                    TypeDefinition = new Supports <TypeDefinitionCapability>(true, new TypeDefinitionCapability()
                    {
                        DynamicRegistration = true,
                    })
                }
            };

            provider.GetStaticOptions(capabilities.TextDocument.CodeAction).Get <ICodeActionOptions, CodeActionOptions>(CodeActionOptions.Of).Should().NotBeNull();
            provider.HasStaticHandler(capabilities.TextDocument.Definition).Should().BeTrue();
            provider.HasStaticHandler(capabilities.TextDocument.TypeDefinition).Should().BeFalse();
        }
        public async Task ShouldRouteToCorrect_Notification()
        {
            var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp");

            textDocumentSyncHandler.Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>()).Returns(Unit.Value);

            var collection = new HandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers())
            {
                textDocumentSyncHandler
            };

            AutoSubstitute.Provide <IHandlerCollection>(collection);
            AutoSubstitute.Provide <IEnumerable <ILspHandlerDescriptor> >(collection);
            var mediator = AutoSubstitute.Resolve <LspRequestRouter>();

            var @params = new DidSaveTextDocumentParams()
            {
                TextDocument = new TextDocumentIdentifier(new Uri("file:///c:/test/123.cs"))
            };

            var request = new Notification(DocumentNames.DidSave, JObject.Parse(JsonConvert.SerializeObject(@params, new Serializer(ClientVersion.Lsp3).Settings)));

            await mediator.RouteNotification(mediator.GetDescriptor(request), request, CancellationToken.None);

            await textDocumentSyncHandler.Received(1).Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>());
        }
예제 #6
0
        public async Task ShouldRouteToCorrect_Notification_WithManyHandlers()
        {
            var textDocumentSyncHandler  = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"));
            var textDocumentSyncHandler2 = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cake"));

            textDocumentSyncHandler.Handle(Arg.Any <DidSaveTextDocumentParams>()).Returns(Task.CompletedTask);
            textDocumentSyncHandler2.Handle(Arg.Any <DidSaveTextDocumentParams>()).Returns(Task.CompletedTask);

            var collection = new HandlerCollection {
                textDocumentSyncHandler, textDocumentSyncHandler2
            };
            var mediator = new LspRequestRouter(collection, _testLoggerFactory);

            var @params = new DidSaveTextDocumentParams()
            {
                TextDocument = new TextDocumentIdentifier(new Uri("file:///c:/test/123.cake"))
            };

            var request = new Notification("textDocument/didSave", JObject.Parse(JsonConvert.SerializeObject(@params)));

            await mediator.RouteNotification(mediator.GetDescriptor(request), request);

            await textDocumentSyncHandler.Received(0).Handle(Arg.Any <DidSaveTextDocumentParams>());

            await textDocumentSyncHandler2.Received(1).Handle(Arg.Any <DidSaveTextDocumentParams>());
        }
예제 #7
0
        public async Task ShouldRouteToCorrect_Request()
        {
            var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"));

            textDocumentSyncHandler.Handle(Arg.Any <DidSaveTextDocumentParams>()).Returns(Task.CompletedTask);

            var codeActionHandler = Substitute.For <ICodeActionHandler>();

            codeActionHandler.GetRegistrationOptions().Returns(new TextDocumentRegistrationOptions()
            {
                DocumentSelector = DocumentSelector.ForPattern("**/*.cs")
            });
            codeActionHandler
            .Handle(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>())
            .Returns(new CommandContainer());

            var collection = new HandlerCollection {
                textDocumentSyncHandler, codeActionHandler
            };
            var mediator = new LspRequestRouter(collection, _testLoggerFactory);

            var id      = Guid.NewGuid().ToString();
            var @params = new DidSaveTextDocumentParams()
            {
                TextDocument = new TextDocumentIdentifier(new Uri("file:///c:/test/123.cs"))
            };

            var request = new Request(id, "textDocument/codeAction", JObject.Parse(JsonConvert.SerializeObject(@params)));

            await mediator.RouteRequest(mediator.GetDescriptor(request), request);

            await codeActionHandler.Received(1).Handle(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>());
        }
예제 #8
0
        public void GH162_TextDocumentSync_Should_Work_With_WillSave_Or_WillSaveWaitUntil()
        {
            var textDocumentSyncHandler =
                TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp");
            var willSaveTextDocumentHandler          = Substitute.For <IWillSaveTextDocumentHandler>();
            var willSaveWaitUntilTextDocumentHandler = Substitute.For <IWillSaveWaitUntilTextDocumentHandler>();
            var didSaveTextDocumentHandler           = Substitute.For <IDidSaveTextDocumentHandler>();

            var collection =
                new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), Substitute.For <IResolverContext>(),
                                            new LspHandlerTypeDescriptorProvider(new [] { typeof(FoundationTests).Assembly, typeof(LanguageServer).Assembly, typeof(LanguageClient).Assembly, typeof(IRegistrationManager).Assembly, typeof(LspRequestRouter).Assembly }))
            {
                textDocumentSyncHandler, willSaveTextDocumentHandler, willSaveWaitUntilTextDocumentHandler,
                didSaveTextDocumentHandler
            };
            var provider     = new ClientCapabilityProvider(collection, true);
            var capabilities = new ClientCapabilities {
                TextDocument = new TextDocumentClientCapabilities {
                    Synchronization = new SynchronizationCapability {
                        DidSave             = true,
                        DynamicRegistration = false,
                        WillSave            = true,
                        WillSaveWaitUntil   = true
                    },
                }
            };

            provider.HasStaticHandler(capabilities.TextDocument.Synchronization).Should().BeTrue();
        }
예제 #9
0
        public void GH162_TextDocumentSync_Should_Work_Without_WillSave_Or_WillSaveWaitUntil()
        {
            var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp");

            var collection = new HandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers())
            {
                textDocumentSyncHandler
            };
            var provider     = new ClientCapabilityProvider(collection);
            var capabilities = new ClientCapabilities()
            {
                TextDocument = new TextDocumentClientCapabilities()
                {
                    Synchronization = new SynchronizationCapability()
                    {
                        DidSave             = true,
                        DynamicRegistration = false,
                        WillSave            = true,
                        WillSaveWaitUntil   = true
                    },
                }
            };

            provider.HasStaticHandler(capabilities.TextDocument.Synchronization).Should().BeTrue();
        }
        public async Task ShouldRouteToCorrect_Request_WithManyHandlers()
        {
            var textDocumentSyncHandler  = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp");
            var textDocumentSyncHandler2 = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cake"), "csharp");

            textDocumentSyncHandler.Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>()).Returns(Unit.Value);
            textDocumentSyncHandler2.Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>()).Returns(Unit.Value);

            var codeActionHandler = Substitute.For <ICodeActionHandler>();

            codeActionHandler.GetRegistrationOptions().Returns(new CodeActionRegistrationOptions()
            {
                DocumentSelector = DocumentSelector.ForPattern("**/*.cs")
            });
            codeActionHandler
            .Handle(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>())
            .Returns(new CommandOrCodeActionContainer());

            var registry           = new TestLanguageServerRegistry();
            var codeActionDelegate = Substitute.For <Func <CodeActionParams, CancellationToken, Task <CommandOrCodeActionContainer> > >();

            codeActionDelegate.Invoke(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>())
            .Returns(new CommandOrCodeActionContainer());
            registry.OnCodeAction(
                codeActionDelegate,
                new CodeActionRegistrationOptions()
            {
                DocumentSelector = DocumentSelector.ForPattern("**/*.cake")
            }
                );

            var textDocumentIdentifiers = new TextDocumentIdentifiers();

            AutoSubstitute.Provide(textDocumentIdentifiers);
            var handlerCollection = new HandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, textDocumentIdentifiers)
            {
                textDocumentSyncHandler, textDocumentSyncHandler2, codeActionHandler
            };

            handlerCollection.Add(registry.Handlers);
            AutoSubstitute.Provide <IHandlerCollection>(handlerCollection);
            AutoSubstitute.Provide <IEnumerable <ILspHandlerDescriptor> >(handlerCollection);
            var mediator = AutoSubstitute.Resolve <LspRequestRouter>();

            var id      = Guid.NewGuid().ToString();
            var @params = new CodeActionParams()
            {
                TextDocument = new TextDocumentIdentifier(new Uri("file:///c:/test/123.cake"))
            };

            var request = new Request(id, DocumentNames.CodeAction, JObject.Parse(JsonConvert.SerializeObject(@params, new Serializer(ClientVersion.Lsp3).Settings)));

            await mediator.RouteRequest(mediator.GetDescriptor(request), request, CancellationToken.None);

            await codeActionHandler.Received(0).Handle(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>());

            await codeActionDelegate.Received(1).Invoke(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>());
        }
        public async Task ShouldRouteToCorrect_Request_WithManyHandlers_CodeLensHandler()
        {
            var textDocumentSyncHandler =
                TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp");
            var textDocumentSyncHandler2 =
                TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cake"), "csharp");

            textDocumentSyncHandler.Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>())
            .Returns(Unit.Value);
            textDocumentSyncHandler2.Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>())
            .Returns(Unit.Value);

            var codeActionHandler = Substitute.For <ICodeLensHandler>();

            codeActionHandler.GetRegistrationOptions().Returns(new CodeLensRegistrationOptions {
                DocumentSelector = DocumentSelector.ForPattern("**/*.cs")
            });
            codeActionHandler
            .Handle(Arg.Any <CodeLensParams>(), Arg.Any <CancellationToken>())
            .Returns(new CodeLensContainer());

            var codeActionHandler2 = Substitute.For <ICodeLensHandler>();

            codeActionHandler2.GetRegistrationOptions().Returns(new CodeLensRegistrationOptions {
                DocumentSelector = DocumentSelector.ForPattern("**/*.cake")
            });
            codeActionHandler2
            .Handle(Arg.Any <CodeLensParams>(), Arg.Any <CancellationToken>())
            .Returns(new CodeLensContainer());

            var tdi        = new TextDocumentIdentifiers();
            var collection =
                new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, tdi, new ServiceCollection().BuildServiceProvider())
            {
                textDocumentSyncHandler, textDocumentSyncHandler2, codeActionHandler, codeActionHandler2
            };

            AutoSubstitute.Provide <IHandlerCollection>(collection);
            AutoSubstitute.Provide <IEnumerable <ILspHandlerDescriptor> >(collection);
            AutoSubstitute.Provide <IHandlerMatcher>(new TextDocumentMatcher(LoggerFactory.CreateLogger <TextDocumentMatcher>(), tdi));
            var mediator = AutoSubstitute.Resolve <LspRequestRouter>();

            var id      = Guid.NewGuid().ToString();
            var @params = new CodeLensParams {
                TextDocument = new TextDocumentIdentifier(new Uri("file:///c:/test/123.cs"))
            };

            var request = new Request(
                id, TextDocumentNames.CodeLens,
                JObject.Parse(JsonConvert.SerializeObject(@params, new Serializer(ClientVersion.Lsp3).Settings))
                );

            await mediator.RouteRequest(mediator.GetDescriptors(request), request, CancellationToken.None);

            await codeActionHandler2.Received(0).Handle(Arg.Any <CodeLensParams>(), Arg.Any <CancellationToken>());

            await codeActionHandler.Received(1).Handle(Arg.Any <CodeLensParams>(), Arg.Any <CancellationToken>());
        }
        public void Should_Contain_AllDefinedTextDocumentSyncMethods(string key, int count)
        {
            var handler = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers());
            var sub     = (IJsonRpcHandler)TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.something"), "csharp");

            handler.Add(sub);
            handler._handlers.Should().Contain(x => x.Method == key);
            handler._handlers.Count.Should().Be(count);
        }
예제 #13
0
        public void Should_Contain_AllDefinedTextDocumentSyncMethods(string key, int count)
        {
            var handler = new HandlerCollection();
            var sub     = (IJsonRpcHandler)TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.something"));

            handler.Add(sub);
            handler._handlers.Should().Contain(x => x.Method == key);
            handler._handlers.Count.Should().Be(count);
        }
        public void Should_Contain_AllDefinedTextDocumentSyncMethods(string key, int count)
        {
            var handler = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), Substitute.For <IResolverContext>(),
                                                      new LspHandlerTypeDescriptorProvider(new [] { typeof(FoundationTests).Assembly, typeof(LanguageServer).Assembly, typeof(LanguageClient).Assembly, typeof(IRegistrationManager).Assembly, typeof(LspRequestRouter).Assembly }));
            var sub = (IJsonRpcHandler)TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.something"), "csharp");

            handler.Add(sub);
            handler.Should().Contain(x => x.Method == key);
            handler.Should().HaveCount(count);
        }
예제 #15
0
        public void Should_DisallowUnsupportedCapabilities(IJsonRpcHandler handler, object instance)
        {
            var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"));

            var collection = new HandlerCollection {
                textDocumentSyncHandler, handler
            };
            var provider = new ClientCapabilityProvider(collection);

            HasHandler(provider, instance).Should().BeFalse();
        }
예제 #16
0
        public void Should_Contain_AllDefinedMethods_ForDifferentKeys(string key, int count)
        {
            var handler = new HandlerCollection();
            var sub     = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"));

            var sub2 = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cake"));

            handler.Add(sub);
            handler.Add(sub2);
            handler._handlers.Should().Contain(x => x.Method == key);
            handler._handlers.Count.Should().Be(count);
        }
        public void Should_DisallowDynamicSupportedCapabilities(IJsonRpcHandler handler, object instance)
        {
            var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp");

            var collection = new HandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers())
            {
                textDocumentSyncHandler, handler
            };
            var provider = new ClientCapabilityProvider(collection, true);

            HasHandler(provider, instance).Should().BeFalse();
        }
        public void Should_Contain_AllDefinedMethods_ForDifferentKeys(string key, int count)
        {
            var handler = new HandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers());
            var sub     = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp");

            var sub2 = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cake"), "csharp");

            handler.Add(sub);
            handler.Add(sub2);
            handler._handlers.Should().Contain(x => x.Method == key);
            handler._handlers.Count.Should().Be(count);
        }
        public void Should_AllowNullSupportedCapabilities(IJsonRpcHandler handler, object instance)
        {
            var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"));

            var collection = new HandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue)
            {
                textDocumentSyncHandler, handler
            };
            var provider = new ClientCapabilityProvider(collection);

            HasHandler(provider, instance).Should().BeTrue();
        }
예제 #20
0
        public async Task ShouldRouteToCorrect_Notification_WithManyHandlers()
        {
            var textDocumentSyncHandler =
                TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp");
            var textDocumentSyncHandler2 =
                TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cake"), "csharp");

            textDocumentSyncHandler.Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>())
            .Returns(Unit.Value);
            textDocumentSyncHandler2.Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>())
            .Returns(Unit.Value);

            var textDocumentIdentifiers = new TextDocumentIdentifiers();

            AutoSubstitute.Provide(textDocumentIdentifiers);
            var collection =
                new SharedHandlerCollection(
                    SupportedCapabilitiesFixture.AlwaysTrue, textDocumentIdentifiers, Substitute.For <IResolverContext>(),
                    new LspHandlerTypeDescriptorProvider(
                        new[] {
                typeof(FoundationTests).Assembly, typeof(LanguageServer).Assembly, typeof(LanguageClient).Assembly, typeof(IRegistrationManager).Assembly,
                typeof(LspRequestRouter).Assembly
            }
                        )
                    )
            {
                textDocumentSyncHandler, textDocumentSyncHandler2
            };

            collection.Initialize();
            AutoSubstitute.Provide <IHandlerCollection>(collection);
            AutoSubstitute.Provide <IEnumerable <ILspHandlerDescriptor> >(collection);
            AutoSubstitute.Provide <IHandlerMatcher>(new TextDocumentMatcher(LoggerFactory.CreateLogger <TextDocumentMatcher>(), textDocumentIdentifiers));
            var mediator = AutoSubstitute.Resolve <LspRequestRouter>();

            var @params = new DidSaveTextDocumentParams {
                TextDocument = new TextDocumentIdentifier(new Uri("file:///c:/test/123.cake"))
            };

            var request = new Notification(
                TextDocumentNames.DidSave,
                JObject.Parse(JsonConvert.SerializeObject(@params, new LspSerializer(ClientVersion.Lsp3).Settings))
                );

            await mediator.RouteNotification(mediator.GetDescriptors(request), request, CancellationToken.None);

            await textDocumentSyncHandler.Received(0)
            .Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>());

            await textDocumentSyncHandler2.Received(1)
            .Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>());
        }
예제 #21
0
        public async Task RequestsCancellation()
        {
            var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp");

            textDocumentSyncHandler.Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>()).Returns(Unit.Value);

            var codeActionHandler = Substitute.For <ICodeActionHandler>();

            codeActionHandler.GetRegistrationOptions().Returns(new CodeActionRegistrationOptions()
            {
                DocumentSelector = DocumentSelector.ForPattern("**/*.cs")
            });
            codeActionHandler
            .Handle(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>())
            .Returns(async(c) =>
            {
                await Task.Delay(1000, c.Arg <CancellationToken>());
                throw new XunitException("Task was not cancelled in time!");
                return(new CommandOrCodeActionContainer());
            });

            var collection = new HandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers())
            {
                textDocumentSyncHandler, codeActionHandler
            };

            AutoSubstitute.Provide <IHandlerCollection>(collection);
            AutoSubstitute.Provide <IEnumerable <ILspHandlerDescriptor> >(collection);
            var mediator = AutoSubstitute.Resolve <LspRequestRouter>();

            var id      = Guid.NewGuid().ToString();
            var @params = new CodeActionParams()
            {
                TextDocument = new TextDocumentIdentifier(new Uri("file:///c:/test/123.cs")),
                Range        = new Range(new Position(1, 1), new Position(2, 2)),
                Context      = new CodeActionContext()
                {
                    Diagnostics = new Container <Diagnostic>()
                }
            };

            var request = new Request(id, "textDocument/codeAction", JObject.Parse(JsonConvert.SerializeObject(@params, new Serializer(ClientVersion.Lsp3).Settings)));

            var response = ((IRequestRouter <ILspHandlerDescriptor>)mediator).RouteRequest(request, CancellationToken.None);

            mediator.CancelRequest(id);
            var result = await response;

            result.IsError.Should().BeTrue();
            result.Error.Should().BeEquivalentTo(new RequestCancelled());
        }
        public async Task ShouldRouteToCorrect_Request_WithManyHandlers_CodeLensHandler()
        {
            var textDocumentSyncHandler  = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"));
            var textDocumentSyncHandler2 = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cake"));

            textDocumentSyncHandler.Handle(Arg.Any <DidSaveTextDocumentParams>()).Returns(Task.CompletedTask);
            textDocumentSyncHandler2.Handle(Arg.Any <DidSaveTextDocumentParams>()).Returns(Task.CompletedTask);

            var codeActionHandler = Substitute.For <ICodeLensHandler>();

            codeActionHandler.GetRegistrationOptions().Returns(new CodeLensRegistrationOptions()
            {
                DocumentSelector = DocumentSelector.ForPattern("**/*.cs")
            });
            codeActionHandler
            .Handle(Arg.Any <CodeLensParams>(), Arg.Any <CancellationToken>())
            .Returns(new CodeLensContainer());

            var codeActionHandler2 = Substitute.For <ICodeLensHandler>();

            codeActionHandler2.GetRegistrationOptions().Returns(new CodeLensRegistrationOptions()
            {
                DocumentSelector = DocumentSelector.ForPattern("**/*.cake")
            });
            codeActionHandler2
            .Handle(Arg.Any <CodeLensParams>(), Arg.Any <CancellationToken>())
            .Returns(new CodeLensContainer());

            var collection = new HandlerCollection {
                textDocumentSyncHandler, textDocumentSyncHandler2, codeActionHandler, codeActionHandler2
            };
            var handlerMatcherCollection = new HandlerMatcherCollection {
                new TextDocumentMatcher(_testLoggerFactory.CreateLogger <TextDocumentMatcher>(), collection.TextDocumentSyncHandlers)
            };
            var mediator = new LspRequestRouter(collection, _testLoggerFactory, handlerMatcherCollection, new Serializer());

            var id      = Guid.NewGuid().ToString();
            var @params = new CodeLensParams()
            {
                TextDocument = new TextDocumentIdentifier(new Uri("file:///c:/test/123.cs"))
            };

            var request = new Request(id, DocumentNames.CodeLens, JObject.Parse(JsonConvert.SerializeObject(@params, new Serializer(ClientVersion.Lsp3).Settings)));

            await mediator.RouteRequest(mediator.GetDescriptor(request), request);

            await codeActionHandler2.Received(0).Handle(Arg.Any <CodeLensParams>(), Arg.Any <CancellationToken>());

            await codeActionHandler.Received(1).Handle(Arg.Any <CodeLensParams>(), Arg.Any <CancellationToken>());
        }
        public async Task ShouldRouteToCorrect_Request()
        {
            var textDocumentSyncHandler =
                TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp");

            textDocumentSyncHandler.Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>())
            .Returns(Unit.Value);

            var codeActionHandler = Substitute.For <ICodeActionHandler>();

            codeActionHandler.GetRegistrationOptions().Returns(new CodeActionRegistrationOptions {
                DocumentSelector = DocumentSelector.ForPattern("**/*.cs")
            });
            codeActionHandler
            .Handle(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>())
            .Returns(new CommandOrCodeActionContainer());

            var collection =
                new SharedHandlerCollection(
                    SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), Substitute.For <IResolverContext>(),
                    new LspHandlerTypeDescriptorProvider(
                        new[] {
                typeof(FoundationTests).Assembly, typeof(LanguageServer).Assembly, typeof(LanguageClient).Assembly, typeof(IRegistrationManager).Assembly,
                typeof(LspRequestRouter).Assembly
            }
                        )
                    )
            {
                textDocumentSyncHandler, codeActionHandler
            };

            AutoSubstitute.Provide <IHandlerCollection>(collection);
            AutoSubstitute.Provide <IEnumerable <ILspHandlerDescriptor> >(collection);
            var mediator = AutoSubstitute.Resolve <LspRequestRouter>();

            var id      = Guid.NewGuid().ToString();
            var @params = new DidSaveTextDocumentParams {
                TextDocument = new TextDocumentIdentifier(new Uri("file:///c:/test/123.cs"))
            };

            var request = new Request(
                id, TextDocumentNames.CodeAction,
                JObject.Parse(JsonConvert.SerializeObject(@params, new Serializer(ClientVersion.Lsp3).Settings))
                );

            await mediator.RouteRequest(mediator.GetDescriptors(request), request, CancellationToken.None);

            await codeActionHandler.Received(1).Handle(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>());
        }
예제 #24
0
        public void Should_AllowNullSupportedCapabilities(IJsonRpcHandler handler, object instance)
        {
            var textDocumentSyncHandler =
                TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp");

            var collection =
                new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), Substitute.For <IResolverContext>(),
                                            new LspHandlerTypeDescriptorProvider(new [] { typeof(FoundationTests).Assembly, typeof(LanguageServer).Assembly, typeof(LanguageClient).Assembly, typeof(IRegistrationManager).Assembly, typeof(LspRequestRouter).Assembly }))
            {
                textDocumentSyncHandler, handler
            };
            var provider = new ClientCapabilityProvider(collection, true);

            HasHandler(provider, instance).Should().BeTrue();
        }
예제 #25
0
        public async Task RequestsCancellation()
        {
            var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"));

            textDocumentSyncHandler.Handle(Arg.Any <DidSaveTextDocumentParams>()).Returns(Task.CompletedTask);

            var codeActionHandler = Substitute.For <ICodeActionHandler>();

            codeActionHandler.GetRegistrationOptions().Returns(new TextDocumentRegistrationOptions()
            {
                DocumentSelector = DocumentSelector.ForPattern("**/*.cs")
            });
            codeActionHandler
            .Handle(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>())
            .Returns(async(c) => {
                await Task.Delay(1000, c.Arg <CancellationToken>());
                throw new XunitException("Task was not cancelled in time!");
                return(new CommandContainer());
            });

            var collection = new HandlerCollection {
                textDocumentSyncHandler, codeActionHandler
            };
            var mediator = new LspRequestRouter(collection, _testLoggerFactory);

            var id      = Guid.NewGuid().ToString();
            var @params = new CodeActionParams()
            {
                TextDocument = new TextDocumentIdentifier(new Uri("file:///c:/test/123.cs")),
                Range        = new Range(new Position(1, 1), new Position(2, 2)),
                Context      = new CodeActionContext()
                {
                    Diagnostics = new Container <Diagnostic>()
                }
            };

            var request = new Request(id, "textDocument/codeAction", JObject.Parse(JsonConvert.SerializeObject(@params)));

            var response = ((IRequestRouter)mediator).RouteRequest(request);

            mediator.CancelRequest(id);
            var result = await response;

            result.IsError.Should().BeTrue();
            result.Error.ShouldBeEquivalentTo(new RequestCancelled());
        }
예제 #26
0
        public async Task GH141_CrashesWithEmptyInitializeParams()
        {
            var process = new NamedPipeServerProcess(Guid.NewGuid().ToString("N"), LoggerFactory);
            await process.Start();

            var server = LanguageServer.PreInit(x => x
                                                .WithInput(process.ClientOutputStream)
                                                .WithOutput(process.ClientInputStream)
                                                .ConfigureLogging(z => z.Services.AddSingleton(LoggerFactory))
                                                .AddHandlers(TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp"))
                                                ) as IRequestHandler <InitializeParams, InitializeResult>;

            var handler = server as IRequestHandler <InitializeParams, InitializeResult>;

            Func <Task> a = async() => await handler.Handle(new InitializeParams()
            {
            }, CancellationToken.None);

            a.Should().NotThrow();
        }
        public async Task ShouldRouteToCorrect_Request()
        {
            var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"));

            textDocumentSyncHandler.Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>()).Returns(Unit.Value);

            var codeActionHandler = Substitute.For <ICodeActionHandler>();

            codeActionHandler.GetRegistrationOptions().Returns(new TextDocumentRegistrationOptions()
            {
                DocumentSelector = DocumentSelector.ForPattern("**/*.cs")
            });
            codeActionHandler
            .Handle(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>())
            .Returns(new CommandOrCodeActionContainer());

            var collection = new HandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue)
            {
                textDocumentSyncHandler, codeActionHandler
            };

            AutoSubstitute.Provide <IHandlerCollection>(collection);
            var mediator = AutoSubstitute.Resolve <LspRequestRouter>();

            var id      = Guid.NewGuid().ToString();
            var @params = new DidSaveTextDocumentParams()
            {
                TextDocument = new TextDocumentIdentifier(new Uri("file:///c:/test/123.cs"))
            };

            var request = new Request(id, DocumentNames.CodeAction, JObject.Parse(JsonConvert.SerializeObject(@params, new Serializer(ClientVersion.Lsp3).Settings)));

            await mediator.RouteRequest(mediator.GetDescriptor(request), request);

            await codeActionHandler.Received(1).Handle(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>());
        }
예제 #28
0
        public void Should_Handle_Mixed_Capabilities()
        {
            var textDocumentSyncHandler =
                TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp");

            var codeActionHandler     = Substitute.For <ICodeActionHandler>();
            var definitionHandler     = Substitute.For <IDefinitionHandler>();
            var typeDefinitionHandler = Substitute.For <ITypeDefinitionHandler>();

            var collection =
                new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), Substitute.For <IResolverContext>(),
                                            new LspHandlerTypeDescriptorProvider(new [] { typeof(FoundationTests).Assembly, typeof(LanguageServer).Assembly, typeof(LanguageClient).Assembly, typeof(IRegistrationManager).Assembly, typeof(LspRequestRouter).Assembly }))
            {
                textDocumentSyncHandler, codeActionHandler, definitionHandler, typeDefinitionHandler
            };
            var provider     = new ClientCapabilityProvider(collection, true);
            var capabilities = new ClientCapabilities {
                TextDocument = new TextDocumentClientCapabilities {
                    CodeAction = new Supports <CodeActionCapability?>(
                        true, new CodeActionCapability {
                        DynamicRegistration = false,
                    }
                        ),
                    TypeDefinition = new Supports <TypeDefinitionCapability?>(
                        true, new TypeDefinitionCapability {
                        DynamicRegistration = true,
                    }
                        )
                }
            };

//            provider.GetStaticOptions(capabilities.TextDocument.CodeAction)
//                    .Get<ICodeActionOptions, CodeActionRegistrationOptions.StaticOptions>(CodeActionRegistrationOptions.StaticOptions.Of).Should().NotBeNull();
            provider.HasStaticHandler(capabilities.TextDocument.Definition).Should().BeTrue();
            provider.HasStaticHandler(capabilities.TextDocument.TypeDefinition).Should().BeFalse();
        }