|
| 1 | +// Licensed to the .NET Foundation under one or more agreements. |
| 2 | +// The .NET Foundation licenses this file to you under the MIT license. |
| 3 | + |
| 4 | +using System; |
| 5 | +using System.Runtime.CompilerServices; |
| 6 | +using System.Threading; |
| 7 | +using System.Threading.Tasks; |
| 8 | +using Microsoft.AspNetCore.Razor; |
| 9 | +using Microsoft.AspNetCore.Razor.Test.Common.Editor; |
| 10 | +using Microsoft.AspNetCore.Razor.Test.Common.VisualStudio; |
| 11 | +using Microsoft.CodeAnalysis; |
| 12 | +using Microsoft.CodeAnalysis.ExternalAccess.Razor; |
| 13 | +using Microsoft.CodeAnalysis.Razor; |
| 14 | +using Microsoft.CodeAnalysis.Razor.Remote; |
| 15 | +using Microsoft.CodeAnalysis.Razor.Telemetry; |
| 16 | +using Microsoft.CodeAnalysis.Text; |
| 17 | +using Xunit; |
| 18 | +using Xunit.Abstractions; |
| 19 | + |
| 20 | +namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost; |
| 21 | + |
| 22 | +public class HtmlRequestInvokerTest(ITestOutputHelper testOutput) : VisualStudioWorkspaceTestBase(testOutput) |
| 23 | +{ |
| 24 | + private DocumentId? _documentId; |
| 25 | + |
| 26 | + protected override void ConfigureWorkspace(AdhocWorkspace workspace) |
| 27 | + { |
| 28 | + var project = workspace.CurrentSolution.AddProject("Project", "Project.dll", LanguageNames.CSharp); |
| 29 | + var document = project.AddAdditionalDocument("File.razor", SourceText.From("<div></div>"), filePath: "file://File.razor"); |
| 30 | + _documentId = document.Id; |
| 31 | + |
| 32 | + Assert.True(workspace.TryApplyChanges(document.Project.Solution)); |
| 33 | + } |
| 34 | + |
| 35 | + [Fact] |
| 36 | + public async Task DiagnosticsRequest_UpdatesUri() |
| 37 | + { |
| 38 | + var document = Workspace.CurrentSolution.GetAdditionalDocument(_documentId).AssumeNotNull(); |
| 39 | + |
| 40 | + var htmlDocumentUri = new Uri("file://File.razor.html", UriKind.Absolute); |
| 41 | + var requestValidator = (object request) => |
| 42 | + { |
| 43 | + var diagnosticParams = Assert.IsType<VSInternalDiagnosticParams>(request); |
| 44 | + Assert.Equal(htmlDocumentUri, diagnosticParams.TextDocument!.DocumentUri.GetRequiredParsedUri()); |
| 45 | + }; |
| 46 | + |
| 47 | + var diagnosticRequest = new VSInternalDiagnosticParams |
| 48 | + { |
| 49 | + TextDocument = new TextDocumentIdentifier { DocumentUri = document.CreateDocumentUri() } |
| 50 | + }; |
| 51 | + |
| 52 | + await MakeHtmlRequestAsync(document, htmlDocumentUri, requestValidator, VSInternalMethods.DocumentPullDiagnosticName, diagnosticRequest); |
| 53 | + |
| 54 | + Assert.Equal(document.CreateDocumentUri(), diagnosticRequest.TextDocument!.DocumentUri); |
| 55 | + } |
| 56 | + |
| 57 | + [Fact] |
| 58 | + public async Task ITextDocumentParamsRequest_UpdatesUri() |
| 59 | + { |
| 60 | + var document = Workspace.CurrentSolution.GetAdditionalDocument(_documentId).AssumeNotNull(); |
| 61 | + |
| 62 | + var htmlDocumentUri = new Uri("file://File.razor.html", UriKind.Absolute); |
| 63 | + var requestValidator = (object request) => |
| 64 | + { |
| 65 | + var hoverParams = Assert.IsAssignableFrom<ITextDocumentParams>(request); |
| 66 | + Assert.Equal(htmlDocumentUri, hoverParams.TextDocument!.DocumentUri.GetRequiredParsedUri()); |
| 67 | + }; |
| 68 | + |
| 69 | + var hoverRequest = new HoverParams |
| 70 | + { |
| 71 | + TextDocument = new TextDocumentIdentifier { DocumentUri = document.CreateDocumentUri() } |
| 72 | + }; |
| 73 | + |
| 74 | + await MakeHtmlRequestAsync(document, htmlDocumentUri, requestValidator, Methods.TextDocumentHoverName, hoverRequest); |
| 75 | + |
| 76 | + Assert.Equal(document.CreateDocumentUri(), hoverRequest.TextDocument!.DocumentUri); |
| 77 | + } |
| 78 | + |
| 79 | + private async Task MakeHtmlRequestAsync<TRequest>(TextDocument document, Uri htmlDocumentUri, Action<object> requestValidator, string method, TRequest request) |
| 80 | + where TRequest : notnull |
| 81 | + { |
| 82 | + var htmlTextSnapshot = new StringTextSnapshot(""); |
| 83 | + var htmlTextBuffer = new TestTextBuffer(htmlTextSnapshot); |
| 84 | + var checksum = await document.GetChecksumAsync(DisposalToken); |
| 85 | + var requestInvoker = new TestLSPRequestInvoker((method, null)); |
| 86 | + var lspDocumentManager = new TestDocumentManager(); |
| 87 | + var htmlVirtualDocument = new HtmlVirtualDocumentSnapshot(htmlDocumentUri, htmlTextBuffer.CurrentSnapshot, hostDocumentSyncVersion: 1, state: checksum); |
| 88 | + var documentSnapshot = new TestLSPDocumentSnapshot(document.CreateUri(), version: (int)(htmlVirtualDocument.HostDocumentSyncVersion!.Value + 1), htmlVirtualDocument); |
| 89 | + lspDocumentManager.AddDocument(documentSnapshot.Uri, documentSnapshot); |
| 90 | + |
| 91 | + var publisher = new TestHtmlDocumentPublisher(); |
| 92 | + var remoteServiceInvoker = new RemoteServiceInvoker(); |
| 93 | + var htmlDocumentSynchronizer = new HtmlDocumentSynchronizer(remoteServiceInvoker, publisher, LoggerFactory); |
| 94 | + var invoker = new HtmlRequestInvoker(requestInvoker, lspDocumentManager, htmlDocumentSynchronizer, NoOpTelemetryReporter.Instance, LoggerFactory); |
| 95 | + |
| 96 | + var validated = false; |
| 97 | + requestInvoker.RequestAction = r => |
| 98 | + { |
| 99 | + validated = true; |
| 100 | + requestValidator(r); |
| 101 | + }; |
| 102 | + |
| 103 | + _ = await invoker.MakeHtmlLspRequestAsync<TRequest, object>( |
| 104 | + document, |
| 105 | + method, |
| 106 | + request, |
| 107 | + DisposalToken); |
| 108 | + |
| 109 | + Assert.True(validated); |
| 110 | + } |
| 111 | + |
| 112 | + private class RemoteServiceInvoker : IRemoteServiceInvoker |
| 113 | + { |
| 114 | + public ValueTask<TResult?> TryInvokeAsync<TService, TResult>(Solution solution, Func<TService, RazorPinnedSolutionInfoWrapper, CancellationToken, ValueTask<TResult>> invocation, CancellationToken cancellationToken, [CallerFilePath] string? callerFilePath = null, [CallerMemberName] string? callerMemberName = null) where TService : class |
| 115 | + { |
| 116 | + return new((TResult?)(object)""); |
| 117 | + } |
| 118 | + } |
| 119 | +} |
0 commit comments