2121using System . IO ;
2222using System . Linq ;
2323using System . Reflection ;
24+ using System . Runtime . InteropServices ;
2425using System . Threading . Tasks ;
2526using Grpc . Dotnet . Cli . Commands ;
2627using Grpc . Dotnet . Cli . Internal ;
@@ -142,15 +143,69 @@ public void AddProtobufReference_ThrowsIfFileNotFound()
142143 Assert . Throws < CLIToolException > ( ( ) => commandBase . AddProtobufReference ( Services . Both , string . Empty , Access . Public , "NonExistentFile" , string . Empty ) ) ;
143144 }
144145
146+ static object [ ] ReferenceCases ( )
147+ {
148+ var cases = new List < object >
149+ {
150+ new object [ ] { "Proto/a.proto" , "Proto\\ a.proto" , "" } ,
151+ new object [ ] { "./Proto/a.proto" , "Proto\\ a.proto" , "" } ,
152+ new object [ ] { "../ProjectWithReference/Proto/a.proto" , "..\\ ProjectWithReference\\ Proto\\ a.proto" , "Protos\\ a.proto" } ,
153+ new object [ ] { "./../ProjectWithReference/Proto/a.proto" , "..\\ ProjectWithReference\\ Proto\\ a.proto" , "Protos\\ a.proto" } ,
154+ } ;
155+
156+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
157+ {
158+ cases . Add ( new object [ ] { "Proto\\ a.proto" , "Proto\\ a.proto" , "" } ) ;
159+ cases . Add ( new object [ ] { ".\\ Proto/a.proto" , "Proto\\ a.proto" , "" } ) ;
160+ cases . Add ( new object [ ] { "..\\ ProjectWithReference\\ Proto\\ a.proto" , "..\\ ProjectWithReference\\ Proto\\ a.proto" , "Protos\\ a.proto" } ) ;
161+ cases . Add ( new object [ ] { ".\\ ..\\ ProjectWithReference\\ Proto\\ a.proto" , "..\\ ProjectWithReference\\ Proto\\ a.proto" , "Protos\\ a.proto" } ) ;
162+ }
163+
164+ return cases . ToArray ( ) ;
165+ }
166+
145167 [ Test ]
146- public void AddProtobufReference_AddsRelativeReference ( )
168+ [ TestCaseSource ( nameof ( ReferenceCases ) ) ]
169+ public void AddProtobufReference_AddsRelativeReference ( string path , string normalizedPath , string link )
147170 {
148171 // Arrange
149172 var commandBase = new CommandBase (
150173 new TestConsole ( ) ,
151174 CreateIsolatedProject ( Path . Combine ( Directory . GetCurrentDirectory ( ) , "TestAssets" , "EmptyProject" , "test.csproj" ) ) ) ;
152175
153- var referencePath = Path . Combine ( "Proto" , "a.proto" ) ;
176+ // Act
177+ commandBase . AddProtobufReference ( Services . Server , "ImportDir" , Access . Internal , path , SourceUrl ) ;
178+ commandBase . Project . ReevaluateIfNecessary ( ) ;
179+
180+ // Assert
181+ var protoRefs = commandBase . Project . GetItems ( CommandBase . ProtobufElement ) ;
182+ Assert . AreEqual ( 1 , protoRefs . Count ) ;
183+ var protoRef = protoRefs . Single ( ) ;
184+ Assert . AreEqual ( normalizedPath , protoRef . UnevaluatedInclude ) ;
185+ Assert . AreEqual ( "Server" , protoRef . GetMetadataValue ( CommandBase . GrpcServicesElement ) ) ;
186+ Assert . AreEqual ( "ImportDir" , protoRef . GetMetadataValue ( CommandBase . AdditionalImportDirsElement ) ) ;
187+ Assert . AreEqual ( "Internal" , protoRef . GetMetadataValue ( CommandBase . AccessElement ) ) ;
188+ Assert . AreEqual ( SourceUrl , protoRef . GetMetadataValue ( CommandBase . SourceUrlElement ) ) ;
189+ Assert . AreEqual ( link , protoRef . GetMetadataValue ( CommandBase . LinkElement ) ) ;
190+ }
191+
192+ [ Test ]
193+ [ TestCaseSource ( nameof ( ReferenceCases ) ) ]
194+ public void AddProtobufReference_AddsAbsoluteReference ( string path , string normalizedPath , string link )
195+ {
196+ // Arrange
197+ var commandBase = new CommandBase (
198+ new TestConsole ( ) ,
199+ CreateIsolatedProject ( Path . Combine ( Directory . GetCurrentDirectory ( ) , "TestAssets" , "EmptyProject" , "test.csproj" ) ) ) ;
200+
201+ var referencePath = Path . Combine ( Directory . GetCurrentDirectory ( ) , "TestAssets" , "EmptyProject" , path ) ;
202+ var normalizedReferencePath = Path . GetFullPath (
203+ Path . Combine (
204+ Directory . GetCurrentDirectory ( ) ,
205+ "TestAssets" ,
206+ "EmptyProject" ,
207+ normalizedPath . Replace ( '\\ ' , Path . DirectorySeparatorChar ) ) )
208+ . Replace ( '/' , '\\ ' ) ;
154209
155210 // Act
156211 commandBase . AddProtobufReference ( Services . Server , "ImportDir" , Access . Internal , referencePath , SourceUrl ) ;
@@ -160,89 +215,158 @@ public void AddProtobufReference_AddsRelativeReference()
160215 var protoRefs = commandBase . Project . GetItems ( CommandBase . ProtobufElement ) ;
161216 Assert . AreEqual ( 1 , protoRefs . Count ) ;
162217 var protoRef = protoRefs . Single ( ) ;
163- Assert . AreEqual ( referencePath , protoRef . UnevaluatedInclude ) ;
218+ Assert . AreEqual ( normalizedReferencePath , protoRef . UnevaluatedInclude ) ;
164219 Assert . AreEqual ( "Server" , protoRef . GetMetadataValue ( CommandBase . GrpcServicesElement ) ) ;
165220 Assert . AreEqual ( "ImportDir" , protoRef . GetMetadataValue ( CommandBase . AdditionalImportDirsElement ) ) ;
166221 Assert . AreEqual ( "Internal" , protoRef . GetMetadataValue ( CommandBase . AccessElement ) ) ;
167222 Assert . AreEqual ( SourceUrl , protoRef . GetMetadataValue ( CommandBase . SourceUrlElement ) ) ;
168- Assert . False ( protoRef . HasMetadata ( CommandBase . LinkElement ) ) ;
223+ Assert . AreEqual ( link , protoRef . GetMetadataValue ( CommandBase . LinkElement ) ) ;
224+ }
225+
226+ static object [ ] AdditionalImportDirsCases ( )
227+ {
228+ var cases = new List < object >
229+ {
230+ new object [ ] { "ImportDir" , "ImportDir" } ,
231+ new object [ ] { "ImportDir;./ImportDir2" , "ImportDir;ImportDir2" } ,
232+ new object [ ] { "../ImportDir;./../ImportDir2" , "../ImportDir;../ImportDir2" } ,
233+ new object [ ] { "ImportDir;;ImportDir2;" , "ImportDir;ImportDir2" } ,
234+ } ;
235+
236+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
237+ {
238+ cases . Add ( new object [ ] { ".\\ ImportDir;ImportDir2" , "ImportDir;ImportDir2" } ) ;
239+ cases . Add ( new object [ ] { "../ImportDir;..\\ ImportDir2" , "..\\ ImportDir;..\\ ImportDir2" } ) ;
240+ cases . Add ( new object [ ] { "./../ImportDir;.\\ ..\\ ImportDir2" , "..\\ ImportDir;..\\ ImportDir2" } ) ;
241+ }
242+
243+ return cases . ToArray ( ) ;
169244 }
170245
171246 [ Test ]
172- public void AddProtobufReference_AddsAbsoluteReference ( )
247+ [ TestCaseSource ( nameof ( AdditionalImportDirsCases ) ) ]
248+ public void AddProtobufReference_AdditionalImportDirs ( string additionalImportDir , string normalizedAdditionalImportDir )
173249 {
174250 // Arrange
175- var commandBase = new CommandBase ( new TestConsole ( ) , new Project ( ) ) ;
176- var referencePath = Path . Combine ( Directory . GetCurrentDirectory ( ) , "TestAssets" , "EmptyProject" , "Proto" , "a.proto" ) ;
251+ var commandBase = new CommandBase (
252+ new TestConsole ( ) ,
253+ CreateIsolatedProject ( Path . Combine ( Directory . GetCurrentDirectory ( ) , "TestAssets" , "EmptyProject" , "test.csproj" ) ) ) ;
177254
255+ const string proto = "Proto/a.proto" ;
256+
178257 // Act
179- commandBase . AddProtobufReference ( Services . Server , "ImportDir" , Access . Internal , referencePath , SourceUrl ) ;
258+ commandBase . AddProtobufReference ( Services . Server , "ImportDir" , Access . Internal , proto , SourceUrl ) ;
180259 commandBase . Project . ReevaluateIfNecessary ( ) ;
181260
182261 // Assert
183262 var protoRefs = commandBase . Project . GetItems ( CommandBase . ProtobufElement ) ;
184263 Assert . AreEqual ( 1 , protoRefs . Count ) ;
185264 var protoRef = protoRefs . Single ( ) ;
186- Assert . AreEqual ( referencePath , protoRef . UnevaluatedInclude ) ;
265+ Assert . AreEqual ( proto . Replace ( '/' , ' \\ ' ) , protoRef . UnevaluatedInclude ) ;
187266 Assert . AreEqual ( "Server" , protoRef . GetMetadataValue ( CommandBase . GrpcServicesElement ) ) ;
188267 Assert . AreEqual ( "ImportDir" , protoRef . GetMetadataValue ( CommandBase . AdditionalImportDirsElement ) ) ;
189268 Assert . AreEqual ( "Internal" , protoRef . GetMetadataValue ( CommandBase . AccessElement ) ) ;
190269 Assert . AreEqual ( SourceUrl , protoRef . GetMetadataValue ( CommandBase . SourceUrlElement ) ) ;
191270 Assert . False ( protoRef . HasMetadata ( CommandBase . LinkElement ) ) ;
192271 }
193272
273+ static object [ ] DoesNotOverwriteCases ( )
274+ {
275+ var cases = new List < object >
276+ {
277+ new object [ ] { "Proto/a.proto" , "Proto/a.proto" , "Proto\\ a.proto" } ,
278+ new object [ ] { "./Proto/a.proto" , "Proto/a.proto" , "Proto\\ a.proto" } ,
279+ new object [ ] { "../ProjectWithReference/Proto/a.proto" , "../ProjectWithReference/Proto/a.proto" , "..\\ ProjectWithReference\\ Proto\\ a.proto" } ,
280+ new object [ ] { "../ProjectWithReference/Proto/a.proto" , "./../ProjectWithReference/Proto/a.proto" , "..\\ ProjectWithReference\\ Proto\\ a.proto" } ,
281+ new object [ ] { "./../ProjectWithReference/Proto/a.proto" , "./../ProjectWithReference/Proto/a.proto" , "..\\ ProjectWithReference\\ Proto\\ a.proto" } ,
282+ } ;
283+
284+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
285+ {
286+ cases . Add ( new object [ ] { "Proto/a.proto" , "Proto\\ a.proto" , "Proto\\ a.proto" } ) ;
287+ cases . Add ( new object [ ] { ".\\ ..\\ ProjectWithReference\\ Proto\\ a.proto" , "../ProjectWithReference/Proto/a.proto" , "..\\ ProjectWithReference\\ Proto\\ a.proto" } ) ;
288+ cases . Add ( new object [ ] { ".\\ ..\\ ProjectWithReference\\ Proto\\ a.proto" , "./../ProjectWithReference/Proto/a.proto" , "..\\ ProjectWithReference\\ Proto\\ a.proto" } ) ;
289+ }
290+
291+ return cases . ToArray ( ) ;
292+ }
293+
194294 [ Test ]
195- public void AddProtobufReference_DoesNotOverwriteReference ( )
295+ [ TestCaseSource ( nameof ( DoesNotOverwriteCases ) ) ]
296+ public void AddProtobufReference_DoesNotOverwriteReference ( string path , string altPath , string normalizedPath )
196297 {
197298 // Arrange
198299 var commandBase = new CommandBase ( new TestConsole ( ) , new Project ( ) ) ;
199- var referencePath = Path . Combine ( Directory . GetCurrentDirectory ( ) , "TestAssets" , "EmptyProject" , "Proto" , "a.proto" ) ;
300+ var referencePath = Path . Combine ( Directory . GetCurrentDirectory ( ) , "TestAssets" , "EmptyProject" , path ) ;
301+ var altReferencePath = Path . Combine ( Directory . GetCurrentDirectory ( ) , "TestAssets" , "EmptyProject" , altPath ) ;
302+ var normalizedReferencePath = Path . GetFullPath (
303+ Path . Combine (
304+ Directory . GetCurrentDirectory ( ) ,
305+ "TestAssets" ,
306+ "EmptyProject" ,
307+ normalizedPath . Replace ( '\\ ' , '/' ) ) )
308+ . Replace ( '/' , '\\ ' ) ;
200309
201310 // Act
202311 commandBase . AddProtobufReference ( Services . Server , "ImportDir" , Access . Internal , referencePath , SourceUrl ) ;
203- commandBase . AddProtobufReference ( Services . Client , "ImportDir2" , Access . Public , referencePath , SourceUrl + ".proto" ) ;
312+ commandBase . AddProtobufReference ( Services . Client , "ImportDir2" , Access . Public , altReferencePath , SourceUrl + ".proto" ) ;
204313 commandBase . Project . ReevaluateIfNecessary ( ) ;
205314
206315 // Assert
207316 var protoRefs = commandBase . Project . GetItems ( CommandBase . ProtobufElement ) ;
208317 Assert . AreEqual ( 1 , protoRefs . Count ) ;
209318 var protoRef = protoRefs . Single ( ) ;
210- Assert . AreEqual ( referencePath , protoRef . UnevaluatedInclude ) ;
319+ Assert . AreEqual ( normalizedReferencePath , protoRef . UnevaluatedInclude ) ;
211320 Assert . AreEqual ( "Server" , protoRef . GetMetadataValue ( CommandBase . GrpcServicesElement ) ) ;
212321 Assert . AreEqual ( "ImportDir" , protoRef . GetMetadataValue ( CommandBase . AdditionalImportDirsElement ) ) ;
213322 Assert . AreEqual ( "Internal" , protoRef . GetMetadataValue ( CommandBase . AccessElement ) ) ;
214323 Assert . AreEqual ( SourceUrl , protoRef . GetMetadataValue ( CommandBase . SourceUrlElement ) ) ;
215324 }
216325
217- static object [ ] ProtosOutsideProject =
326+ static object [ ] ProtosOutsideProject ( )
218327 {
219- new object [ ] { Path . Combine ( Directory . GetCurrentDirectory ( ) , "TestAssets" , "ProjectWithReference" , "Proto" , "a.proto" ) } ,
220- new object [ ] { Path . Combine ( ".." , "ProjectWithReference" , "Proto" , "a.proto" ) } ,
221- } ;
328+ var cases = new List < object >
329+ {
330+ Case ( Directory . GetCurrentDirectory ( ) , "TestAssets" , "ProjectWithReference" , "Proto" , "a.proto" ) ,
331+ Case ( ".." , "ProjectWithReference" , "Proto" , "a.proto" )
332+ } ;
333+
334+ return cases . ToArray ( ) ;
335+
336+ static object Case ( params string [ ] segments )
337+ {
338+ var path = Path . Combine ( segments ) ;
339+ return new object [ ]
340+ {
341+ path ,
342+ path . Replace ( '/' , '\\ ' )
343+ } ;
344+ }
345+ }
222346
223347 [ Test ]
224- [ TestCaseSource ( " ProtosOutsideProject" ) ]
225- public void AddProtobufReference_AddsLinkElementIfFileOutsideProject ( string reference )
348+ [ TestCaseSource ( nameof ( ProtosOutsideProject ) ) ]
349+ public void AddProtobufReference_AddsLinkElementIfFileOutsideProject ( string path , string normalizedPath )
226350 {
227351 // Arrange
228352 var commandBase = new CommandBase (
229353 new TestConsole ( ) ,
230354 CreateIsolatedProject ( Path . Combine ( Directory . GetCurrentDirectory ( ) , "TestAssets" , "EmptyProject" , "test.csproj" ) ) ) ;
231355
232356 // Act
233- commandBase . AddProtobufReference ( Services . Server , "ImportDir" , Access . Internal , reference , SourceUrl ) ;
357+ commandBase . AddProtobufReference ( Services . Server , "ImportDir" , Access . Internal , path , SourceUrl ) ;
234358 commandBase . Project . ReevaluateIfNecessary ( ) ;
235359
236360 // Assert
237361 var protoRefs = commandBase . Project . GetItems ( CommandBase . ProtobufElement ) ;
238362 Assert . AreEqual ( 1 , protoRefs . Count ) ;
239363 var protoRef = protoRefs . Single ( ) ;
240- Assert . AreEqual ( reference , protoRef . UnevaluatedInclude ) ;
364+ Assert . AreEqual ( normalizedPath , protoRef . UnevaluatedInclude ) ;
241365 Assert . AreEqual ( "Server" , protoRef . GetMetadataValue ( CommandBase . GrpcServicesElement ) ) ;
242366 Assert . AreEqual ( "ImportDir" , protoRef . GetMetadataValue ( CommandBase . AdditionalImportDirsElement ) ) ;
243367 Assert . AreEqual ( "Internal" , protoRef . GetMetadataValue ( CommandBase . AccessElement ) ) ;
244368 Assert . AreEqual ( SourceUrl , protoRef . GetMetadataValue ( CommandBase . SourceUrlElement ) ) ;
245- Assert . AreEqual ( Path . Combine ( CommandBase . ProtosFolder , " a.proto") , protoRef . GetMetadataValue ( CommandBase . LinkElement ) ) ;
369+ Assert . AreEqual ( $ " { CommandBase . ProtosFolder } \\ a.proto", protoRef . GetMetadataValue ( CommandBase . LinkElement ) ) ;
246370 }
247371
248372 [ Test ]
0 commit comments