9
9
using System . Linq ;
10
10
using System . Threading ;
11
11
using System . Threading . Tasks ;
12
- using Castle . Core . Logging ;
13
12
using Microsoft . AspNetCore . Razor . Language ;
14
13
using Microsoft . AspNetCore . Razor . Language . Components ;
15
14
using Microsoft . AspNetCore . Razor . LanguageServer . CodeActions . Models ;
16
15
using Microsoft . AspNetCore . Razor . LanguageServer . CodeActions . Razor ;
17
16
using Microsoft . AspNetCore . Razor . LanguageServer . EndpointContracts ;
18
17
using Microsoft . AspNetCore . Razor . LanguageServer . Formatting ;
19
18
using Microsoft . AspNetCore . Razor . LanguageServer . Hosting ;
20
- using Microsoft . AspNetCore . Razor . LanguageServer . Test ;
21
19
using Microsoft . AspNetCore . Razor . ProjectSystem ;
20
+ using Microsoft . AspNetCore . Razor . Test . Common ;
22
21
using Microsoft . AspNetCore . Razor . Test . Common . LanguageServer ;
23
22
using Microsoft . AspNetCore . Razor . Test . Common . ProjectSystem ;
24
23
using Microsoft . AspNetCore . Razor . Test . Common . Workspaces ;
25
24
using Microsoft . AspNetCore . Razor . Utilities ;
26
25
using Microsoft . CodeAnalysis . ExternalAccess . Razor ;
27
26
using Microsoft . CodeAnalysis . Razor ;
27
+ using Microsoft . CodeAnalysis . Razor . DocumentMapping ;
28
28
using Microsoft . CodeAnalysis . Razor . ProjectSystem ;
29
29
using Microsoft . CodeAnalysis . Razor . Protocol ;
30
30
using Microsoft . CodeAnalysis . Razor . Protocol . CodeActions ;
31
31
using Microsoft . CodeAnalysis . Razor . Workspaces ;
32
32
using Microsoft . CodeAnalysis . Testing ;
33
33
using Microsoft . CodeAnalysis . Text ;
34
+ using Microsoft . VisualStudio . Copilot . Internal ;
34
35
using Microsoft . VisualStudio . LanguageServer . Protocol ;
36
+ using Moq ;
35
37
using Roslyn . Test . Utilities ;
36
38
using Xunit ;
37
39
using Xunit . Abstractions ;
38
- using static Microsoft . AspNetCore . Razor . LanguageServer . Formatting . FormattingLanguageServerTestBase ;
40
+ using Xunit . Sdk ;
39
41
40
42
namespace Microsoft . AspNetCore . Razor . LanguageServer . CodeActions ;
41
43
@@ -64,26 +66,27 @@ private GenerateMethodCodeActionResolver[] CreateRazorCodeActionResolvers(
64
66
razorFormattingService )
65
67
] ;
66
68
67
- // TODO: Make this func
68
- //private ExtractToComponentCodeActionResolver[] CreateExtractComponentCodeActionResolvers(string filePath, RazorCodeDocument codeDocument)
69
- //{
70
- // var emptyDocumentContextFactory = new TestDocumentContextFactory();
71
- // var languageServer = new Test.TestLanguageServer(new Dictionary<string, Func<object?, Task<object>>>()
72
- // {
73
- // [CustomMessageNames.RazorFormatNewFileEndpointName] = c => Task.FromResult<object>(null!),
74
- // });
75
- // var razorLSPOptionsMonitor = TestRazorLSPOptionsMonitor.Create();
76
- // var testFormattingService = await TestRazorFormattingService.CreateWithFullSupportAsync(LoggerFactory);
77
- //return [
78
- // new ExtractToComponentCodeActionResolver(
79
- // new GenerateMethodResolverDocumentContextFactory(filePath, codeDocument),
80
- // razorLSPOptionsMonitor,
81
- // TestLanguageServerFeatureOptions.Instance,
82
- // languageServer,
83
- // testFormattingService,
84
- // new DocumentVersionCacheTest())
85
- // ];
86
- //}
69
+ private ExtractToComponentCodeActionResolver [ ] CreateExtractComponentCodeActionResolver (
70
+ string filePath ,
71
+ RazorCodeDocument codeDocument ,
72
+ IRazorFormattingService razorFormattingService ,
73
+ IClientConnection clientConnection ,
74
+ RazorLSPOptionsMonitor ? optionsMonitor = null )
75
+ {
76
+ var projectManager = new StrictMock < IDocumentVersionCache > ( ) ;
77
+ int ? version = 1 ;
78
+ projectManager . Setup ( x => x . TryGetDocumentVersion ( It . IsAny < IDocumentSnapshot > ( ) , out version ) ) . Returns ( true ) ;
79
+
80
+ return [
81
+ new ExtractToComponentCodeActionResolver (
82
+ new GenerateMethodResolverDocumentContextFactory ( filePath , codeDocument ) ,
83
+ optionsMonitor ?? TestRazorLSPOptionsMonitor . Create ( ) ,
84
+ TestLanguageServerFeatureOptions . Instance ,
85
+ clientConnection ,
86
+ razorFormattingService ,
87
+ projectManager . Object )
88
+ ] ;
89
+ }
87
90
88
91
#region CSharp CodeAction Tests
89
92
@@ -1032,7 +1035,7 @@ await ValidateCodeActionAsync(input,
1032
1035
}
1033
1036
1034
1037
[ Fact ]
1035
- public async Task Handle_ExtractComponent ( )
1038
+ public async Task Handle_ExtractComponent_SingleElement_ReturnsResult ( )
1036
1039
{
1037
1040
var input = """
1038
1041
<[||]div id="a">
@@ -1053,12 +1056,115 @@ public async Task Handle_ExtractComponent()
1053
1056
</div>
1054
1057
""" ;
1055
1058
1056
- //await ValidateExtractComponentCodeActionAsync(
1057
- // input,
1058
- // expectedRazorComponent,
1059
- // ExtractToComponentTitle,
1060
- // razorCodeActionProviders: [new ExtractToComponentCodeActionProvider(LoggerFactory)],
1061
- // codeActionResolversCreator: CreateExtractComponentCodeActionResolvers);
1059
+ await ValidateExtractComponentCodeActionAsync (
1060
+ input ,
1061
+ expectedRazorComponent ,
1062
+ ExtractToComponentTitle ,
1063
+ razorCodeActionProviders : [ new ExtractToComponentCodeActionProvider ( LoggerFactory ) ] ,
1064
+ codeActionResolversCreator : CreateExtractComponentCodeActionResolver ) ;
1065
+ }
1066
+
1067
+ [ Fact ]
1068
+ public async Task Handle_ExtractComponent_SiblingElement_ReturnsResult ( )
1069
+ {
1070
+ var input = """
1071
+ <[|div id="a">
1072
+ <h1>Div a title</h1>
1073
+ <Book Title="To Kill a Mockingbird" Author="Harper Lee" Year="Long ago" />
1074
+ <p>Div a par</p>
1075
+ </div>
1076
+ <div id="b">
1077
+ <Movie Title="Aftersun" Director="Charlotte Wells" Year="2022" />
1078
+ </div|]>
1079
+ """ ;
1080
+
1081
+ var expectedRazorComponent = """
1082
+ <div id="a">
1083
+ <h1>Div a title</h1>
1084
+ <Book Title="To Kill a Mockingbird" Author="Harper Lee" Year="Long ago" />
1085
+ <p>Div a par</p>
1086
+ </div>
1087
+ <div id="b">
1088
+ <Movie Title="Aftersun" Director="Charlotte Wells" Year="2022" />
1089
+ </div>
1090
+ """ ;
1091
+
1092
+ await ValidateExtractComponentCodeActionAsync (
1093
+ input ,
1094
+ expectedRazorComponent ,
1095
+ ExtractToComponentTitle ,
1096
+ razorCodeActionProviders : [ new ExtractToComponentCodeActionProvider ( LoggerFactory ) ] ,
1097
+ codeActionResolversCreator : CreateExtractComponentCodeActionResolver ) ;
1098
+ }
1099
+
1100
+ [ Fact ]
1101
+ public async Task Handle_ExtractComponent_StartNodeContainsEndNode_ReturnsResult ( )
1102
+ {
1103
+ var input = """
1104
+ <[|div id="parent">
1105
+ <div>
1106
+ <div>
1107
+ <div>
1108
+ <p>Deeply nested par</p|]>
1109
+ </div>
1110
+ </div>
1111
+ </div>
1112
+ </div>
1113
+ """ ;
1114
+
1115
+ var expectedRazorComponent = """
1116
+ <div id="parent">
1117
+ <div>
1118
+ <div>
1119
+ <div>
1120
+ <p>Deeply nested par</p>
1121
+ </div>
1122
+ </div>
1123
+ </div>
1124
+ </div>
1125
+ """ ;
1126
+
1127
+ await ValidateExtractComponentCodeActionAsync (
1128
+ input ,
1129
+ expectedRazorComponent ,
1130
+ ExtractToComponentTitle ,
1131
+ razorCodeActionProviders : [ new ExtractToComponentCodeActionProvider ( LoggerFactory ) ] ,
1132
+ codeActionResolversCreator : CreateExtractComponentCodeActionResolver ) ;
1133
+ }
1134
+
1135
+ [ Fact ]
1136
+ public async Task Handle_ExtractComponent_EndNodeContainsStartNode_ReturnsResult ( )
1137
+ {
1138
+ var input = """
1139
+ <div id="parent">
1140
+ <div>
1141
+ <div>
1142
+ <div>
1143
+ <[|p>Deeply nested par</p>
1144
+ </div>
1145
+ </div>
1146
+ </div>
1147
+ </div|]>
1148
+ """ ;
1149
+
1150
+ var expectedRazorComponent = """
1151
+ <div id="parent">
1152
+ <div>
1153
+ <div>
1154
+ <div>
1155
+ <p>Deeply nested par</p>
1156
+ </div>
1157
+ </div>
1158
+ </div>
1159
+ </div>
1160
+ """ ;
1161
+
1162
+ await ValidateExtractComponentCodeActionAsync (
1163
+ input ,
1164
+ expectedRazorComponent ,
1165
+ ExtractToComponentTitle ,
1166
+ razorCodeActionProviders : [ new ExtractToComponentCodeActionProvider ( LoggerFactory ) ] ,
1167
+ codeActionResolversCreator : CreateExtractComponentCodeActionResolver ) ;
1062
1168
}
1063
1169
1064
1170
#endregion
@@ -1210,13 +1316,13 @@ private async Task ValidateExtractComponentCodeActionAsync(
1210
1316
string codeAction ,
1211
1317
int childActionIndex = 0 ,
1212
1318
IRazorCodeActionProvider [ ] ? razorCodeActionProviders = null ,
1213
- Func < string , RazorCodeDocument , IRazorCodeActionResolver [ ] > ? codeActionResolversCreator = null ,
1319
+ Func < string , RazorCodeDocument , IRazorFormattingService , IClientConnection , RazorLSPOptionsMonitor ? , IRazorCodeActionResolver [ ] > ? codeActionResolversCreator = null ,
1214
1320
RazorLSPOptionsMonitor ? optionsMonitor = null ,
1215
1321
Diagnostic [ ] ? diagnostics = null )
1216
1322
{
1217
1323
TestFileMarkupParser . GetSpan ( input , out input , out var textSpan ) ;
1218
1324
1219
- var razorFilePath = "C:/path/test .razor" ;
1325
+ var razorFilePath = "C:/path/Test .razor" ;
1220
1326
var componentFilePath = "C:/path/Component.razor" ;
1221
1327
var codeDocument = CreateCodeDocument ( input , filePath : razorFilePath ) ;
1222
1328
var sourceText = codeDocument . GetSourceText ( ) ;
@@ -1250,17 +1356,11 @@ private async Task ValidateExtractComponentCodeActionAsync(
1250
1356
codeActionToRun ,
1251
1357
requestContext ,
1252
1358
languageServer ,
1253
- codeActionResolversCreator ? . Invoke ( razorFilePath , codeDocument ) ?? [ ] ) ;
1254
-
1255
- var edits = new List < TextChange > ( ) ;
1359
+ codeActionResolversCreator ? . Invoke ( razorFilePath , codeDocument , formattingService , languageServer , arg5 : null ) ?? [ ] ) ;
1256
1360
1257
- // Only get changes made in the new component file
1258
- foreach ( var change in changes . Where ( e => e . TextDocument . Uri . AbsolutePath == componentFilePath ) )
1259
- {
1260
- edits . AddRange ( change . Edits . Select ( e => e . ToTextChange ( sourceText ) ) ) ;
1261
- }
1361
+ var edits = changes . Where ( change => change . TextDocument . Uri . AbsolutePath == componentFilePath ) . Single ( ) ;
1362
+ var actual = edits . Edits . Select ( edit => edit . NewText ) . Single ( ) ;
1262
1363
1263
- var actual = sourceText . WithChanges ( edits ) . ToString ( ) ;
1264
1364
AssertEx . EqualOrDiff ( expected , actual ) ;
1265
1365
}
1266
1366
0 commit comments