Skip to content

Commit 840da46

Browse files
committed
Functioning tests and fixed selection issue
1 parent dfa7d6d commit 840da46

File tree

2 files changed

+87
-58
lines changed

2 files changed

+87
-58
lines changed

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/ExtractToNewComponentCodeActionProvider.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,13 @@ private static bool IsInsideProperHtmlContent(RazorCodeActionContext context, Ma
128128
}
129129

130130
var endOwner = syntaxTree.Root.FindInnermostNode(endLocation.Value.AbsoluteIndex, true);
131+
132+
// Correct selection to include the current node if the selection ends immediately after a closing tag.
133+
if (string.IsNullOrWhiteSpace(endOwner.ToFullString()) && endOwner.TryGetPreviousSibling(out var previousSibling))
134+
{
135+
endOwner = previousSibling;
136+
}
137+
131138
return endOwner?.FirstAncestorOrSelf<MarkupElementSyntax>();
132139
}
133140

src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/CodeActions/Razor/ExtractToNewComponentCodeActionProviderTest.cs

Lines changed: 80 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Test.CodeActions.Razor;
2929

3030
public class ExtractToNewComponentCodeActionProviderTest(ITestOutputHelper testOutput) : LanguageServerTestBase(testOutput)
3131
{
32-
[Fact (Skip = "Not fully set up yet")]
32+
[Fact]
3333
public async Task Handle_InvalidFileKind()
3434
{
3535
// Arrange
@@ -76,29 +76,29 @@ public async Task Handle_InvalidFileKind()
7676
Assert.Empty(commandOrCodeActionContainer);
7777
}
7878

79-
[Fact (Skip = "Incorrectly set up")]
80-
public async Task Handle_InProperMarkup_ReturnsNull()
79+
[Fact]
80+
public async Task Handle_SinglePointSelection_ReturnsNotEmpty()
8181
{
8282
// Arrange
83-
var documentPath = "c:/Test.razor";
83+
var documentPath = "c:/Test.cs";
8484
var contents = """
85-
page "/"
86-
85+
@page "/"
86+
8787
<PageTitle>Home</PageTitle>
88-
88+
8989
<div id="parent">
90-
<div>
90+
<$$div>
9191
<h1>Div a title</h1>
92-
<p>Div $$a par</p>
92+
<p>Div a par</p>
9393
</div>
9494
<div>
9595
<h1>Div b title</h1>
9696
<p>Div b par</p>
9797
</div>
98-
</div
99-
98+
</div>
99+
100100
<h1>Hello, world!</h1>
101-
101+
102102
Welcome to your new app.
103103
""";
104104
TestFileMarkupParser.GetPosition(contents, out contents, out var cursorPosition);
@@ -119,64 +119,81 @@ public async Task Handle_InProperMarkup_ReturnsNull()
119119
var commandOrCodeActionContainer = await provider.ProvideAsync(context, default);
120120

121121
// Assert
122-
Assert.Empty(commandOrCodeActionContainer);
122+
Assert.NotEmpty(commandOrCodeActionContainer);
123123
}
124124

125-
[Theory (Skip = "Incorrectly set up")]
126-
[InlineData("""
127-
<div id="parent">
128-
[|<div>
129-
<h1>Div a title</h1>
130-
<p>Div a par</p>
131-
</div>|]
132-
<div>
133-
<h1>Div b title</h1>
134-
<p>Div b par</p>
135-
</div>
136-
</div>
137-
""")]
138-
[InlineData("""
139-
<div id="parent">
140-
<div>
141-
<h1>Div a title</h1>
142-
[|<p>Div a par</p>|]
143-
</div>
144-
<div>
145-
<h1>Div b title</h1>
146-
<p>Div b par</p>
147-
</div>
148-
</div>
149-
""")]
150-
[InlineData("""
151-
<div id="parent">
152-
<div>
153-
<h1>Div a title</h1>
154-
[|<p>Div a par</p>
155-
</div>
156-
<div>
157-
<h1>Div b title</h1>
158-
<p>Div b par</p>|]
159-
</div>
160-
</div>
161-
""")]
162-
public async Task Handle_ValidElementSelection_ReturnsNotNull(string markupElementSelection)
125+
[Fact]
126+
public async Task Handle_MultiPointSelection_ReturnsNotEmpty()
163127
{
164128
// Arrange
165-
var documentPath = "c:/Test.razor";
166-
var contents = $$"""
167-
page "/"
129+
var documentPath = "c:/Test.cs";
130+
var contents = """
131+
@page "/"
168132
169133
<PageTitle>Home</PageTitle>
170134
171-
{{markupElementSelection}}
135+
<div id="parent">
136+
[|<div>
137+
$$<h1>Div a title</h1>
138+
<p>Div a par</p>
139+
</div>
140+
<div>
141+
<h1>Div b title</h1>
142+
<p>Div b par</p>
143+
</div|]>
144+
</div>
172145
173146
<h1>Hello, world!</h1>
174147
175148
Welcome to your new app.
176149
""";
150+
TestFileMarkupParser.GetPositionAndSpan(contents, out contents, out var cursorPosition, out var selectionSpan);
151+
152+
var request = new VSCodeActionParams()
153+
{
154+
TextDocument = new VSTextDocumentIdentifier { Uri = new Uri(documentPath) },
155+
Range = new Range(),
156+
Context = new VSInternalCodeActionContext()
157+
};
158+
159+
var location = new SourceLocation(cursorPosition, -1, -1);
160+
var context = CreateRazorCodeActionContext(request, location, documentPath, contents);
161+
162+
var provider = new ExtractToNewComponentCodeActionProvider(LoggerFactory);
177163

178-
TestFileMarkupParser.GetPositionAndSpans(
179-
contents, out contents, out int cursorPosition, out ImmutableArray<TextSpan> spans);
164+
// Act
165+
var commandOrCodeActionContainer = await provider.ProvideAsync(context, default);
166+
167+
// Assert
168+
Assert.NotEmpty(commandOrCodeActionContainer);
169+
}
170+
171+
[Fact]
172+
public async Task Handle_MultiPointSelectionWithEndAfterElement_ReturnsCurrentElement()
173+
{
174+
// Arrange
175+
var documentPath = "c:/Test.cs";
176+
var contents = """
177+
@page "/"
178+
179+
<PageTitle>Home</PageTitle>
180+
181+
<div id="parent">
182+
[|<div>
183+
$$<h1>Div a title</h1>
184+
<p>Div a par</p>
185+
</div>
186+
<div>
187+
<h1>Div b title</h1>
188+
<p>Div b par</p>
189+
</div>|]
190+
</div>
191+
192+
<h1>Hello, world!</h1>
193+
194+
Welcome to your new app.
195+
""";
196+
TestFileMarkupParser.GetPositionAndSpan(contents, out contents, out var cursorPosition, out var selectionSpan);
180197

181198
var request = new VSCodeActionParams()
182199
{
@@ -186,7 +203,7 @@ public async Task Handle_ValidElementSelection_ReturnsNotNull(string markupEleme
186203
};
187204

188205
var location = new SourceLocation(cursorPosition, -1, -1);
189-
var context = CreateRazorCodeActionContext(request, location, documentPath, contents, supportsFileCreation: true);
206+
var context = CreateRazorCodeActionContext(request, location, documentPath, contents);
190207

191208
var provider = new ExtractToNewComponentCodeActionProvider(LoggerFactory);
192209

@@ -195,6 +212,11 @@ public async Task Handle_ValidElementSelection_ReturnsNotNull(string markupEleme
195212

196213
// Assert
197214
Assert.NotEmpty(commandOrCodeActionContainer);
215+
var codeAction = Assert.Single(commandOrCodeActionContainer);
216+
var razorCodeActionResolutionParams = ((JsonElement)codeAction.Data!).Deserialize<RazorCodeActionResolutionParams>();
217+
Assert.NotNull(razorCodeActionResolutionParams);
218+
var actionParams = ((JsonElement)razorCodeActionResolutionParams.Data).Deserialize<ExtractToNewComponentCodeActionParams>();
219+
Assert.NotNull(actionParams);
198220
}
199221

200222
private static RazorCodeActionContext CreateRazorCodeActionContext(VSCodeActionParams request, SourceLocation location, string filePath, string text, bool supportsFileCreation = true)

0 commit comments

Comments
 (0)