Skip to content

Commit 9162078

Browse files
committed
Add failing test to ensure add using is offered first
Currently its "Extract to New Component" which is annoying, and unlikely to be correct IMO
1 parent 54a350d commit 9162078

File tree

2 files changed

+65
-34
lines changed

2 files changed

+65
-34
lines changed

src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CodeActions/CohostCodeActionsEndpointTestBase.cs

Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,25 @@ namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost.CodeActions;
3131
public abstract class CohostCodeActionsEndpointTestBase(ITestOutputHelper testOutputHelper) : CohostEndpointTestBase(testOutputHelper)
3232
{
3333
private protected async Task VerifyCodeActionAsync(TestCode input, string? expected, string codeActionName, int childActionIndex = 0, string? fileKind = null, (string filePath, string contents)[]? additionalFiles = null, (Uri fileUri, string contents)[]? additionalExpectedFiles = null)
34+
{
35+
var document = CreateRazorDocument(input, fileKind, additionalFiles);
36+
37+
var codeAction = await VerifyCodeActionRequestAsync(document, input, codeActionName, childActionIndex, expectOffer: expected is not null);
38+
39+
if (codeAction is null)
40+
{
41+
Assert.Null(expected);
42+
return;
43+
}
44+
45+
var workspaceEdit = codeAction.Data is null
46+
? codeAction.Edit.AssumeNotNull()
47+
: await ResolveCodeActionAsync(document, codeAction);
48+
49+
await VerifyCodeActionResultAsync(document, workspaceEdit, expected, additionalExpectedFiles);
50+
}
51+
52+
private protected TextDocument CreateRazorDocument(TestCode input, string? fileKind = null, (string filePath, string contents)[]? additionalFiles = null)
3453
{
3554
var fileSystem = (RemoteFileSystem)OOPExportProvider.GetExportedValue<IFileSystem>();
3655
fileSystem.GetTestAccessor().SetFileSystem(new TestFileSystem(additionalFiles));
@@ -49,23 +68,42 @@ private protected async Task VerifyCodeActionAsync(TestCode input, string? expec
4968
});
5069

5170
var document = CreateProjectAndRazorDocument(input.Text, fileKind, createSeparateRemoteAndLocalWorkspaces: true, additionalFiles: additionalFiles);
71+
return document;
72+
}
5273

53-
var codeAction = await VerifyCodeActionRequestAsync(document, input, codeActionName, childActionIndex, expectOffer: expected is not null);
74+
private async Task<CodeAction?> VerifyCodeActionRequestAsync(TextDocument document, TestCode input, string codeActionName, int childActionIndex, bool expectOffer)
75+
{
76+
var result = await GetCodeActionsAsync(document, input);
77+
if (result is null)
78+
{
79+
return null;
80+
}
5481

55-
if (codeAction is null)
82+
var codeActionToRun = (VSInternalCodeAction?)result.SingleOrDefault(e => ((RazorVSInternalCodeAction)e.Value!).Name == codeActionName).Value;
83+
84+
if (!expectOffer)
5685
{
57-
Assert.Null(expected);
58-
return;
86+
Assert.Null(codeActionToRun);
87+
return null;
5988
}
6089

61-
var workspaceEdit = codeAction.Data is null
62-
? codeAction.Edit.AssumeNotNull()
63-
: await ResolveCodeActionAsync(document, codeAction);
90+
AssertEx.NotNull(codeActionToRun, $"""
91+
Could not find code action with name '{codeActionName}'.
6492
65-
await VerifyCodeActionResultAsync(document, workspaceEdit, expected, additionalExpectedFiles);
93+
Available:
94+
{string.Join(Environment.NewLine + " ", result.Select(e => ((RazorVSInternalCodeAction)e.Value!).Name))}
95+
""");
96+
97+
if (codeActionToRun.Children?.Length > 0)
98+
{
99+
codeActionToRun = codeActionToRun.Children[childActionIndex];
100+
}
101+
102+
Assert.NotNull(codeActionToRun);
103+
return codeActionToRun;
66104
}
67105

68-
private async Task<CodeAction?> VerifyCodeActionRequestAsync(TextDocument document, TestCode input, string codeActionName, int childActionIndex, bool expectOffer)
106+
private protected async Task<SumType<Command, CodeAction>[]?> GetCodeActionsAsync(TextDocument document, TestCode input)
69107
{
70108
var requestInvoker = new TestLSPRequestInvoker();
71109
var endpoint = new CohostCodeActionsEndpoint(RemoteServiceInvoker, ClientCapabilitiesService, TestHtmlDocumentSynchronizer.Instance, requestInvoker, NoOpTelemetryReporter.Instance);
@@ -107,37 +145,13 @@ private protected async Task VerifyCodeActionAsync(TestCode input, string? expec
107145
}
108146

109147
var result = await endpoint.GetTestAccessor().HandleRequestAsync(document, request, DisposalToken);
110-
111148
if (result is null)
112149
{
113150
return null;
114151
}
115152

116-
Assert.NotNull(result);
117153
Assert.NotEmpty(result);
118-
119-
var codeActionToRun = (VSInternalCodeAction?)result.SingleOrDefault(e => ((RazorVSInternalCodeAction)e.Value!).Name == codeActionName).Value;
120-
121-
if (!expectOffer)
122-
{
123-
Assert.Null(codeActionToRun);
124-
return null;
125-
}
126-
127-
AssertEx.NotNull(codeActionToRun, $"""
128-
Could not find code action with name '{codeActionName}'.
129-
130-
Available:
131-
{string.Join(Environment.NewLine + " ", result.Select(e => ((RazorVSInternalCodeAction)e.Value!).Name))}
132-
""");
133-
134-
if (codeActionToRun.Children?.Length > 0)
135-
{
136-
codeActionToRun = codeActionToRun.Children[childActionIndex];
137-
}
138-
139-
Assert.NotNull(codeActionToRun);
140-
return codeActionToRun;
154+
return result;
141155
}
142156

143157
private async Task VerifyCodeActionResultAsync(TextDocument document, WorkspaceEdit workspaceEdit, string? expected, (Uri fileUri, string contents)[]? additionalExpectedFiles = null)

src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CodeActions/TypeAccessibilityTests.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the MIT license. See License.txt in the project root for license information.
33

4+
using System.Linq;
45
using System.Threading.Tasks;
6+
using Microsoft.CodeAnalysis.Razor.CodeActions.Models;
57
using Microsoft.CodeAnalysis.Razor.Protocol;
68
using Xunit;
79
using Xunit.Abstractions;
@@ -79,4 +81,19 @@ @using Microsoft.AspNetCore.Components.Sections
7981
""",
8082
codeActionName: LanguageServerConstants.CodeActions.AddUsing);
8183
}
84+
85+
[Fact]
86+
public async Task AddUsingShouldBeFirst()
87+
{
88+
var input = """
89+
<div></div>
90+
91+
<Section[||]Outlet></SectionOutlet>
92+
""";
93+
94+
var document = CreateRazorDocument(input);
95+
var codeActions = await GetCodeActionsAsync(document, input);
96+
97+
Assert.Equal(LanguageServerConstants.CodeActions.AddUsing, codeActions.Select(a => ((RazorVSInternalCodeAction)a.Value!).Name).First());
98+
}
8299
}

0 commit comments

Comments
 (0)