@@ -61,10 +61,9 @@ private GenerateMethodCodeActionResolver[] CreateRazorCodeActionResolvers(
61
61
razorFormattingService )
62
62
] ;
63
63
64
- // TODO: Make this func
65
- private ExtractToComponentCodeActionResolver [ ] CreateExtractComponentCodeActionResolvers ( string filePath , RazorCodeDocument codeDocument )
64
+
65
+ private ExtractToComponentCodeActionResolver [ ] CreateExtractComponentCodeActionResolver ( string filePath , RazorCodeDocument codeDocument )
66
66
{
67
- var emptyDocumentContextFactory = new TestDocumentContextFactory ( ) ;
68
67
return [
69
68
new ExtractToComponentCodeActionResolver (
70
69
new GenerateMethodResolverDocumentContextFactory ( filePath , codeDocument ) ,
@@ -1019,7 +1018,7 @@ await ValidateCodeActionAsync(input,
1019
1018
}
1020
1019
1021
1020
[ Fact ]
1022
- public async Task Handle_ExtractComponent ( )
1021
+ public async Task Handle_ExtractComponent_SingleElement_ReturnsResult ( )
1023
1022
{
1024
1023
var input = """
1025
1024
<[||]div id="a">
@@ -1045,7 +1044,75 @@ await ValidateExtractComponentCodeActionAsync(
1045
1044
expectedRazorComponent ,
1046
1045
ExtractToComponentTitle ,
1047
1046
razorCodeActionProviders : [ new ExtractToComponentCodeActionProvider ( LoggerFactory ) ] ,
1048
- codeActionResolversCreator : CreateExtractComponentCodeActionResolvers ) ;
1047
+ codeActionResolversCreator : CreateExtractComponentCodeActionResolver ) ;
1048
+ }
1049
+
1050
+ [ Fact ]
1051
+ public async Task Handle_ExtractComponent_SiblingElement_ReturnsResult ( )
1052
+ {
1053
+ var input = """
1054
+ <[|div id="a">
1055
+ <h1>Div a title</h1>
1056
+ <Book Title="To Kill a Mockingbird" Author="Harper Lee" Year="Long ago" />
1057
+ <p>Div a par</p>
1058
+ </div>
1059
+ <div id="b">
1060
+ <Movie Title="Aftersun" Director="Charlotte Wells" Year="2022" />
1061
+ </div|]>
1062
+ """ ;
1063
+
1064
+ var expectedRazorComponent = """
1065
+ <div id="a">
1066
+ <h1>Div a title</h1>
1067
+ <Book Title="To Kill a Mockingbird" Author="Harper Lee" Year="Long ago" />
1068
+ <p>Div a par</p>
1069
+ </div>
1070
+ <div id="b">
1071
+ <Movie Title="Aftersun" Director="Charlotte Wells" Year="2022" />
1072
+ </div>
1073
+ """ ;
1074
+
1075
+ await ValidateExtractComponentCodeActionAsync (
1076
+ input ,
1077
+ expectedRazorComponent ,
1078
+ ExtractToComponentTitle ,
1079
+ razorCodeActionProviders : [ new ExtractToComponentCodeActionProvider ( LoggerFactory ) ] ,
1080
+ codeActionResolversCreator : CreateExtractComponentCodeActionResolver ) ;
1081
+ }
1082
+
1083
+ [ Fact ]
1084
+ public async Task Handle_ExtractComponent_StartNodeContainsEndNode_ReturnsResult ( )
1085
+ {
1086
+ var input = """
1087
+ <[|div id="parent">
1088
+ <div>
1089
+ <div>
1090
+ <div>
1091
+ <p>Deeply nested par</p|]>
1092
+ </div>
1093
+ </div>
1094
+ </div>
1095
+ </div>
1096
+ """ ;
1097
+
1098
+ var expectedRazorComponent = """
1099
+ <div id="parent">
1100
+ <div>
1101
+ <div>
1102
+ <div>
1103
+ <p>Deeply nested par</p>
1104
+ </div>
1105
+ </div>
1106
+ </div>
1107
+ </div>
1108
+ """ ;
1109
+
1110
+ await ValidateExtractComponentCodeActionAsync (
1111
+ input ,
1112
+ expectedRazorComponent ,
1113
+ ExtractToComponentTitle ,
1114
+ razorCodeActionProviders : [ new ExtractToComponentCodeActionProvider ( LoggerFactory ) ] ,
1115
+ codeActionResolversCreator : CreateExtractComponentCodeActionResolver ) ;
1049
1116
}
1050
1117
1051
1118
#endregion
@@ -1196,19 +1263,20 @@ private async Task ValidateExtractComponentCodeActionAsync(
1196
1263
string ? expected ,
1197
1264
string codeAction ,
1198
1265
int childActionIndex = 0 ,
1266
+ IEnumerable < ( string filePath , string contents ) > ? additionalRazorDocuments = null ,
1199
1267
IRazorCodeActionProvider [ ] ? razorCodeActionProviders = null ,
1200
1268
Func < string , RazorCodeDocument , IRazorCodeActionResolver [ ] > ? codeActionResolversCreator = null ,
1201
1269
RazorLSPOptionsMonitor ? optionsMonitor = null ,
1202
1270
Diagnostic [ ] ? diagnostics = null )
1203
1271
{
1204
1272
TestFileMarkupParser . GetSpan ( input , out input , out var textSpan ) ;
1205
1273
1206
- var razorFilePath = "C:/path/test.razor" ;
1207
- var componentFilePath = "C:/path/Component.razor" ;
1274
+ var razorFilePath = "C:/path/to/ test.razor" ;
1275
+ var componentFilePath = "C:/path/to/ Component.razor" ;
1208
1276
var codeDocument = CreateCodeDocument ( input , filePath : razorFilePath ) ;
1209
1277
var sourceText = codeDocument . Source . Text ;
1210
1278
var uri = new Uri ( razorFilePath ) ;
1211
- var languageServer = await CreateLanguageServerAsync ( codeDocument , razorFilePath ) ;
1279
+ var languageServer = await CreateLanguageServerAsync ( codeDocument , razorFilePath , additionalRazorDocuments ) ;
1212
1280
var documentContext = CreateDocumentContext ( uri , codeDocument ) ;
1213
1281
var requestContext = new RazorRequestContext ( documentContext , null ! , "lsp/method" , uri : null ) ;
1214
1282
@@ -1239,15 +1307,9 @@ private async Task ValidateExtractComponentCodeActionAsync(
1239
1307
languageServer ,
1240
1308
codeActionResolversCreator ? . Invoke ( razorFilePath , codeDocument ) ?? [ ] ) ;
1241
1309
1242
- var edits = new List < TextChange > ( ) ;
1243
-
1244
- // Only get changes made in the new component file
1245
- foreach ( var change in changes . Where ( e => e . TextDocument . Uri . AbsolutePath == componentFilePath ) )
1246
- {
1247
- edits . AddRange ( change . Edits . Select ( sourceText . GetTextChange ) ) ;
1248
- }
1310
+ var edits = changes . Where ( change => change . TextDocument . Uri . AbsolutePath == componentFilePath ) . Single ( ) ;
1311
+ var actual = edits . Edits . Select ( edit => edit . NewText ) . Single ( ) ;
1249
1312
1250
- var actual = sourceText . WithChanges ( edits ) . ToString ( ) ;
1251
1313
AssertEx . EqualOrDiff ( expected , actual ) ;
1252
1314
}
1253
1315
0 commit comments