@@ -7,6 +7,8 @@ namespace StyleCop.Analyzers.Test.DocumentationRules
77 using System . Threading ;
88 using System . Threading . Tasks ;
99 using Analyzers . DocumentationRules ;
10+ using Helpers ;
11+ using Microsoft . CodeAnalysis ;
1012 using Microsoft . CodeAnalysis . Diagnostics ;
1113 using TestHelper ;
1214 using Xunit ;
@@ -184,6 +186,235 @@ public class ClassName
184186 await this . VerifyCSharpDiagnosticAsync ( testCode . Replace ( "$$" , p ) , expected , CancellationToken . None ) . ConfigureAwait ( false ) ;
185187 }
186188
189+ [ Theory ]
190+ [ MemberData ( nameof ( Declarations ) ) ]
191+ public async Task VerifyInheritedDocumentationReportsNoDiagnosticsAsync ( string declaration )
192+ {
193+ var testCode = @"
194+ /// <summary>
195+ /// Foo
196+ /// </summary>
197+ public class ClassName
198+ {
199+ /// <inheritdoc/>
200+ $$
201+ }" ;
202+ await this . VerifyCSharpDiagnosticAsync ( testCode . Replace ( "$$" , declaration ) , EmptyDiagnosticResults , CancellationToken . None ) . ConfigureAwait ( false ) ;
203+ }
204+
205+ [ Fact ]
206+ public async Task VerifyIncludedMemberWithoutParamsIsNotReportedAsync ( )
207+ {
208+ var testCode = @"
209+ /// <summary>
210+ /// Foo
211+ /// </summary>
212+ public class ClassName
213+ {
214+ /// <include file='MissingParamDocumentation.xml' path='/ClassName/Method/*' />
215+ public ClassName Method() { return null; }
216+ }" ;
217+ await this . VerifyCSharpDiagnosticAsync ( testCode , EmptyDiagnosticResults , CancellationToken . None ) . ConfigureAwait ( false ) ;
218+ }
219+
220+ [ Fact ]
221+ public async Task VerifyIncludedMemberWithValidParamsIsNotReportedAsync ( )
222+ {
223+ var testCode = @"
224+ /// <summary>
225+ /// Foo
226+ /// </summary>
227+ public class ClassName
228+ {
229+ /// <include file='WithParamDocumentation.xml' path='/ClassName/Method/*' />
230+ public ClassName Method(string foo, string bar) { return null; }
231+ }" ;
232+ await this . VerifyCSharpDiagnosticAsync ( testCode , EmptyDiagnosticResults , CancellationToken . None ) . ConfigureAwait ( false ) ;
233+ }
234+
235+ [ Fact ]
236+ public async Task VerifyIncludedMemberWithInvalidParamsIsReportedAsync ( )
237+ {
238+ var testCode = @"
239+ /// <summary>
240+ /// Foo
241+ /// </summary>
242+ public class ClassName
243+ {
244+ /// <include file='WithInvalidParamDocumentation.xml' path='/ClassName/Method/*' />
245+ public ClassName Method(string foo, string bar) { return null; }
246+ }" ;
247+
248+ var expected = new [ ]
249+ {
250+ this . CSharpDiagnostic ( ) . WithLocation ( 8 , 22 ) . WithArguments ( "boo" ) ,
251+ this . CSharpDiagnostic ( ) . WithLocation ( 8 , 22 ) . WithArguments ( "far" )
252+ } ;
253+
254+ await this . VerifyCSharpDiagnosticAsync ( testCode , expected , CancellationToken . None ) . ConfigureAwait ( false ) ;
255+ }
256+
257+ [ Fact ]
258+ public async Task VerifyIncludedMemberWithInvalidParamsThatShouldBeHandledBySA1613IsNotReportedAsync ( )
259+ {
260+ var testCode = @"
261+ /// <summary>
262+ /// Foo
263+ /// </summary>
264+ public class ClassName
265+ {
266+ /// <include file='WithSA1613ParamDocumentation.xml' path='/ClassName/Method/*' />
267+ public ClassName Method(string foo, string bar) { return null; }
268+ }" ;
269+ await this . VerifyCSharpDiagnosticAsync ( testCode , EmptyDiagnosticResults , CancellationToken . None ) . ConfigureAwait ( false ) ;
270+ }
271+
272+ [ Fact ]
273+ public async Task VerifyIncludedMemberWithAllDocumentationWrongOrderIsReportedAsync ( )
274+ {
275+ var testCode = @"
276+ /// <summary>
277+ /// Foo
278+ /// </summary>
279+ public class ClassName
280+ {
281+ /// <include file='WithParamDocumentation.xml' path='/ClassName/Method/*' />
282+ public ClassName Method(string bar, string foo) { return null; }
283+ }" ;
284+
285+ var diagnostic = this . CSharpDiagnostic ( )
286+ . WithMessageFormat ( "The parameter documentation for '{0}' should be at position {1}." ) ;
287+
288+ var expected = new [ ]
289+ {
290+ diagnostic . WithLocation ( 8 , 22 ) . WithArguments ( "foo" , 2 ) ,
291+ diagnostic . WithLocation ( 8 , 22 ) . WithArguments ( "bar" , 1 ) ,
292+ } ;
293+
294+ await this . VerifyCSharpDiagnosticAsync ( testCode , expected , CancellationToken . None ) . ConfigureAwait ( false ) ;
295+ }
296+
297+ [ Fact ]
298+ public async Task VerifyIncludedMemberWithTooManyDocumentationIsReportedAsync ( )
299+ {
300+ var testCode = @"
301+ /// <summary>
302+ /// Foo
303+ /// </summary>
304+ public class ClassName
305+ {
306+ /// <include file='WithTooManyParamDocumentation.xml' path='/ClassName/Method/*' />
307+ public ClassName Method(string foo, string bar) { return null; }
308+ }" ;
309+
310+ var diagnostic = this . CSharpDiagnostic ( )
311+ . WithMessageFormat ( "The parameter documentation for '{0}' should be at position {1}." ) ;
312+
313+ var expected = diagnostic . WithLocation ( 8 , 22 ) . WithArguments ( "bar" , 2 ) ;
314+
315+ await this . VerifyCSharpDiagnosticAsync ( testCode , expected , CancellationToken . None ) . ConfigureAwait ( false ) ;
316+ }
317+
318+ [ Fact ]
319+ public async Task VerifyIncludedInheritedDocumentationIsNotReportedAsync ( )
320+ {
321+ var testCode = @"
322+ /// <summary>
323+ /// Foo
324+ /// </summary>
325+ public class ClassName
326+ {
327+ /// <include file='WithInheritedDocumentation.xml' path='/ClassName/Method/*' />
328+ public ClassName Method(string foo, string bar) { return null; }
329+ }" ;
330+ await this . VerifyCSharpDiagnosticAsync ( testCode , EmptyDiagnosticResults , CancellationToken . None ) . ConfigureAwait ( false ) ;
331+ }
332+
333+ /// <inheritdoc/>
334+ protected override Project CreateProject ( string [ ] sources , string language = "C#" , string [ ] filenames = null )
335+ {
336+ var resolver = new TestXmlReferenceResolver ( ) ;
337+
338+ string contentWithoutParamDocumentation = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
339+ <ClassName>
340+ <Method>
341+ <summary>
342+ Foo
343+ </summary>
344+ </Method>
345+ </ClassName>
346+ " ;
347+ resolver . XmlReferences . Add ( "MissingParamDocumentation.xml" , contentWithoutParamDocumentation ) ;
348+
349+ string contentWithParamDocumentation = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
350+ <ClassName>
351+ <Method>
352+ <summary>
353+ Foo
354+ </summary>
355+ <param name=""foo"">Param 1</param>
356+ <param name=""bar"">Param 2</param>
357+ </Method>
358+ </ClassName>
359+ " ;
360+ resolver . XmlReferences . Add ( "WithParamDocumentation.xml" , contentWithParamDocumentation ) ;
361+
362+ string contentWithInvalidParamDocumentation = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
363+ <ClassName>
364+ <Method>
365+ <summary>
366+ Foo
367+ </summary>
368+ <param name=""boo"">Param 1</param>
369+ <param name=""far"">Param 2</param>
370+ </Method>
371+ </ClassName>
372+ " ;
373+ resolver . XmlReferences . Add ( "WithInvalidParamDocumentation.xml" , contentWithInvalidParamDocumentation ) ;
374+
375+ string contentWithSA1613ParamDocumentation = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
376+ <ClassName>
377+ <Method>
378+ <summary>
379+ Foo
380+ </summary>
381+ <param>Test</param>
382+ <param/>
383+ <param name="""">Test</param>
384+ <param name="" "">Test</param>
385+ </Method>
386+ </ClassName>
387+ " ;
388+ resolver . XmlReferences . Add ( "WithSA1613ParamDocumentation.xml" , contentWithSA1613ParamDocumentation ) ;
389+
390+ string contentWithTooManyParamDocumentation = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
391+ <ClassName>
392+ <Method>
393+ <summary>
394+ Foo
395+ </summary>
396+ <param name=""foo"">Param 1</param>
397+ <param name=""bar"">Param 2</param>
398+ <param name=""bar"">Param 3</param>
399+ </Method>
400+ </ClassName>
401+ " ;
402+ resolver . XmlReferences . Add ( "WithTooManyParamDocumentation.xml" , contentWithTooManyParamDocumentation ) ;
403+
404+ string contentWithInheritedDocumentation = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
405+ <ClassName>
406+ <Method>
407+ <inheritdoc />
408+ </Method>
409+ </ClassName>
410+ " ;
411+ resolver . XmlReferences . Add ( "WithInheritedDocumentation.xml" , contentWithInheritedDocumentation ) ;
412+
413+ Project project = base . CreateProject ( sources , language , filenames ) ;
414+ project = project . WithCompilationOptions ( project . CompilationOptions . WithXmlReferenceResolver ( resolver ) ) ;
415+ return project ;
416+ }
417+
187418 protected override IEnumerable < DiagnosticAnalyzer > GetCSharpDiagnosticAnalyzers ( )
188419 {
189420 yield return new SA1612ElementParameterDocumentationMustMatchElementParameters ( ) ;
0 commit comments