Skip to content

Commit ab398f7

Browse files
committed
Update SA1625 to handle included documentation (fixes #1915)
1 parent 578d7f7 commit ab398f7

3 files changed

Lines changed: 402 additions & 19 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1625UnitTests.cs

Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ namespace StyleCop.Analyzers.Test.DocumentationRules
66
using System.Collections.Generic;
77
using System.Threading;
88
using System.Threading.Tasks;
9+
using Helpers;
10+
using Microsoft.CodeAnalysis;
911
using Microsoft.CodeAnalysis.Diagnostics;
1012
using StyleCop.Analyzers.DocumentationRules;
1113
using TestHelper;
@@ -271,6 +273,305 @@ public class TestClass
271273
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
272274
}
273275

276+
[Fact]
277+
public async Task VerifyThatCorrectIncludedDocumentationDoesNotReportADiagnosticAsync()
278+
{
279+
var testCode = $@"
280+
public class TestClass
281+
{{
282+
/// <include file='Correct.xml' path='/TestClass/Test/*' />
283+
public void Test() {{ }}
284+
}}
285+
";
286+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
287+
}
288+
289+
[Fact]
290+
public async Task VerifyThatCorrectIncludedDocumentationWithEmptyElementsDoesNotReportADiagnosticAsync()
291+
{
292+
var testCode = $@"
293+
public class TestClass
294+
{{
295+
/// <include file='CorrectWithEmptyElements.xml' path='/TestClass/Test/*' />
296+
public void Test() {{ }}
297+
}}
298+
public class TestClass2 {{ }}
299+
";
300+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
301+
}
302+
303+
[Fact]
304+
public async Task VerifyThatTheAnalyzerDoesNotCrashOnIncludedInheritDocAsync()
305+
{
306+
var testCode = $@"
307+
public class TestClass
308+
{{
309+
/// <include file='Inherited.xml' path='/TestClass/Test/*' />
310+
public void Test() {{ }}
311+
}}
312+
";
313+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
314+
}
315+
316+
[Fact]
317+
public async Task VerifyThatIncludedWhitespacesAreNormalizedForEmptyXmlElementsAsync()
318+
{
319+
var testCode = $@"
320+
public class TestClass
321+
{{
322+
/// <include file='BadWithNormalization.xml' path='/TestClass/Test/*' />
323+
public void Test() {{ }}
324+
}}
325+
";
326+
var expected = this.CSharpDiagnostic().WithLocation(5, 17);
327+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
328+
}
329+
330+
[Fact]
331+
public async Task VerifyThatIncludedDuplicatedDocumentationDoesReportADiagnosticAsync()
332+
{
333+
var testCode = $@"
334+
public class TestClass
335+
{{
336+
/// <include file='BadWithDuplicates.xml' path='/TestClass/Test/*' />
337+
public void Test() {{ }}
338+
}}
339+
";
340+
var expected = this.CSharpDiagnostic().WithLocation(5, 17);
341+
342+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
343+
}
344+
345+
[Fact]
346+
public async Task VerifyThatAnalyzerIgnoresLeadingAndTrailingWhitespaceInIncludedDocumentationAsync()
347+
{
348+
var testCode = $@"
349+
public class TestClass
350+
{{
351+
/// <include file='BadWithDuplicates2.xml' path='/TestClass/Test/*' />
352+
public void Test() {{ }}
353+
}}
354+
";
355+
var expected = this.CSharpDiagnostic().WithLocation(5, 17);
356+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
357+
}
358+
359+
[Fact]
360+
public async Task VerifyThatAnalysisIgnoresUnusedParametersInIncludedDocumentationAsync()
361+
{
362+
var testCode = $@"
363+
public class TestClass
364+
{{
365+
/// <include file='WithIgnoredParameters.xml' path='/TestClass/Test/*' />
366+
public void Test() {{ }}
367+
}}
368+
";
369+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
370+
}
371+
372+
// [Fact]
373+
// public async Task VerifyThatAnalysisIgnoresEmptyElementsInIncludedDocumentationAsync()
374+
// {
375+
// var testCode = $@"
376+
//public class TestClass
377+
//{{
378+
// /// <summary></summary>
379+
// /// <remark>Documentation</remark>
380+
// /// <remark></remark>
381+
// /// <remark>Documentation</remark>
382+
// /// <include file='With.xml' path='/TestClass/Test/*' />
383+
// public void Test() {{ }}
384+
//}}
385+
//";
386+
// var expected = this.CSharpDiagnostic().WithLocation(7, 9);
387+
// await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
388+
// }
389+
390+
// [Fact]
391+
// public async Task VerifyThatCorrectIncludedDocumentationDoesNotReportADiagnosticMultiLineAsync()
392+
// {
393+
// var testCode = $@"
394+
//public class TestClass
395+
//{{
396+
// /** <summary>
397+
// * Some documentation.
398+
// * </summary>
399+
// * <remark>Some remark.</remark>
400+
// **/
401+
// public void Test() {{ }}
402+
//}}
403+
//";
404+
// await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
405+
// }
406+
407+
// [Fact]
408+
// public async Task VerifyThatIncludedDuplicatedDocumentationDoesReportADiagnosticMultiLineAsync()
409+
// {
410+
// var testCode = $@"
411+
//public class TestClass
412+
//{{
413+
// /** <summary>Some documentation.</summary>
414+
// * <remark>Some documentation.</remark>
415+
// **/
416+
// public void Test() {{ }}
417+
//}}
418+
//";
419+
// var expected = this.CSharpDiagnostic().WithLocation(5, 7);
420+
421+
// await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
422+
// }
423+
424+
// [Fact]
425+
// public async Task VerifyThatAnalyzerIgnoresIncludedLeadingAndTrailingWhitespaceMultiLineAsync()
426+
// {
427+
// var testCode = $@"
428+
//public class TestClass
429+
//{{
430+
// /** <summary>
431+
// * Some documentation.
432+
// *
433+
// *
434+
// * </summary>
435+
// * <remark> Some documentation. </remark>
436+
// **/
437+
// public void Test() {{ }}
438+
//}}
439+
//";
440+
// var expected = this.CSharpDiagnostic().WithLocation(9, 7);
441+
// await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
442+
// }
443+
444+
// [Fact]
445+
// public async Task VerifyThatAnalysisIgnoresIncludedUnusedParametersMultiLineAsync()
446+
// {
447+
// var testCode = $@"
448+
//public class TestClass
449+
//{{
450+
// /** <summary>The parameter is not used.</summary>
451+
// * <remark>Documentation</remark>
452+
// * <remark>The parameter is not used.</remark>
453+
// * <remark>Documentation</remark>
454+
// **/
455+
// public void Test() {{ }}
456+
//}}
457+
//";
458+
// var expected = this.CSharpDiagnostic().WithLocation(7, 7);
459+
// await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
460+
// }
461+
462+
// [Fact]
463+
// public async Task VerifyThatAnalysisIgnoresIncludedEmptyElementsMultiLineAsync()
464+
// {
465+
// var testCode = $@"
466+
//public class TestClass
467+
//{{
468+
// /** <summary></summary>
469+
// * <remark>Documentation</remark>
470+
// * <remark></remark>
471+
// * <remark>Documentation</remark>
472+
// **/
473+
// public void Test() {{ }}
474+
//}}
475+
//";
476+
// var expected = this.CSharpDiagnostic().WithLocation(7, 7);
477+
// await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
478+
// }
479+
480+
/// <inheritdoc/>
481+
protected override Project ApplyCompilationOptions(Project project)
482+
{
483+
var resolver = new TestXmlReferenceResolver();
484+
485+
string correctDocumentation = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
486+
<TestClass>
487+
<Test>
488+
<summary>
489+
Some documentation.
490+
</summary>
491+
<remark>Some remark.</remark>
492+
</Test>
493+
</TestClass>
494+
";
495+
resolver.XmlReferences.Add("Correct.xml", correctDocumentation);
496+
497+
string correctWithEmptyElements = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
498+
<TestClass>
499+
<Test>
500+
<summary>
501+
Some documentation <see cref=""TestClass""/>.
502+
</summary>
503+
<summary>
504+
Some documentation <see cref=""TestClass2""/>.
505+
</summary>
506+
<remark>Some remark.</remark>
507+
</Test>
508+
</TestClass>
509+
";
510+
resolver.XmlReferences.Add("CorrectWithEmptyElements.xml", correctWithEmptyElements);
511+
512+
string inherited = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
513+
<TestClass>
514+
<Test>
515+
<inheritdoc />
516+
</Test>
517+
</TestClass>
518+
";
519+
resolver.XmlReferences.Add("Inherited.xml", inherited);
520+
521+
string badWithNormalization = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
522+
<TestClass>
523+
<Test>
524+
<summary>
525+
Some documentation <see cref=""TestClass""/>.
526+
</summary>
527+
<summary>
528+
Some documentation <see cref = ""TestClass"" />.
529+
</summary>
530+
<remark>Some remark.</remark>
531+
</Test>
532+
</TestClass>
533+
";
534+
resolver.XmlReferences.Add("BadWithNormalization.xml", badWithNormalization);
535+
536+
string badWithDuplicates = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
537+
<TestClass>
538+
<Test>
539+
<summary>Some documentation.</summary>
540+
<remark>Some documentation.</remark>
541+
</Test>
542+
</TestClass>
543+
";
544+
resolver.XmlReferences.Add("BadWithDuplicates.xml", badWithDuplicates);
545+
546+
string badWithDuplicates2 = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
547+
<TestClass>
548+
<Test>
549+
<summary>
550+
Some documentation.
551+
552+
553+
</summary>
554+
<remark> Some documentation. </remark>
555+
</Test>
556+
</TestClass>
557+
";
558+
resolver.XmlReferences.Add("BadWithDuplicates2.xml", badWithDuplicates2);
559+
560+
string withIgnoredParameters = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
561+
<TestClass>
562+
<Test>
563+
<summary>The parameter is not used.</summary>
564+
<remark>The parameter is not used.</remark>
565+
</Test>
566+
</TestClass>
567+
";
568+
resolver.XmlReferences.Add("WithIgnoredParameters.xml", withIgnoredParameters);
569+
570+
project = base.ApplyCompilationOptions(project);
571+
project = project.WithCompilationOptions(project.CompilationOptions.WithXmlReferenceResolver(resolver));
572+
return project;
573+
}
574+
274575
/// <inheritdoc/>
275576
protected override IEnumerable<DiagnosticAnalyzer> GetCSharpDiagnosticAnalyzers()
276577
{

0 commit comments

Comments
 (0)