public async Task HandleRequestAsync_RazorProjection_DoesNotInvokeServer()
        {
            // Arrange
            var documentManager = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>(s => s.Uri == Uri));

            var invokedServer  = false;
            var requestInvoker = new Mock <LSPRequestInvoker>();

            requestInvoker
            .Setup(r => r.ReinvokeRequestOnServerAsync <DocumentOnAutoInsertParams, DocumentOnAutoInsertResponseItem>(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <DocumentOnAutoInsertParams>(), It.IsAny <CancellationToken>()))
            .Callback <string, string, DocumentOnAutoInsertParams, CancellationToken>((method, serverContentType, formattingParams, ct) =>
            {
                invokedServer = true;
            })
            .Returns(Task.FromResult(new DocumentOnAutoInsertResponseItem()
            {
                TextEdit = new TextEdit()
            }));

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.Razor,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>();

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));
            var documentMappingProvider = Mock.Of <LSPDocumentMappingProvider>();

            var handler = new OnAutoInsertHandler(documentManager, requestInvoker.Object, projectionProvider.Object, documentMappingProvider);
            var request = new DocumentOnAutoInsertParams()
            {
                Character    = ">",
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Options = new FormattingOptions()
                {
                    OtherOptions = new Dictionary <string, object>()
                },
                Position = new Position(0, 0)
            };

            // Act
            var response = await handler.HandleRequestAsync(request, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.False(invokedServer);
            Assert.Null(response);
        }
        public async Task HandleRequestAsync_InvokesServerWithCorrectKey()
        {
            // Arrange
            var documentManager = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>(s => s.Uri == Uri));

            var invokedServer  = false;
            var requestInvoker = new Mock <LSPRequestInvoker>();

            requestInvoker
            .Setup(r => r.ReinvokeRequestOnServerAsync <DocumentOnTypeFormattingParams, TextEdit[]>(It.IsAny <string>(), It.IsAny <LanguageServerKind>(), It.IsAny <DocumentOnTypeFormattingParams>(), It.IsAny <CancellationToken>()))
            .Callback <string, LanguageServerKind, DocumentOnTypeFormattingParams, CancellationToken>((method, serverKind, formattingParams, ct) =>
            {
                Assert.True(formattingParams.Options.OtherOptions.ContainsKey(LanguageServerConstants.ExpectsCursorPlaceholderKey));
                invokedServer = true;
            })
            .Returns(Task.FromResult <TextEdit[]>(new[] { new TextEdit() }));

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.Html,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>();

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));
            var documentMappingProvider = Mock.Of <LSPDocumentMappingProvider>();
            var editorService           = Mock.Of <LSPEditorService>();

            var handler = new TestOnTypeFormattingHandler(JoinableTaskContext, documentManager, requestInvoker.Object, projectionProvider.Object, documentMappingProvider, editorService);
            var request = new DocumentOnTypeFormattingParams()
            {
                Character    = ">",
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Options = new FormattingOptions()
                {
                    OtherOptions = new Dictionary <string, object>()
                },
                Position = new Position(0, 0)
            };

            // Act
            var edits = await handler.HandleRequestAsync(request, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(invokedServer);
            Assert.Empty(edits);
        }
Example #3
0
        public async Task HandleRequestAsync_CSharpProjection_DoesNotRemapNonRazorFiles()
        {
            // Arrange
            var progressReported = false;
            var documentManager  = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>());

            var externalCSharpUri      = new Uri("C:/path/to/someotherfile.cs");
            var externalCsharpLocation = GetReferenceItem(100, externalCSharpUri);

            var(requestInvoker, progressListener) = MockServices(externalCsharpLocation, out var token);

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.CSharp,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>();

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));

            var documentMappingProvider = Mock.Of <LSPDocumentMappingProvider>();
            var languageServiceBroker   = Mock.Of <ILanguageServiceBroker2>();

            var referencesHandler = new FindAllReferencesHandler(requestInvoker, documentManager, projectionProvider.Object, documentMappingProvider, progressListener);

            referencesHandler.WaitForProgressNotificationTimeout = TestWaitForProgressNotificationTimeout;

            var progressToken = new ProgressWithCompletion <object>((val) =>
            {
                var results        = Assert.IsType <VSReferenceItem[]>(val);
                var actualLocation = Assert.Single(results);
                AssertVSReferenceItem(externalCsharpLocation, actualLocation);
                progressReported = true;
            });
            var referenceRequest = new ReferenceParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position           = new Position(10, 5),
                PartialResultToken = progressToken
            };

            // Act
            var result = await referencesHandler.HandleRequestAsync(referenceRequest, new ClientCapabilities(), token, CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(progressReported);
        }
        public async Task HandleRequestAsync_CSharpProjection_InvokesCSharpLanguageServer()
        {
            // Arrange
            var called          = false;
            var expectedEdit    = new TextEdit();
            var documentManager = new TestDocumentManager();
            var snapshot        = new StringTextSnapshot(@"
@code {
public string _foo;
}");

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>(m => m.Snapshot == snapshot));
            var requestInvoker = new Mock <LSPRequestInvoker>();

            requestInvoker
            .Setup(r => r.ReinvokeRequestOnServerAsync <DocumentOnTypeFormattingParams, TextEdit[]>(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <DocumentOnTypeFormattingParams>(), It.IsAny <CancellationToken>()))
            .Callback <string, string, DocumentOnTypeFormattingParams, CancellationToken>((method, serverContentType, onTypeFormattingParams, ct) =>
            {
                Assert.Equal(Methods.TextDocumentOnTypeFormattingName, method);
                Assert.Equal(RazorLSPConstants.CSharpContentTypeName, serverContentType);
                called = true;
            })
            .Returns(Task.FromResult(new[] { expectedEdit }));

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.CSharp,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>();

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));
            var mappingProvider     = Mock.Of <LSPDocumentMappingProvider>();
            var formatOnTypeHandler = new OnTypeFormattingHandler(documentManager, requestInvoker.Object, projectionProvider.Object, mappingProvider);
            var formattingRequest   = new DocumentOnTypeFormattingParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position  = new Position(2, 19),
                Character = ";",
                Options   = new FormattingOptions()
            };

            // Act
            var result = await formatOnTypeHandler.HandleRequestAsync(formattingRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(called);
        }
        public async Task HandleRequestAsync_HtmlProjection_InvokesHtmlLanguageServer_ReturnsItem()
        {
            // Arrange
            var called         = false;
            var expectedResult = new ReinvocationResponse <SignatureHelp>("LanguageClientName", new SignatureHelp());

            var virtualHtmlUri = new Uri("C:/path/to/file.razor__virtual.html");
            var requestInvoker = new Mock <LSPRequestInvoker>(MockBehavior.Strict);

            requestInvoker
            .Setup(r => r.ReinvokeRequestOnServerAsync <TextDocumentPositionParams, SignatureHelp>(
                       It.IsAny <ITextBuffer>(),
                       It.IsAny <string>(),
                       It.IsAny <string>(),
                       It.IsAny <TextDocumentPositionParams>(),
                       It.IsAny <CancellationToken>()))
            .Callback <ITextBuffer, string, string, TextDocumentPositionParams, CancellationToken>((textBuffer, method, clientName, definitionParams, ct) =>
            {
                Assert.Equal(Methods.TextDocumentSignatureHelpName, method);
                Assert.Equal(RazorLSPConstants.HtmlLanguageServerName, clientName);
                called = true;
            })
            .Returns(Task.FromResult(expectedResult));

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.Html,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>(MockBehavior.Strict);

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));

            var signatureHelpHandler = new SignatureHelpHandler(requestInvoker.Object, DocumentManager, projectionProvider.Object, LoggerProvider);
            var signatureHelpRequest = new TextDocumentPositionParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position = new Position(10, 5)
            };

            // Act
            var result = await signatureHelpHandler.HandleRequestAsync(signatureHelpRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(called);
            Assert.Equal(expectedResult.Response, result);
        }
        public async Task HandleRequestAsync_CSharpProjection_InvokesCSharpLanguageServerWithNoResult()
        {
            // Arrange
            var called       = false;
            var hoverRequest = new TextDocumentPositionParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position = new Position(0, 1)
            };

            var documentManager = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>());

            var requestInvoker = new Mock <LSPRequestInvoker>();

            requestInvoker
            .Setup(r => r.ReinvokeRequestOnServerAsync <TextDocumentPositionParams, Hover>(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <TextDocumentPositionParams>(), It.IsAny <CancellationToken>()))
            .Callback <string, string, TextDocumentPositionParams, CancellationToken>((method, serverContentType, hoverParams, ct) =>
            {
                Assert.Equal(Methods.TextDocumentHoverName, method);
                Assert.Equal(RazorLSPConstants.CSharpContentTypeName, serverContentType);
                called = true;
            })
            .Returns(Task.FromResult <Hover>(null));

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.CSharp,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>();

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));

            var documentMappingProvider = new Mock <LSPDocumentMappingProvider>();

            var hoverHandler = new HoverHandler(requestInvoker.Object, documentManager, projectionProvider.Object, documentMappingProvider.Object);

            // Act
            var result = await hoverHandler.HandleRequestAsync(hoverRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(called);
            Assert.Null(result);
        }
        public async Task HandleRequestAsync_CSharpProjection_InvokesCSharpLanguageServer_ReturnsItem()
        {
            // Arrange
            var called          = false;
            var expectedResult  = new SignatureHelp();
            var documentManager = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>());

            var virtualCSharpUri = new Uri("C:/path/to/file.razor.g.cs");
            var requestInvoker   = new Mock <LSPRequestInvoker>(MockBehavior.Strict);

            requestInvoker
            .Setup(r => r.ReinvokeRequestOnServerAsync <TextDocumentPositionParams, SignatureHelp>(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <TextDocumentPositionParams>(), It.IsAny <CancellationToken>()))
            .Callback <string, string, TextDocumentPositionParams, CancellationToken>((method, serverContentType, definitionParams, ct) =>
            {
                Assert.Equal(Methods.TextDocumentSignatureHelpName, method);
                Assert.Equal(RazorLSPConstants.CSharpContentTypeName, serverContentType);
                called = true;
            })
            .Returns(Task.FromResult(expectedResult));

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.CSharp,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>(MockBehavior.Strict);

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));

            var signatureHelpHandler = new SignatureHelpHandler(requestInvoker.Object, documentManager, projectionProvider.Object);
            var signatureHelpRequest = new TextDocumentPositionParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position = new Position(10, 5)
            };

            // Act
            var result = await signatureHelpHandler.HandleRequestAsync(signatureHelpRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(called);
            Assert.Equal(expectedResult, result);
        }
        public async Task HandleRequestAsync_RemapFailure_DiscardsLocation()
        {
            // Arrange
            var called            = false;
            var expectedHighlight = GetHighlight(5, 5, 5, 5);
            var documentManager   = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>(d => d.Version == 0, MockBehavior.Strict));

            var csharpHighlight = GetHighlight(100, 100, 100, 100);
            var requestInvoker  = GetRequestInvoker <DocumentHighlightParams, DocumentHighlight[]>(
                new[] { csharpHighlight },
                (method, serverContentType, highlightParams, ct) =>
            {
                Assert.Equal(Methods.TextDocumentDocumentHighlightName, method);
                Assert.Equal(RazorLSPConstants.CSharpContentTypeName, serverContentType);
                called = true;
            });

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.CSharp,
            };
            var projectionProvider = GetProjectionProvider(projectionResult);

            var documentMappingProvider = new Mock <LSPDocumentMappingProvider>(MockBehavior.Strict).Object;

            Mock.Get(documentMappingProvider).Setup(p => p.MapToDocumentRangesAsync(RazorLanguageKind.CSharp, Uri, It.IsAny <Range[]>(), CancellationToken.None))
            .Returns(Task.FromResult <RazorMapToDocumentRangesResponse>(null));

            var highlightHandler = new DocumentHighlightHandler(requestInvoker, documentManager, projectionProvider, documentMappingProvider);
            var highlightRequest = new DocumentHighlightParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position = new Position(10, 5)
            };

            // Act
            var result = await highlightHandler.HandleRequestAsync(highlightRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(called);
            Assert.Empty(result);
        }
        public async Task HandleRequestAsync_RemapFailure_ReturnsNull()
        {
            // Arrange
            var invokerCalled    = false;
            var expectedResponse = GetMatchingHTMLBracketRange(5);
            var documentManager  = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>(d => d.Version == 0, MockBehavior.Strict));

            var htmlResponse   = GetMatchingHTMLBracketRange(10);
            var requestInvoker = GetRequestInvoker <DocumentOnTypeRenameParams, DocumentOnTypeRenameResponseItem>(
                htmlResponse,
                (method, serverContentType, highlightParams, ct) =>
            {
                Assert.Equal(MSLSPMethods.OnTypeRenameName, method);
                Assert.Equal(RazorLSPConstants.HtmlLSPContentTypeName, serverContentType);
                invokerCalled = true;
            });

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.Html,
            };
            var projectionProvider = GetProjectionProvider(projectionResult);

            var documentMappingProvider = new Mock <LSPDocumentMappingProvider>(MockBehavior.Strict).Object;

            Mock.Get(documentMappingProvider).Setup(p => p.MapToDocumentRangesAsync(RazorLanguageKind.Html, Uri, It.IsAny <Range[]>(), CancellationToken.None))
            .Returns(Task.FromResult <RazorMapToDocumentRangesResponse>(null));

            var onTypeRenameHandler = new OnTypeRenameHandler(documentManager, requestInvoker, projectionProvider, documentMappingProvider, LoggerProvider);
            var onTypeRenameRequest = new DocumentOnTypeRenameParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position = new Position(10, 5)
            };

            // Act
            var result = await onTypeRenameHandler.HandleRequestAsync(onTypeRenameRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(invokerCalled);
            Assert.Null(result);
        }
        public async Task HandleRequestAsync_HtmlProjection_RemapsHighlightRange()
        {
            // Arrange
            var invokerCalled    = false;
            var expectedResponse = GetMatchingHTMLBracketRange(5);
            var documentManager  = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>(d => d.Version == 0, MockBehavior.Strict));

            var htmlResponse   = GetMatchingHTMLBracketRange(10);
            var requestInvoker = GetRequestInvoker <DocumentOnTypeRenameParams, DocumentOnTypeRenameResponseItem>(
                htmlResponse,
                (method, serverContentType, highlightParams, ct) =>
            {
                Assert.Equal(MSLSPMethods.OnTypeRenameName, method);
                Assert.Equal(RazorLSPConstants.HtmlLSPContentTypeName, serverContentType);
                invokerCalled = true;
            });

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.Html,
            };
            var projectionProvider = GetProjectionProvider(projectionResult);

            var documentMappingProvider = GetDocumentMappingProvider(expectedResponse.Ranges, 0, RazorLanguageKind.Html);

            var onTypeRenameHandler = new OnTypeRenameHandler(documentManager, requestInvoker, projectionProvider, documentMappingProvider, LoggerProvider);
            var onTypeRenameRequest = new DocumentOnTypeRenameParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position = new Position(10, 5)
            };

            // Act
            var result = await onTypeRenameHandler.HandleRequestAsync(onTypeRenameRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(invokerCalled);
            Assert.NotNull(result);
            Assert.Collection(result.Ranges,
                              r => Assert.Equal(expectedResponse.Ranges[0], r),
                              r => Assert.Equal(expectedResponse.Ranges[1], r));
        }
Example #11
0
        public async Task HandleRequestAsync_CSharpProjection_RemapsHighlightRange()
        {
            // Arrange
            var called            = false;
            var expectedHighlight = GetHighlight(5, 5, 5, 5);
            var documentManager   = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>(d => d.Version == 0));

            var csharpHighlight = GetHighlight(100, 100, 100, 100);
            var requestInvoker  = GetRequestInvoker <DocumentHighlightParams, DocumentHighlight[]>(
                new[] { csharpHighlight },
                (method, serverKind, highlightParams, ct) =>
            {
                Assert.Equal(Methods.TextDocumentDocumentHighlightName, method);
                Assert.Equal(LanguageServerKind.CSharp, serverKind);
                called = true;
            });

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.CSharp,
            };
            var projectionProvider = GetProjectionProvider(projectionResult);

            var documentMappingProvider = GetDocumentMappingProvider(expectedHighlight.Range, 0, RazorLanguageKind.CSharp);

            var highlightHandler = new DocumentHighlightHandler(requestInvoker, documentManager, projectionProvider, documentMappingProvider);
            var highlightRequest = new DocumentHighlightParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position = new Position(10, 5)
            };

            // Act
            var result = await highlightHandler.HandleRequestAsync(highlightRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(called);
            var actualHighlight = Assert.Single(result);

            Assert.Equal(expectedHighlight.Range, actualHighlight.Range);
        }
Example #12
0
        public async Task TryGetProvisionalCompletionsAsync_ProjectionAtStartOfLine_ReturnsFalse()
        {
            // Arrange
            var completionRequest = new CompletionParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Context = new CompletionContext()
                {
                    TriggerKind      = CompletionTriggerKind.TriggerCharacter,
                    TriggerCharacter = "."
                },
                Position = new Position(0, 1)
            };

            var documentManager = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>());

            var requestInvoker = new Mock <LSPRequestInvoker>();

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.Html,
                Position     = new Position(1, 0)
            };
            var previousCharacterProjection = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.CSharp,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>();

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(previousCharacterProjection));

            var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object);

            // Act
            var(succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, Mock.Of <LSPDocumentSnapshot>(), projectionResult, CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.False(succeeded);
            Assert.Null(result);
        }
Example #13
0
        public async Task HandleRequestAsync_ProgressListener_ReturnsNull()
        {
            // Arrange
            var documentManager = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>());
            var requestInvoker = Mock.Of <LSPRequestInvoker>();

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.CSharp,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>();

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));

            Task onCompleted             = null;
            var  documentMappingProvider = Mock.Of <LSPDocumentMappingProvider>();
            var  progressListener        = Mock.Of <LSPProgressListener>(l =>
                                                                         l.TryListenForProgress(
                                                                             It.IsAny <string>(),
                                                                             It.IsAny <Func <JToken, CancellationToken, Task> >(),
                                                                             It.IsAny <TimeSpan>(),
                                                                             It.IsAny <CancellationToken>(),
                                                                             out onCompleted) == false);

            var referencesHandler = new FindAllReferencesHandler(requestInvoker, documentManager, projectionProvider.Object, documentMappingProvider, progressListener);

            referencesHandler.WaitForProgressNotificationTimeout = TestWaitForProgressNotificationTimeout;
            var referenceRequest = new ReferenceParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position = new Position(0, 1)
            };

            // Act
            var result = await referencesHandler.HandleRequestAsync(referenceRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.Null(result);
        }
Example #14
0
        public async Task HandleRequestAsync_VersionMismatch_DiscardsLocation()
        {
            // Arrange
            var called            = false;
            var expectedHighlight = GetHighlight(5, 5, 5, 5);
            var documentManager   = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>(d => d.Version == 1));

            var csharpHighlight = GetHighlight(100, 100, 100, 100);
            var requestInvoker  = GetRequestInvoker <DocumentHighlightParams, DocumentHighlight[]>(
                new[] { csharpHighlight },
                (method, serverContentType, highlightParams, ct) =>
            {
                Assert.Equal(Methods.TextDocumentDocumentHighlightName, method);
                Assert.Equal(RazorLSPConstants.CSharpContentTypeName, serverContentType);
                called = true;
            });

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.CSharp,
            };
            var projectionProvider = GetProjectionProvider(projectionResult);

            var documentMappingProvider = GetDocumentMappingProvider(expectedHighlight.Range, 0 /* Different from document version (1) */, RazorLanguageKind.CSharp);

            var highlightHandler = new DocumentHighlightHandler(requestInvoker, documentManager, projectionProvider, documentMappingProvider);
            var highlightRequest = new DocumentHighlightParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position = new Position(10, 5)
            };

            // Act
            var result = await highlightHandler.HandleRequestAsync(highlightRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(called);
            Assert.Empty(result);
        }
        public async Task HandleRequestAsync_HtmlProjection_RemapsHighlightRange()
        {
            // Arrange
            var called            = false;
            var expectedHighlight = GetHighlight(5, 5, 5, 5);

            var htmlHighlight  = GetHighlight(100, 100, 100, 100);
            var requestInvoker = GetRequestInvoker <DocumentHighlightParams, DocumentHighlight[]>(
                new[] { htmlHighlight },
                (textBuffer, method, clientName, highlightParams, ct) =>
            {
                Assert.Equal(Methods.TextDocumentDocumentHighlightName, method);
                Assert.Equal(RazorLSPConstants.HtmlLanguageServerName, clientName);
                called = true;
            });

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.Html,
            };
            var projectionProvider = GetProjectionProvider(projectionResult);

            var documentMappingProvider = GetDocumentMappingProvider(expectedHighlight.Range, 0, RazorLanguageKind.Html);

            var highlightHandler = new DocumentHighlightHandler(requestInvoker, DocumentManager, projectionProvider, documentMappingProvider, LoggerProvider);
            var highlightRequest = new DocumentHighlightParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position = new Position(10, 5)
            };

            // Act
            var result = await highlightHandler.HandleRequestAsync(highlightRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(called);
            var actualHighlight = Assert.Single(result);

            Assert.Equal(expectedHighlight.Range, actualHighlight.Range);
        }
Example #16
0
        public async Task HandleRequestAsync_CSharpProjection_IncompatibleTriggerCharacter_ReturnsNull()
        {
            // Arrange
            var completionRequest = new CompletionParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Context = new CompletionContext()
                {
                    TriggerKind = CompletionTriggerKind.TriggerCharacter, TriggerCharacter = "<"
                },
                Position = new Position(0, 1)
            };

            var documentManager = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>());

            var requestInvoker = new Mock <LSPRequestInvoker>();

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.CSharp,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>();

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));

            var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object);

            // Act
            var result = await completionHandler.HandleRequestAsync(completionRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.Null(result);
        }
Example #17
0
        public async Task HandleRequestAsync_HtmlProjection_ReturnsNull()
        {
            // Arrange
            var documentManager = new TestDocumentManager();
            var snapshot        = new StringTextSnapshot(@"
@code {
public string _foo;
}");

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>(m => m.Snapshot == snapshot, MockBehavior.Strict));
            var requestInvoker   = Mock.Of <LSPRequestInvoker>(MockBehavior.Strict);
            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.Html,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>(MockBehavior.Strict);

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));
            var mappingProvider     = Mock.Of <LSPDocumentMappingProvider>(MockBehavior.Strict);
            var formatOnTypeHandler = new OnTypeFormattingHandler(documentManager, requestInvoker, projectionProvider.Object, mappingProvider);
            var formattingRequest   = new DocumentOnTypeFormattingParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position  = new Position(0, 1),
                Character = ";",
                Options   = new FormattingOptions()
            };

            // Act
            var result = await formatOnTypeHandler.HandleRequestAsync(formattingRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.Null(result);
        }
        public async Task HandleRequestAsync_ReturnNullIfCSharpLanguageServerReturnsNull()
        {
            // Arrange
            var virtualCSharpUri = new Uri("C:/path/to/file.razor.g.cs");
            var requestInvoker   = Mock.Of <LSPRequestInvoker>(i =>
                                                               i.ReinvokeRequestOnServerAsync <TextDocumentPositionParams, SignatureHelp>(
                                                                   It.IsAny <ITextBuffer>(),
                                                                   It.IsAny <string>(),
                                                                   It.IsAny <string>(),
                                                                   It.IsAny <TextDocumentPositionParams>(),
                                                                   It.IsAny <CancellationToken>()) == Task.FromResult(new ReinvocationResponse <SignatureHelp>("LanguageClient", null)), MockBehavior.Strict);

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.CSharp,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>(MockBehavior.Strict);

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));

            var signatureHelpHandler = new SignatureHelpHandler(requestInvoker, DocumentManager, projectionProvider.Object, LoggerProvider);
            var signatureHelpRequest = new TextDocumentPositionParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position = new Position(10, 5)
            };

            // Act
            var result = await signatureHelpHandler.HandleRequestAsync(signatureHelpRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.Null(result);
        }
Example #19
0
        public async Task TryGetProvisionalCompletionsAsync_AtCorrectProvisionalCompletionPoint_ReturnsExpectedResult()
        {
            // Arrange
            var completionRequest = new CompletionParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Context = new CompletionContext()
                {
                    TriggerKind      = CompletionTriggerKind.TriggerCharacter,
                    TriggerCharacter = "."
                },
                Position = new Position(0, 1)
            };

            var virtualDocumentUri = new Uri("C:/path/to/file.razor__virtual.cs");

            var documentManager = new TestDocumentManager();

            var languageServerCalled = false;
            var expectedItem         = new CompletionItem()
            {
                InsertText = "DateTime"
            };
            var requestInvoker = new Mock <LSPRequestInvoker>(MockBehavior.Strict);

            requestInvoker
            .Setup(r => r.RequestServerAsync <CompletionParams, SumType <CompletionItem[], CompletionList>?>(It.IsAny <string>(), LanguageServerKind.CSharp, It.IsAny <CompletionParams>(), It.IsAny <CancellationToken>()))
            .Callback <string, LanguageServerKind, CompletionParams, CancellationToken>((method, serverKind, completionParams, ct) =>
            {
                Assert.Equal(Methods.TextDocumentCompletionName, method);
                Assert.Equal(LanguageServerKind.CSharp, serverKind);
                languageServerCalled = true;
            })
            .Returns(Task.FromResult <SumType <CompletionItem[], CompletionList>?>(new[] { expectedItem }));

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.Html,
                Position     = new Position(1, 7)
            };
            var previousCharacterProjection = new ProjectionResult()
            {
                LanguageKind  = RazorLanguageKind.CSharp,
                Position      = new Position(100, 10),
                PositionIndex = 1000,
                Uri           = virtualDocumentUri
            };
            var projectionProvider = new Mock <LSPProjectionProvider>();

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(previousCharacterProjection));

            var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object);

            // Act
            var(succeeded, result) = await completionHandler.TryGetProvisionalCompletionsAsync(completionRequest, Mock.Of <LSPDocumentSnapshot>(), projectionResult, CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(succeeded);
            Assert.True(languageServerCalled);
            Assert.Equal(2, documentManager.UpdateVirtualDocumentCallCount);
            Assert.NotNull(result);
            var item = Assert.Single((CompletionItem[])result.Value);

            Assert.Equal(expectedItem.InsertText, item.InsertText);
        }
Example #20
0
        public async Task HandleRequestAsync_CSharpProjection_ReturnsKeywordsFromCSharp()
        {
            // Arrange
            var called        = false;
            var expectedItems = new CompletionItem[] {
                new CompletionItem()
                {
                    InsertText = "DateTime", Label = "DateTime"
                },
                new CompletionItem()
                {
                    InsertText = "FROMCSHARP", Label = "for"
                },
            };

            var completionRequest = new CompletionParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Context = new CompletionContext()
                {
                    TriggerKind = CompletionTriggerKind.Invoked, TriggerCharacter = "@"
                },
                Position = new Position(0, 1)
            };

            var documentManager = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>());

            var requestInvoker = new Mock <LSPRequestInvoker>();

            requestInvoker
            .Setup(r => r.ReinvokeRequestOnServerAsync <CompletionParams, SumType <CompletionItem[], CompletionList>?>(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <CompletionParams>(), It.IsAny <CancellationToken>()))
            .Callback <string, string, CompletionParams, CancellationToken>((method, serverContentType, completionParams, ct) =>
            {
                Assert.Equal(Methods.TextDocumentCompletionName, method);
                Assert.Equal(RazorLSPConstants.CSharpContentTypeName, serverContentType);
                called = true;
            })
            .Returns(Task.FromResult <SumType <CompletionItem[], CompletionList>?>(expectedItems));

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.CSharp,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>();

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));

            var completionHandler = new CompletionHandler(JoinableTaskContext, requestInvoker.Object, documentManager, projectionProvider.Object);

            // Act
            var result = await completionHandler.HandleRequestAsync(completionRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(called);
            Assert.True(result.HasValue);
            var _ = result.Value.Match <SumType <CompletionItem[], CompletionList> >(
                array => {
                Assert.Collection(array,
                                  item => Assert.Equal("DateTime", item.InsertText),
                                  item => {
                    Assert.Equal("for", item.Label);
                    Assert.Equal("FROMCSHARP", item.InsertText);
                },
                                  item => Assert.Equal("foreach", item.Label),
                                  item => Assert.Equal("while", item.Label),
                                  item => Assert.Equal("switch", item.Label),
                                  item => Assert.Equal("lock", item.Label),
                                  item => Assert.Equal("case", item.Label),
                                  item => Assert.Equal("if", item.Label),
                                  item => Assert.Equal("try", item.Label),
                                  item => Assert.Equal("do", item.Label),
                                  item => Assert.Equal("using", item.Label)
                                  );;

                return(array);
            },
                list => {
                throw new NotImplementedException();
            });
        }
        public async Task HandleRequestAsync_InvokesCSharpServer_RemapsEdits()
        {
            // Arrange
            var invokedServer   = false;
            var mappedTextEdits = false;
            var requestInvoker  = new Mock <LSPRequestInvoker>(MockBehavior.Strict);

            requestInvoker
            .Setup(r => r.ReinvokeRequestOnServerAsync <VSInternalDocumentOnAutoInsertParams, VSInternalDocumentOnAutoInsertResponseItem>(
                       It.IsAny <ITextBuffer>(),
                       VSInternalMethods.OnAutoInsertName,
                       It.IsAny <string>(),
                       It.IsAny <VSInternalDocumentOnAutoInsertParams>(),
                       It.IsAny <CancellationToken>()))
            .Callback <ITextBuffer, string, string, VSInternalDocumentOnAutoInsertParams, CancellationToken>((textBuffer, method, clientName, formattingParams, ct) => invokedServer = true)
            .Returns(Task.FromResult(new ReinvocationResponse <VSInternalDocumentOnAutoInsertResponseItem>("LanguageClientName", new VSInternalDocumentOnAutoInsertResponseItem()
            {
                TextEdit = new TextEdit()
                {
                    Range = new Range(), NewText = "sometext"
                }, TextEditFormat = InsertTextFormat.Snippet
            })));

            var projectionUri    = new Uri(Uri.AbsoluteUri + "__virtual.html");
            var projectionResult = new ProjectionResult()
            {
                Uri          = projectionUri,
                LanguageKind = RazorLanguageKind.CSharp,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>(MockBehavior.Strict);

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));

            var documentMappingProvider = new Mock <LSPDocumentMappingProvider>(MockBehavior.Strict);

            documentMappingProvider
            .Setup(d => d.RemapFormattedTextEditsAsync(projectionUri, It.IsAny <TextEdit[]>(), It.IsAny <FormattingOptions>(), /*containsSnippet*/ true, It.IsAny <CancellationToken>()))
            .Callback(() => mappedTextEdits = true)
            .Returns(Task.FromResult(new[] { new TextEdit()
                                             {
                                                 NewText = "mapped-sometext"
                                             } }));

            var handler = new OnAutoInsertHandler(DocumentManager, requestInvoker.Object, projectionProvider.Object, documentMappingProvider.Object, LoggerProvider);
            var request = new VSInternalDocumentOnAutoInsertParams()
            {
                Character    = "/",
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Options = new FormattingOptions()
                {
                    OtherOptions = new Dictionary <string, object>()
                },
                Position = new Position(1, 4)
            };

            // Act
            var response = await handler.HandleRequestAsync(request, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(invokedServer);
            Assert.True(mappedTextEdits);
            Assert.NotNull(response);
        }
        public async Task HandleRequestAsync_CSharpProjection_InvokesCSharpLanguageServer()
        {
            // Arrange
            var called = false;

            var expectedContents = new SumType <SumType <string, MarkedString>, SumType <string, MarkedString>[], MarkupContent>(
                new MarkedString()
            {
                Language = "markdown",
                Value    = "Hover Details"
            }
                );

            var lspResponse = new Hover()
            {
                Range = new Range()
                {
                    Start = new Position(10, 0),
                    End   = new Position(10, 1)
                },
                Contents = expectedContents
            };

            var expectedItem = new Hover()
            {
                Range = new Range()
                {
                    Start = new Position(0, 0),
                    End   = new Position(0, 1)
                },
                Contents = expectedContents
            };

            var hoverRequest = new TextDocumentPositionParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position = new Position(0, 1)
            };

            var documentManager = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>());

            var requestInvoker = new Mock <LSPRequestInvoker>();

            requestInvoker
            .Setup(r => r.ReinvokeRequestOnServerAsync <TextDocumentPositionParams, Hover>(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <TextDocumentPositionParams>(), It.IsAny <CancellationToken>()))
            .Callback <string, string, TextDocumentPositionParams, CancellationToken>((method, serverContentType, hoverParams, ct) =>
            {
                Assert.Equal(Methods.TextDocumentHoverName, method);
                Assert.Equal(RazorLSPConstants.CSharpContentTypeName, serverContentType);
                called = true;
            })
            .Returns(Task.FromResult(lspResponse));

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.CSharp
            };
            var projectionProvider = new Mock <LSPProjectionProvider>();

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));

            var remappingResult = new RazorMapToDocumentRangesResponse()
            {
                Ranges = new[] {
                    new Range()
                    {
                        Start = new Position(0, 0),
                        End   = new Position(0, 1)
                    }
                },
                HostDocumentVersion = 0
            };
            var documentMappingProvider = new Mock <LSPDocumentMappingProvider>();

            documentMappingProvider.Setup(d => d.MapToDocumentRangesAsync(RazorLanguageKind.CSharp, It.IsAny <Uri>(), It.IsAny <Range[]>(), It.IsAny <CancellationToken>())).
            Returns(Task.FromResult(remappingResult));

            var hoverHandler = new HoverHandler(requestInvoker.Object, documentManager, projectionProvider.Object, documentMappingProvider.Object);

            // Act
            var result = await hoverHandler.HandleRequestAsync(hoverRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(called);
            Assert.Equal(expectedItem.Contents, result.Contents);
            Assert.Equal(expectedItem.Range, result.Range);
        }
        internal async Task <(bool, SumType <CompletionItem[], CompletionList>?)> TryGetProvisionalCompletionsAsync(CompletionParams request, LSPDocumentSnapshot documentSnapshot, ProjectionResult projection, CancellationToken cancellationToken)
        {
            SumType <CompletionItem[], CompletionList>?result = null;

            if (projection.LanguageKind != RazorLanguageKind.Html ||
                request.Context.TriggerKind != CompletionTriggerKind.TriggerCharacter ||
                request.Context.TriggerCharacter != ".")
            {
                return(false, result);
            }

            if (projection.Position.Character == 0)
            {
                // We're at the start of line. Can't have provisional completions here.
                return(false, result);
            }

            var previousCharacterPosition   = new Position(projection.Position.Line, projection.Position.Character - 1);
            var previousCharacterProjection = await _projectionProvider.GetProjectionAsync(documentSnapshot, previousCharacterPosition, cancellationToken).ConfigureAwait(false);

            if (previousCharacterProjection == null || previousCharacterProjection.LanguageKind != RazorLanguageKind.CSharp)
            {
                return(false, result);
            }

            if (!(_documentManager is TrackingLSPDocumentManager trackingDocumentManager))
            {
                return(false, result);
            }

            // Edit the CSharp projected document to contain a '.'. This allows C# completion to provide valid
            // completion items for moments when a user has typed a '.' that's typically interpreted as Html.
            var addProvisionalDot = new VisualStudioTextChange(previousCharacterProjection.PositionIndex, 0, ".");

            await _joinableTaskFactory.SwitchToMainThreadAsync();

            trackingDocumentManager.UpdateVirtualDocument <CSharpVirtualDocument>(documentSnapshot.Uri, new[] { addProvisionalDot }, previousCharacterProjection.HostDocumentVersion);

            var provisionalCompletionParams = new CompletionParams()
            {
                Context      = request.Context,
                Position     = new Position(previousCharacterProjection.Position.Line, previousCharacterProjection.Position.Character + 1),
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = previousCharacterProjection.Uri
                }
            };

            result = await _requestInvoker.ReinvokeRequestOnServerAsync <CompletionParams, SumType <CompletionItem[], CompletionList>?>(
                Methods.TextDocumentCompletionName,
                RazorLSPConstants.CSharpContentTypeName,
                provisionalCompletionParams,
                cancellationToken).ConfigureAwait(true);

            // We have now obtained the necessary completion items. We no longer need the provisional change. Revert.
            var removeProvisionalDot = new VisualStudioTextChange(previousCharacterProjection.PositionIndex, 1, string.Empty);

            trackingDocumentManager.UpdateVirtualDocument <CSharpVirtualDocument>(documentSnapshot.Uri, new[] { removeProvisionalDot }, previousCharacterProjection.HostDocumentVersion);

            return(true, result);
        }
Example #24
0
        public async Task HandleRequestAsync_HtmlProjection_InvokesHtmlLanguageServer()
        {
            // Arrange
            var invokedLSPRequest   = false;
            var invokedRemapRequest = false;
            var expectedLocation    = GetLocation(5, 5, 5, 5, Uri);

            var virtualHtmlUri = new Uri("C:/path/to/file.razor__virtual.html");
            var htmlLocation   = GetLocation(100, 100, 100, 100, virtualHtmlUri);
            var requestInvoker = new Mock <LSPRequestInvoker>(MockBehavior.Strict);

            requestInvoker
            .Setup(r => r.ReinvokeRequestOnServerAsync <TextDocumentPositionParams, Location[]>(
                       It.IsAny <ITextBuffer>(),
                       It.IsAny <string>(),
                       It.IsAny <string>(),
                       It.IsAny <TextDocumentPositionParams>(),
                       It.IsAny <CancellationToken>()))
            .Callback <ITextBuffer, string, string, TextDocumentPositionParams, CancellationToken>((textBuffer, method, clientName, definitionParams, ct) =>
            {
                Assert.Equal(Methods.TextDocumentDefinitionName, method);
                Assert.Equal(RazorLSPConstants.HtmlLanguageServerName, clientName);
                invokedLSPRequest = true;
            })
            .Returns(Task.FromResult(new ReinvocationResponse <Location[]>("LanguageClientName", new[] { htmlLocation })));

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.Html,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>(MockBehavior.Strict);

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));

            var documentMappingProvider = new Mock <LSPDocumentMappingProvider>(MockBehavior.Strict);

            documentMappingProvider
            .Setup(d => d.RemapLocationsAsync(It.IsAny <Location[]>(), It.IsAny <CancellationToken>()))
            .Callback <Location[], CancellationToken>((locations, token) =>
            {
                Assert.Equal(htmlLocation, locations[0]);
                invokedRemapRequest = true;
            })
            .Returns(Task.FromResult(Array.Empty <Location>()));

            var definitionHandler = new GoToDefinitionHandler(requestInvoker.Object, DocumentManager, projectionProvider.Object, documentMappingProvider.Object, LoggerProvider);
            var definitionRequest = new TextDocumentPositionParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position = new Position(10, 5)
            };

            // Act
            var result = await definitionHandler.HandleRequestAsync(definitionRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(invokedLSPRequest);
            Assert.True(invokedRemapRequest);

            // Actual remapping behavior is tested elsewhere.
        }
Example #25
0
        public async Task HandleRequestAsync_CSharpProjection_FiltersReferenceClassifiedRuns()
        {
            // Arrange
            var progressReported = false;
            var externalUri      = new Uri("C:/path/to/someotherfile.razor");

            var expectedClassifiedRun = new ClassifiedTextElement(new ClassifiedTextRun[]
            {
                new ClassifiedTextRun("text", "counter"),
            });
            var expectedReferenceItem = GetReferenceItem(5, 5, 5, 5, externalUri, text: expectedClassifiedRun);
            var documentManager       = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>(d => d.Version == 2));
            documentManager.AddDocument(externalUri, Mock.Of <LSPDocumentSnapshot>(d => d.Version == 5));

            var virtualClassifiedRun = new ClassifiedTextElement(new ClassifiedTextRun[]
            {
                new ClassifiedTextRun("field name", "__o"),
                new ClassifiedTextRun("text", " "),
                new ClassifiedTextRun("operator", "="),
                new ClassifiedTextRun("text", " "),
                new ClassifiedTextRun("text", "counter"),
                new ClassifiedTextRun("punctuation", ";"),
            });
            var virtualCSharpUri = new Uri("C:/path/to/someotherfile.razor.g.cs");
            var csharpLocation   = GetReferenceItem(100, 100, 100, 100, virtualCSharpUri, text: virtualClassifiedRun);

            var(requestInvoker, progressListener) = MockServices(csharpLocation, out var token);

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.CSharp,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>();

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));

            var remappingResult = new RazorMapToDocumentRangesResponse()
            {
                Ranges = new[] { expectedReferenceItem.Location.Range },
                HostDocumentVersion = 5
            };
            var documentMappingProvider = new Mock <LSPDocumentMappingProvider>();

            documentMappingProvider.Setup(d => d.MapToDocumentRangesAsync(RazorLanguageKind.CSharp, externalUri, new[] { csharpLocation.Location.Range }, It.IsAny <CancellationToken>())).
            Returns(Task.FromResult(remappingResult));

            var referencesHandler = new FindAllReferencesHandler(requestInvoker, documentManager, projectionProvider.Object, documentMappingProvider.Object, progressListener);

            referencesHandler.WaitForProgressNotificationTimeout = TestWaitForProgressNotificationTimeout;

            var progressToken = new ProgressWithCompletion <object>((val) =>
            {
                var results             = Assert.IsType <VSReferenceItem[]>(val);
                var actualReferenceItem = Assert.Single(results);
                AssertVSReferenceItem(expectedReferenceItem, actualReferenceItem);
                progressReported = true;
            });
            var referenceRequest = new ReferenceParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position           = new Position(10, 5),
                PartialResultToken = progressToken
            };

            // Act
            var result = await referencesHandler.HandleRequestAsync(referenceRequest, new ClientCapabilities(), token, CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(progressReported);
        }
Example #26
0
        public async Task HandleRequestAsync_InvokesServer_RemapsEdits()
        {
            // Arrange
            var documentManager = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>(s => s.Uri == Uri && s.Snapshot == Mock.Of <ITextSnapshot>()));

            var invokedServer   = false;
            var mappedTextEdits = false;
            var requestInvoker  = new Mock <LSPRequestInvoker>(MockBehavior.Strict);

            requestInvoker
            .Setup(r => r.ReinvokeRequestOnServerAsync <DocumentOnAutoInsertParams, DocumentOnAutoInsertResponseItem>(MSLSPMethods.OnAutoInsertName, It.IsAny <LanguageServerKind>(), It.IsAny <DocumentOnAutoInsertParams>(), It.IsAny <CancellationToken>()))
            .Callback <string, LanguageServerKind, DocumentOnAutoInsertParams, CancellationToken>((method, serverKind, formattingParams, ct) =>
            {
                invokedServer = true;
            })
            .Returns(Task.FromResult(new DocumentOnAutoInsertResponseItem()
            {
                TextEdit = new TextEdit()
                {
                    Range = new Range(), NewText = "sometext"
                }
            }));

            var projectionUri    = new Uri(Uri.AbsoluteUri + "__virtual.html");
            var projectionResult = new ProjectionResult()
            {
                Uri          = projectionUri,
                LanguageKind = RazorLanguageKind.Html,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>();

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));

            var documentMappingProvider = new Mock <LSPDocumentMappingProvider>(MockBehavior.Strict);

            documentMappingProvider
            .Setup(d => d.RemapTextEditsAsync(projectionUri, It.IsAny <TextEdit[]>(), It.IsAny <CancellationToken>()))
            .Callback(() => { mappedTextEdits = true; })
            .Returns(Task.FromResult(new[] { new TextEdit() }));

            var handler = new OnAutoInsertHandler(documentManager, requestInvoker.Object, projectionProvider.Object, documentMappingProvider.Object);
            var request = new DocumentOnAutoInsertParams()
            {
                Character    = "=",
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Options = new FormattingOptions()
                {
                    OtherOptions = new Dictionary <string, object>()
                },
                Position = new Position(1, 4)
            };

            // Act
            var response = await handler.HandleRequestAsync(request, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(invokedServer);
            Assert.True(mappedTextEdits);
            Assert.NotNull(response);
        }
Example #27
0
        public async Task HandleRequestAsync_VersionMismatch_DiscardsExternalRazorFiles()
        {
            // Arrange
            var progressReported = false;
            var externalUri      = new Uri("C:/path/to/someotherfile.razor");
            var expectedLocation = GetReferenceItem(5, externalUri);
            var documentManager  = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>(d => d.Version == 2));
            documentManager.AddDocument(externalUri, Mock.Of <LSPDocumentSnapshot>(d => d.Version == 5));

            var virtualCSharpUri = new Uri("C:/path/to/someotherfile.razor.g.cs");
            var csharpLocation   = GetReferenceItem(100, virtualCSharpUri);

            var(requestInvoker, progressListener) = MockServices(csharpLocation, out var token);

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.CSharp,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>();

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));

            var remappingResult = new RazorMapToDocumentRangesResponse()
            {
                Ranges = new[] { expectedLocation.Location.Range },
                HostDocumentVersion = 6
            };
            var documentMappingProvider = new Mock <LSPDocumentMappingProvider>();

            documentMappingProvider.Setup(d => d.MapToDocumentRangesAsync(RazorLanguageKind.CSharp, externalUri, new[] { csharpLocation.Location.Range }, It.IsAny <CancellationToken>())).
            Returns(Task.FromResult(remappingResult));

            var languageServiceBroker = Mock.Of <ILanguageServiceBroker2>();

            var referencesHandler = new FindAllReferencesHandler(requestInvoker, documentManager, projectionProvider.Object, documentMappingProvider.Object, progressListener);

            referencesHandler.WaitForProgressNotificationTimeout = TestWaitForProgressNotificationTimeout;

            var progressToken = new ProgressWithCompletion <object>((val) =>
            {
                var results = Assert.IsType <VSReferenceItem[]>(val);
                Assert.Empty(results);
                progressReported = true;
            });
            var referenceRequest = new ReferenceParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position           = new Position(10, 5),
                PartialResultToken = progressToken
            };

            // Act
            var result = await referencesHandler.HandleRequestAsync(referenceRequest, new ClientCapabilities(), token, CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(progressReported);
            Assert.Empty(result);
        }
Example #28
0
        private async Task <ProjectionResult?> GetProjectionCoreAsync(LSPDocumentSnapshot documentSnapshot, Position position, bool rejectOnNewerParallelRequest, CancellationToken cancellationToken)
        {
            if (documentSnapshot is null)
            {
                throw new ArgumentNullException(nameof(documentSnapshot));
            }

            if (position is null)
            {
                throw new ArgumentNullException(nameof(position));
            }

            // We initialize the logger here instead of the constructor as the projection provider is constructed
            // *before* the language server. Thus, the log hub has yet to be initialized, thus we would be unable to
            // create the logger at that time.
            await InitializeLogHubAsync(cancellationToken).ConfigureAwait(false);

            var languageQueryParams = new RazorLanguageQueryParams()
            {
                Position = position,
                Uri      = documentSnapshot.Uri
            };

            var response = await _requestInvoker.ReinvokeRequestOnServerAsync <RazorLanguageQueryParams, RazorLanguageQueryResponse>(
                documentSnapshot.Snapshot.TextBuffer,
                LanguageServerConstants.RazorLanguageQueryEndpoint,
                RazorLSPConstants.RazorLanguageServerName,
                CheckRazorLanguageQueryCapability,
                languageQueryParams,
                cancellationToken).ConfigureAwait(false);

            var languageResponse = response?.Response;

            if (languageResponse is null)
            {
                _logHubLogger?.LogInformation("The language server is still being spun up. Could not resolve the projection.");
                return(null);
            }

            VirtualDocumentSnapshot virtualDocument;

            if (languageResponse.Kind == RazorLanguageKind.CSharp &&
                documentSnapshot.TryGetVirtualDocument <CSharpVirtualDocumentSnapshot>(out var csharpDoc))
            {
                virtualDocument = csharpDoc;
            }
            else if (languageResponse.Kind == RazorLanguageKind.Html &&
                     documentSnapshot.TryGetVirtualDocument <HtmlVirtualDocumentSnapshot>(out var htmlDoc))
            {
                virtualDocument = htmlDoc;
            }
            else
            {
                _logHubLogger?.LogInformation($"Could not find projection for {languageResponse.Kind:G}.");
                return(null);
            }

            if (languageResponse.HostDocumentVersion is null)
            {
                // There should always be a document version attached to an open document.
                // Log it and move on as if it was synchronized.
                var message = $"Could not find a document version associated with the document '{documentSnapshot.Uri}'";
                _activityLogger.LogVerbose(message);
                _logHubLogger?.LogWarning(message);
            }
            else
            {
                var synchronized = await _documentSynchronizer.TrySynchronizeVirtualDocumentAsync(documentSnapshot.Version, virtualDocument, rejectOnNewerParallelRequest, cancellationToken).ConfigureAwait(false);

                if (!synchronized)
                {
                    _logHubLogger?.LogInformation("Could not synchronize.");
                    return(null);
                }
            }

            var result = new ProjectionResult()
            {
                Uri                 = virtualDocument.Uri,
                Position            = languageResponse.Position,
                PositionIndex       = languageResponse.PositionIndex,
                LanguageKind        = languageResponse.Kind,
                HostDocumentVersion = languageResponse.HostDocumentVersion
            };

            return(result);
        }
Example #29
0
        public async Task HandleRequestAsync_LargeProject_InvokesCSharpLanguageServer()
        {
            // Validates batching mechanism for the progress notification on large projects

            // Arrange
            var lspFarEndpointCalled = false;

            const int BATCH_SIZE     = 10;
            const int NUM_BATCHES    = 10;
            const int NUM_DOCUMENTS  = BATCH_SIZE * NUM_BATCHES;
            const int MAPPING_OFFSET = 10;

            var expectedUris             = new Uri[NUM_DOCUMENTS];
            var virtualUris              = new Uri[NUM_DOCUMENTS];
            var expectedReferences       = new VSReferenceItem[NUM_BATCHES][];
            var csharpUnmappedReferences = new VSReferenceItem[NUM_BATCHES][];
            var parameterTokens          = new JObject[NUM_BATCHES];

            var token = Guid.NewGuid().ToString();

            var documentNumber = 0;

            for (var batch = 0; batch < NUM_BATCHES; ++batch)
            {
                expectedReferences[batch]       = new VSReferenceItem[BATCH_SIZE];
                csharpUnmappedReferences[batch] = new VSReferenceItem[BATCH_SIZE];

                for (var documentInBatch = 0; documentInBatch < BATCH_SIZE; ++documentInBatch)
                {
                    expectedUris[documentNumber] = new Uri($"C:/path/to/file{documentNumber}.razor");
                    virtualUris[documentNumber]  = new Uri($"C:/path/to/file{documentNumber}.razor.g.cs");
                    expectedReferences[batch][documentInBatch] = GetReferenceItem(documentNumber, expectedUris[documentNumber]);

                    var umappedOffset = documentNumber * MAPPING_OFFSET;
                    csharpUnmappedReferences[batch][documentInBatch] = GetReferenceItem(umappedOffset, virtualUris[documentNumber]);
                    documentNumber++;
                }

                parameterTokens[batch] = new JObject
                {
                    { "token", token },
                    { "value", JArray.FromObject(csharpUnmappedReferences[batch]) }
                };
            }

            var documentManager = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>());

            var languageServiceBroker = Mock.Of <ILanguageServiceBroker2>();

            using var lspProgressListener = new DefaultLSPProgressListener(languageServiceBroker);

            var requestInvoker = new Mock <LSPRequestInvoker>();

            requestInvoker
            .Setup(r => r.ReinvokeRequestOnServerAsync <TextDocumentPositionParams, VSReferenceItem[]>(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <TextDocumentPositionParams>(), It.IsAny <CancellationToken>()))
            .Callback <string, string, TextDocumentPositionParams, CancellationToken>((method, serverContentType, definitionParams, ct) =>
            {
                Assert.Equal(Methods.TextDocumentReferencesName, method);
                Assert.Equal(RazorLSPConstants.CSharpContentTypeName, serverContentType);
                lspFarEndpointCalled = true;

                for (var i = 0; i < NUM_BATCHES; ++i)
                {
                    _ = lspProgressListener.ProcessProgressNotificationAsync(Methods.ProgressNotificationName, parameterTokens[i]);
                }
            })
            .Returns(Task.FromResult(Array.Empty <VSReferenceItem>()));

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.CSharp,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>();

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));

            var documentMappingProvider = new Mock <LSPDocumentMappingProvider>();

            documentMappingProvider
            .Setup(d => d.MapToDocumentRangesAsync(RazorLanguageKind.CSharp, It.IsAny <Uri>(), It.IsAny <Range[]>(), It.IsAny <CancellationToken>()))
            .Returns <RazorLanguageKind, Uri, Range[], CancellationToken>((languageKind, uri, ranges, ct) =>
            {
                var unmappedPosition = ranges[0].Start.Line;
                var mappedPosition   = unmappedPosition / MAPPING_OFFSET;

                var mappedRange = new Range()
                {
                    Start = new Position(mappedPosition, mappedPosition),
                    End   = new Position(mappedPosition, mappedPosition)
                };

                var response = new RazorMapToDocumentRangesResponse()
                {
                    Ranges = new[] { mappedRange }
                };

                return(Task.FromResult(response));
            });

            var referencesHandler = new FindAllReferencesHandler(requestInvoker.Object, documentManager, projectionProvider.Object, documentMappingProvider.Object, lspProgressListener);

            referencesHandler.WaitForProgressNotificationTimeout = TestWaitForProgressNotificationTimeout;

            var progressBatchesReported = new ConcurrentBag <VSReferenceItem[]>();
            var progressToken           = new ProgressWithCompletion <object>((val) =>
            {
                var results = Assert.IsType <VSReferenceItem[]>(val);
                Assert.Equal(BATCH_SIZE, results.Length);
                progressBatchesReported.Add(results);
            });
            var referenceRequest = new ReferenceParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position           = new Position(10, 5),
                PartialResultToken = progressToken
            };

            // Act
            var result = await referencesHandler.HandleRequestAsync(referenceRequest, new ClientCapabilities(), token, CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(lspFarEndpointCalled);

            var sortedBatchesReported = progressBatchesReported.ToList();

            sortedBatchesReported.Sort((VSReferenceItem[] a, VSReferenceItem[] b) =>
            {
                var indexA = a[0].Location.Range.Start.Character;
                var indexB = b[0].Location.Range.Start.Character;
                return(indexA.CompareTo(indexB));
            });

            Assert.Equal(NUM_BATCHES, sortedBatchesReported.Count);

            for (var batch = 0; batch < NUM_BATCHES; ++batch)
            {
                for (var documentInBatch = 0; documentInBatch < BATCH_SIZE; ++documentInBatch)
                {
                    AssertVSReferenceItem(
                        expectedReferences[batch][documentInBatch],
                        sortedBatchesReported[batch][documentInBatch]);
                }
            }
        }
Example #30
0
        public async Task HandleRequestAsync_HtmlProjection_InvokesHtmlLanguageServer()
        {
            // Arrange
            var lspFarEndpointCalled = false;
            var progressReported     = false;
            var expectedUri1         = new Uri("C:/path/to/file1.razor");
            var expectedUri2         = new Uri("C:/path/to/file2.razor");
            var expectedLocation1    = GetReferenceItem(5, expectedUri1);
            var expectedLocation2    = GetReferenceItem(10, expectedUri2);
            var documentManager      = new TestDocumentManager();

            documentManager.AddDocument(Uri, Mock.Of <LSPDocumentSnapshot>());

            var virtualHtmlUri1 = new Uri("C:/path/to/file1.razor__virtual.html");
            var virtualHtmlUri2 = new Uri("C:/path/to/file2.razor__virtual.html");
            var htmlLocation1   = GetReferenceItem(100, virtualHtmlUri1);
            var htmlLocation2   = GetReferenceItem(200, virtualHtmlUri2);

            var languageServiceBroker = Mock.Of <ILanguageServiceBroker2>();

            using var lspProgressListener = new DefaultLSPProgressListener(languageServiceBroker);

            var token          = Guid.NewGuid().ToString();
            var parameterToken = new JObject
            {
                { "token", token },
                { "value", JArray.FromObject(new[] { htmlLocation1, htmlLocation2 }) }
            };

            var requestInvoker = new Mock <LSPRequestInvoker>();

            requestInvoker
            .Setup(r => r.ReinvokeRequestOnServerAsync <TextDocumentPositionParams, VSReferenceItem[]>(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <TextDocumentPositionParams>(), It.IsAny <CancellationToken>()))
            .Callback <string, string, TextDocumentPositionParams, CancellationToken>((method, serverContentType, definitionParams, ct) =>
            {
                Assert.Equal(Methods.TextDocumentReferencesName, method);
                Assert.Equal(RazorLSPConstants.HtmlLSPContentTypeName, serverContentType);
                lspFarEndpointCalled = true;

                _ = lspProgressListener.ProcessProgressNotificationAsync(Methods.ProgressNotificationName, parameterToken);
            })
            .Returns(Task.FromResult(Array.Empty <VSReferenceItem>()));

            var projectionResult = new ProjectionResult()
            {
                LanguageKind = RazorLanguageKind.Html,
            };
            var projectionProvider = new Mock <LSPProjectionProvider>();

            projectionProvider.Setup(p => p.GetProjectionAsync(It.IsAny <LSPDocumentSnapshot>(), It.IsAny <Position>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(projectionResult));

            var remappingResult1 = new RazorMapToDocumentRangesResponse()
            {
                Ranges = new[] { expectedLocation1.Location.Range }
            };
            var remappingResult2 = new RazorMapToDocumentRangesResponse()
            {
                Ranges = new[] { expectedLocation2.Location.Range }
            };
            var documentMappingProvider = new Mock <LSPDocumentMappingProvider>();

            documentMappingProvider
            .Setup(d => d.MapToDocumentRangesAsync(RazorLanguageKind.Html, It.IsAny <Uri>(), It.IsAny <Range[]>(), It.IsAny <CancellationToken>()))
            .Returns <RazorLanguageKind, Uri, Range[], CancellationToken>((languageKind, uri, ranges, ct) => Task.FromResult(uri.LocalPath.Contains("file1") ? remappingResult1 : remappingResult2));

            var referencesHandler = new FindAllReferencesHandler(requestInvoker.Object, documentManager, projectionProvider.Object, documentMappingProvider.Object, lspProgressListener);

            referencesHandler.WaitForProgressNotificationTimeout = TestWaitForProgressNotificationTimeout;

            var progressToken = new ProgressWithCompletion <object>((val) =>
            {
                var results = Assert.IsType <VSReferenceItem[]>(val);
                Assert.Collection(results,
                                  a => AssertVSReferenceItem(expectedLocation1, a),
                                  b => AssertVSReferenceItem(expectedLocation2, b));
                progressReported = true;
            });
            var referenceRequest = new ReferenceParams()
            {
                TextDocument = new TextDocumentIdentifier()
                {
                    Uri = Uri
                },
                Position           = new Position(10, 5),
                PartialResultToken = progressToken
            };

            // Act
            var result = await referencesHandler.HandleRequestAsync(referenceRequest, new ClientCapabilities(), token, CancellationToken.None).ConfigureAwait(false);

            // Assert
            Assert.True(lspFarEndpointCalled);
            Assert.True(progressReported);
        }