Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,13 @@ public ImmutableArray<Registration> GetRegistrations(VSInternalClientCapabilitie
ResultId = Guid.NewGuid().ToString()
};
}

internal TestAccessor GetTestAccessor() => new(this);

internal readonly struct TestAccessor(DocumentPullDiagnosticsEndpoint instance)
{
public Task<LspDiagnostic[]?> HandleRequestAsync(TextDocument razorDocument, CancellationToken cancellationToken)
=> instance.GetDiagnosticsAsync(razorDocument, cancellationToken);
}
}

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.LanguageServer.Test;
Expand All @@ -12,68 +11,11 @@
using Microsoft.VisualStudio.Razor.Settings;
using Roslyn.Test.Utilities;
using Xunit;
using Xunit.Abstractions;

namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost;

public class CohostDocumentPullDiagnosticsTest(ITestOutputHelper testOutputHelper) : CohostEndpointTestBase(testOutputHelper)
public partial class CohostDocumentPullDiagnosticsTest
{
[Fact]
public Task NoDiagnostics()
=> VerifyDiagnosticsAsync("""
<div></div>

@code
{
public void IJustMetYou()
{
}
}
""");

[Fact]
public Task CSharp()
=> VerifyDiagnosticsAsync("""
<div></div>

@code
{
public void IJustMetYou()
{
{|CS0103:CallMeMaybe|}();
}
}
""");

[Fact]
public Task Razor()
=> VerifyDiagnosticsAsync("""
<div>

{|RZ10012:<NonExistentComponent />|}

</div>
""");

[Fact]
public Task CSharpAndRazor_MiscellaneousFile()
=> VerifyDiagnosticsAsync("""
<div>

{|RZ10012:<NonExistentComponent />|}

</div>

@code
{
public void IJustMetYou()
{
{|CS0103:CallMeMaybe|}();
}
}
""",
miscellaneousFile: true);

[Fact]
public Task Html()
{
Expand Down Expand Up @@ -449,34 +391,6 @@ Task Send() =>
}]);
}

[Fact]
public Task CombinedAndNestedDiagnostics()
=> VerifyDiagnosticsAsync("""
@using System.Threading.Tasks;

<div>

{|RZ10012:<NonExistentComponent />|}

@code
{
public void IJustMetYou()
{
{|CS0103:CallMeMaybe|}();
}
}

<div>
@{
{|CS4033:await Task.{|CS1501:Delay|}()|};
}

{|RZ9980:<p>|}
</div>

</div>
""");

[Fact]
public Task TODOComments()
=> VerifyDiagnosticsAsync("""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,16 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Classification;
using Microsoft.CodeAnalysis.Razor.Tooltip;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Text.Adornments;
using Xunit;

namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost;

internal static class HoverAssertions
{
public static async Task VerifyRangeAsync(this Hover hover, TextSpan expected, TextDocument document)
{
var text = await document.GetTextAsync();
Assert.NotNull(hover.Range);
Assert.Equal(text.GetLinePositionSpan(expected), hover.Range.ToLinePositionSpan());
}

public static void VerifyRawContent(this Hover hover, Action<object?> verifier)
public static void VerifyContents(this LspHover hover, Action<object?> verifier)
{
var vsHover = Assert.IsType<VSInternalHover>(hover);
verifier(vsHover.RawContent);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Test.Common;
using Microsoft.CodeAnalysis.Razor.Telemetry;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Xunit;

namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost;

public partial class CohostDocumentPullDiagnosticsTest
{
private async Task VerifyDiagnosticsAsync(TestCode input, VSInternalDiagnosticReport[]? htmlResponse = null, bool miscellaneousFile = false)
{
var document = CreateProjectAndRazorDocument(input.Text, miscellaneousFile: miscellaneousFile);
var inputText = await document.GetTextAsync(DisposalToken);

var requestInvoker = new TestHtmlRequestInvoker([(VSInternalMethods.DocumentPullDiagnosticName, htmlResponse)]);

var endpoint = new DocumentPullDiagnosticsEndpoint(IncompatibleProjectService, RemoteServiceInvoker, requestInvoker, ClientCapabilitiesService, NoOpTelemetryReporter.Instance, LoggerFactory);

var result = await endpoint.GetTestAccessor().HandleRequestAsync(document, DisposalToken);

Assert.NotNull(result);

var markers = result.SelectMany(d =>
new[] {
(index: inputText.GetTextSpan(d.Range).Start, text: $"{{|{d.Code!.Value.Second}:"),
(index: inputText.GetTextSpan(d.Range).End, text:"|}")
});

var testOutput = input.Text;
// Ordering by text last means start tags get sorted before end tags, for zero width ranges
foreach (var (index, text) in markers.OrderByDescending(i => i.index).ThenByDescending(i => i.text))
{
testOutput = testOutput.Insert(index, text);
}

AssertEx.EqualOrDiff(input.OriginalInput, testOutput);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;

namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost;

public partial class CohostDocumentPullDiagnosticsTest(ITestOutputHelper testOutputHelper) : CohostEndpointTestBase(testOutputHelper)
{
[Fact]
public Task NoDiagnostics()
=> VerifyDiagnosticsAsync("""
<div></div>

@code
{
public void IJustMetYou()
{
}
}
""");

[Fact]
public Task CSharp()
=> VerifyDiagnosticsAsync("""
<div></div>

@code
{
public void IJustMetYou()
{
{|CS0103:CallMeMaybe|}();
}
}
""");

[Fact]
public Task Razor()
=> VerifyDiagnosticsAsync("""
<div>

{|RZ10012:<NonExistentComponent />|}

</div>
""");

[Fact]
public Task CSharpAndRazor_MiscellaneousFile()
=> VerifyDiagnosticsAsync("""
<div>

{|RZ10012:<NonExistentComponent />|}

</div>

@code
{
public void IJustMetYou()
{
{|CS0103:CallMeMaybe|}();
}
}
""",
miscellaneousFile: true);

[Fact]
public Task CombinedAndNestedDiagnostics()
=> VerifyDiagnosticsAsync("""
@using System.Threading.Tasks;

<div>

{|RZ10012:<NonExistentComponent />|}

@code
{
public void IJustMetYou()
{
{|CS0103:CallMeMaybe|}();
}
}

<div>
@{
{|CS4033:await Task.{|CS1501:Delay|}()|};
}

{|RZ9980:<p>|}
</div>

</div>
""");
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ public async Task Razor()

await VerifyHoverAsync(code, async (hover, document) =>
{
await hover.VerifyRangeAsync(code.Span, document);
await VerifyRangeAsync(hover, code.Span, document);

hover.VerifyRawContent(
hover.VerifyContents(
Container(
Container(
Image,
Expand Down Expand Up @@ -109,9 +109,9 @@ public async Task CSharp()

await VerifyHoverAsync(code, async (hover, document) =>
{
await hover.VerifyRangeAsync(code.Span, document);
await VerifyRangeAsync(hover, code.Span, document);

hover.VerifyRawContent(
hover.VerifyContents(
Container(
Container(
Image,
Expand Down Expand Up @@ -139,9 +139,9 @@ public async Task ComponentAttribute()

await VerifyHoverAsync(code, async (hover, document) =>
{
await hover.VerifyRangeAsync(code.Span, document);
await VerifyRangeAsync(hover, code.Span, document);

hover.VerifyRawContent(
hover.VerifyContents(
Container(
Container(
Image,
Expand Down Expand Up @@ -184,9 +184,9 @@ private void Foo()

await VerifyHoverAsync(code, async (hover, document) =>
{
await hover.VerifyRangeAsync(code.Span, document);
await VerifyRangeAsync(hover, code.Span, document);

hover.VerifyRawContent(
hover.VerifyContents(
Container(
Container(
Image,
Expand Down Expand Up @@ -221,9 +221,9 @@ public async Task ComponentEndTag()

await VerifyHoverAsync(code, async (hover, document) =>
{
await hover.VerifyRangeAsync(code.Span, document);
await VerifyRangeAsync(hover, code.Span, document);

hover.VerifyRawContent(
hover.VerifyContents(
Container(
Container(
Image,
Expand Down Expand Up @@ -258,9 +258,9 @@ public async Task ComponentEndTag_FullyQualified()

await VerifyHoverAsync(code, async (hover, document) =>
{
await hover.VerifyRangeAsync(code.Span, document);
await VerifyRangeAsync(hover, code.Span, document);

hover.VerifyRawContent(
hover.VerifyContents(
Container(
Container(
Image,
Expand Down Expand Up @@ -295,9 +295,9 @@ public async Task ComponentEndTag_FullyQualified_Namespace()

await VerifyHoverAsync(code, async (hover, document) =>
{
await hover.VerifyRangeAsync(code.Span, document);
await VerifyRangeAsync(hover, code.Span, document);

hover.VerifyRawContent(
hover.VerifyContents(
Container(
Container(
Image,
Expand Down Expand Up @@ -344,4 +344,11 @@ private async Task VerifyHoverAsync(TestCode input, Hover htmlResponse, Action<H

return await endpoint.GetTestAccessor().HandleRequestAsync(textDocumentPositionParams, document, DisposalToken);
}

private static async Task VerifyRangeAsync(Hover hover, TextSpan expected, TextDocument document)
{
var text = await document.GetTextAsync();
Assert.NotNull(hover.Range);
Assert.Equal(text.GetLinePositionSpan(expected), hover.Range.ToLinePositionSpan());
}
}
Loading