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 @@ -55,9 +55,40 @@ Eat more chickin.
await VerifySpellCheckableRangesAsync(input);
}

private async Task VerifySpellCheckableRangesAsync(TestCode input)
[Fact]
public async Task ComponentAttributes()
{
await VerifySpellCheckableRangesAsync(
input: """
<SurveyPrompt Title="[|Hello|][| there|]" />
<SurveyPrompt @bind-Title="InputValue" />

<form @onsubmit="DoSubmit" required></form>

<input type="[|checkbox|]" checked></input>

@code
{
private string? [|InputValue|] { get; set; }
}
""",
additionalFiles: [
(FilePath("SurveyPrompt.razor"), """
@namespace SomeProject

<div></div>

@code
{
[Parameter]
public string Title { get; set; }
}
""")]);
}

private async Task VerifySpellCheckableRangesAsync(TestCode input, (string file, string contents)[]? additionalFiles = null)
{
var document = CreateProjectAndRazorDocument(input.Text);
var document = CreateProjectAndRazorDocument(input.Text, additionalFiles: additionalFiles);
var sourceText = await document.GetTextAsync(DisposalToken);

var endpoint = new CohostDocumentSpellCheckEndpoint(IncompatibleProjectService, RemoteServiceInvoker);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,25 @@ await VerifyOnTypeFormattingAsync(
html: true);
}

[Fact]
public async Task FormattingDisabled()
{
ClientSettingsManager.Update(ClientSettingsManager.GetClientSettings().AdvancedSettings with { FormatOnType = false });

await VerifyOnTypeFormattingAsync(
input: """
@{
if(true){}$$
}
""",
expected: """
@{
if(true){}
}
""",
triggerCharacter: '}');
}

private async Task VerifyOnTypeFormattingAsync(TestCode input, string expected, char triggerCharacter, bool html = false)
{
var document = CreateProjectAndRazorDocument(input.Text);
Expand All @@ -126,9 +145,7 @@ private async Task VerifyOnTypeFormattingAsync(TestCode input, string expected,
requestInvoker = StrictMock.Of<IHtmlRequestInvoker>();
}

var clientSettingsManager = new ClientSettingsManager(changeTriggers: []);

var endpoint = new CohostOnTypeFormattingEndpoint(IncompatibleProjectService, RemoteServiceInvoker, requestInvoker, clientSettingsManager, LoggerFactory);
var endpoint = new CohostOnTypeFormattingEndpoint(IncompatibleProjectService, RemoteServiceInvoker, requestInvoker, ClientSettingsManager, LoggerFactory);

var request = new DocumentOnTypeFormattingParams()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Test.Common;
Expand Down Expand Up @@ -99,7 +100,33 @@ private void M(string thisIsMyString)
}
""");

private async Task VerifyRangeFormattingAsync(TestCode input, string expected)
[Fact]
public async Task FormatOnPasteDisabled()
{
ClientSettingsManager.Update(ClientSettingsManager.GetClientSettings().AdvancedSettings with { FormatOnPaste = false });

await VerifyRangeFormattingAsync(
input: """
<div>
[|hello
<div>
</div>|]
</div>
""",
expected: """
<div>
hello
<div>
</div>
</div>
""",
otherOptions: new()
{
{ "fromPaste", true }
});
}

private async Task VerifyRangeFormattingAsync(TestCode input, string expected, Dictionary<string, SumType<bool, int, string>>? otherOptions = null)
{
var document = CreateProjectAndRazorDocument(input.Text);
var inputText = await document.GetTextAsync(DisposalToken);
Expand All @@ -114,23 +141,28 @@ private async Task VerifyRangeFormattingAsync(TestCode input, string expected)

var requestInvoker = new TestHtmlRequestInvoker([(Methods.TextDocumentFormattingName, htmlEdits)]);

var clientSettingsManager = new ClientSettingsManager(changeTriggers: []);

var endpoint = new CohostRangeFormattingEndpoint(IncompatibleProjectService, RemoteServiceInvoker, requestInvoker, clientSettingsManager, LoggerFactory);
var endpoint = new CohostRangeFormattingEndpoint(IncompatibleProjectService, RemoteServiceInvoker, requestInvoker, ClientSettingsManager, LoggerFactory);

var request = new DocumentRangeFormattingParams()
{
TextDocument = new TextDocumentIdentifier() { DocumentUri = document.CreateDocumentUri() },
Options = new FormattingOptions()
{
TabSize = 4,
InsertSpaces = true
InsertSpaces = true,
OtherOptions = otherOptions
},
Range = inputText.GetRange(input.Span)
};

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

if (edits is null or [])
{
Assert.Equal(input.Text, expected);
return;
}

var changes = edits.Select(inputText.GetTextChange);
var finalText = inputText.WithChanges(changes);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Test.Common;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using Xunit;
using Xunit.Abstractions;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
// 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 Microsoft.AspNetCore.Razor.Test.Common;
using Microsoft.CodeAnalysis.Razor.Formatting;
using Microsoft.VisualStudio.Razor.LanguageClient.Cohost;
using Microsoft.VisualStudio.Razor.LanguageClient.Cohost.Formatting;
using Xunit;
using Xunit.Abstractions;

namespace Microsoft.VisualStudio.LanguageServices.Razor.Test.Cohost.Formatting;

[Collection(HtmlFormattingCollection.Name)]
public class CascadingTypeParameterFormattingTest(FormattingTestContext context, HtmlFormattingFixture fixture, ITestOutputHelper testOutput)
: FormattingTestBase(context, fixture.Service, testOutput), IClassFixture<FormattingTestContext>
{
[FormattingTestFact]
[WorkItem("https://github.com/dotnet/razor-tooling/issues/5648")]
public async Task GenericComponentWithCascadingTypeParameter()
{
await RunFormattingTestAsync(
input: """
@page "/counter"

@if(true)
{
// indented
}

<TestGeneric Items="_items">
@foreach (var v in System.Linq.Enumerable.Range(1, 10))
{
<div></div>
}
</TestGeneric>

@if(true)
{
// indented
}

@code
{
private IEnumerable<int> _items = new[] { 1, 2, 3, 4, 5 };
}
""",
expected: """
@page "/counter"

@if (true)
{
// indented
}

<TestGeneric Items="_items">
@foreach (var v in System.Linq.Enumerable.Range(1, 10))
{
<div></div>
}
</TestGeneric>

@if (true)
{
// indented
}

@code
{
private IEnumerable<int> _items = new[] { 1, 2, 3, 4, 5 };
}
""");
}

[FormattingTestFact]
[WorkItem("https://github.com/dotnet/razor-tooling/issues/5648")]
public async Task GenericComponentWithCascadingTypeParameter_Nested()
{
await RunFormattingTestAsync(
input: """
@page "/counter"

<TestGeneric Items="_items">
@foreach (var v in System.Linq.Enumerable.Range(1, 10))
{
<div></div>
}
<TestGeneric Items="_items">
@foreach (var v in System.Linq.Enumerable.Range(1, 10))
{
<div></div>
}
</TestGeneric>
</TestGeneric>

@code
{
private IEnumerable<int> _items = new[] { 1, 2, 3, 4, 5 };
}
""",
expected: """
@page "/counter"

<TestGeneric Items="_items">
@foreach (var v in System.Linq.Enumerable.Range(1, 10))
{
<div></div>
}
<TestGeneric Items="_items">
@foreach (var v in System.Linq.Enumerable.Range(1, 10))
{
<div></div>
}
</TestGeneric>
</TestGeneric>

@code
{
private IEnumerable<int> _items = new[] { 1, 2, 3, 4, 5 };
}
""");
}

[FormattingTestFact]
[WorkItem("https://github.com/dotnet/razor-tooling/issues/5648")]
public async Task GenericComponentWithCascadingTypeParameter_MultipleParameters()
{
await RunFormattingTestAsync(
input: """
@page "/counter"

<TestGenericTwo Items="_items" ItemsTwo="_items2">
@foreach (var v in System.Linq.Enumerable.Range(1, 10))
{
<div></div>
}
</TestGenericTwo>

@code
{
private IEnumerable<int> _items = new[] { 1, 2, 3, 4, 5 };
private IEnumerable<long> _items2 = new long[] { 1, 2, 3, 4, 5 };
}
""",
expected: """
@page "/counter"

<TestGenericTwo Items="_items" ItemsTwo="_items2">
@foreach (var v in System.Linq.Enumerable.Range(1, 10))
{
<div></div>
}
</TestGenericTwo>

@code
{
private IEnumerable<int> _items = new[] { 1, 2, 3, 4, 5 };
private IEnumerable<long> _items2 = new long[] { 1, 2, 3, 4, 5 };
}
""");
}

private Task RunFormattingTestAsync(
TestCode input,
string expected)
{
return base.RunFormattingTestAsync(
input,
expected,
additionalFiles: [
(FilePath("TestGeneric.razor"), """
@using System.Collections.Generic
@using Microsoft.AspNetCore.Components
@typeparam TItem
@attribute [CascadingTypeParameter(nameof(TItem))]

<h3>TestGeneric</h3>

@code
{
[Parameter] public IEnumerable<TItem> Items { get; set; }
[Parameter] public RenderFragment ChildContent { get; set; }
}
"""),
(FilePath("TestGenericTwo.razor"), """
@using System.Collections.Generic
@using Microsoft.AspNetCore.Components
@typeparam TItem
@typeparam TItemTwo
@attribute [CascadingTypeParameter(nameof(TItem))]
@attribute [CascadingTypeParameter(nameof(TItemTwo))]

<h3>TestGeneric</h3>

@code
{
[Parameter] public IEnumerable<TItem> Items { get; set; }
[Parameter] public IEnumerable<TItemTwo> ItemsTwo { get; set; }
[Parameter] public RenderFragment ChildContent { get; set; }
}
""")]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@ private protected async Task RunFormattingTestAsync(
int tabSize = 4,
bool allowDiagnostics = false,
bool debugAssertsEnabled = true,
RazorCSharpSyntaxFormattingOptions? csharpSyntaxFormattingOptions = null)
RazorCSharpSyntaxFormattingOptions? csharpSyntaxFormattingOptions = null,
(string fileName, string contents)[]? additionalFiles = null)
{
(input, expected) = ProcessFormattingContext(input, expected);

var document = CreateProjectAndRazorDocument(input.Text, fileKind, inGlobalNamespace: inGlobalNamespace);
var document = CreateProjectAndRazorDocument(input.Text, fileKind, inGlobalNamespace: inGlobalNamespace, additionalFiles: additionalFiles);
if (!allowDiagnostics)
{
//TODO: Tests in LanguageServer have extra components that are not present in this project, like Counter, etc.
Expand Down
Loading