Skip to content

Commit

Permalink
Merge pull request #3801 from bjornhellander/feature/sa1612-test-impr…
Browse files Browse the repository at this point in the history
…ovements

Improve tests for SA1612
  • Loading branch information
sharwell authored Mar 19, 2024
2 parents 834d939 + ed0ef91 commit f66d17d
Showing 1 changed file with 157 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
namespace StyleCop.Analyzers.Test.DocumentationRules
{
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Testing;
Expand All @@ -23,12 +24,41 @@ public static IEnumerable<object[]> Declarations
{
get
{
yield return new[] { " public ClassName Method(string foo, string bar, string @new) { return null; }" };
yield return new[] { " public delegate ClassName Method(string foo, string bar, string @new);" };
yield return new[] { " public ClassName this[string foo, string bar, string @new] { get { return null; } set { } }" };
yield return new object[] { " public ClassName {|#0:Method|}(string foo, string bar, string @new) { return null; }" };
yield return new object[] { " public delegate ClassName {|#0:Method|}(string foo, string bar, string @new);" };
yield return new object[] { " public ClassName {|#0:this|}[string foo, string bar, string @new] { get { return null; } set { } }" };
}
}

[Fact]
public async Task VerifyClassIsNotReportedAsync()
{
var testCode = @"
/// <summary>
/// Foo
/// </summary>
public class ClassName
{
}";

await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}

[Fact]
public async Task VerifyMethodWithNoParametersIsNotReportedAsync()
{
var testCode = @"
public class ClassName
{
/// <summary>
/// Foo
/// </summary>
public void Method() { }
}";

await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}

[Fact]
public async Task TestMemberWithoutDocumentationAsync()
{
Expand Down Expand Up @@ -198,7 +228,7 @@ public class ClassName

[Theory]
[MemberData(nameof(Declarations))]
public async Task TestMembersWithAllDocumentationWrongOrderAsync(string p)
public async Task TestMembersWithAllDocumentationWrongOrderAsync(string declaration)
{
var testCode = @"
/// <summary>
Expand All @@ -212,7 +242,7 @@ public class ClassName
/// <param name=""bar"">Param 2</param>
/// <param name=""new"">Param 3</param>
/// <param name=""foo"">Param 1</param>
$$
$$
}";

var diagnostic = Diagnostic()
Expand All @@ -225,12 +255,29 @@ public class ClassName
diagnostic.WithLocation(12, 22).WithArguments("foo", 1),
};

await VerifyCSharpDiagnosticAsync(testCode.Replace("$$", p), expected, CancellationToken.None).ConfigureAwait(false);
await VerifyCSharpDiagnosticAsync(testCode.Replace("$$", declaration), expected, CancellationToken.None).ConfigureAwait(false);

var testSettings = @"
{
""settings"": {
""documentationRules"": {
""documentExposedElements"": false
}
}
}
";

expected = new[]
{
diagnostic.WithLocation(12, 22).WithArguments("foo", 1),
};

await VerifyCSharpDiagnosticAsync(testCode.Replace("$$", declaration), testSettings, expected, CancellationToken.None).ConfigureAwait(false);
}

[Theory]
[MemberData(nameof(Declarations))]
public async Task TestMembersWithTooManyDocumentationAsync(string p)
public async Task TestMembersWithTooManyDocumentationAsync(string declaration)
{
var testCode = @"
/// <summary>
Expand All @@ -245,15 +292,32 @@ public class ClassName
/// <param name=""bar"">Param 2</param>
/// <param name=""new"">Param 3</param>
/// <param name=""bar"">Param 4</param>
$$
$$
}";

var diagnostic = Diagnostic()
.WithMessageFormat("The parameter documentation for '{0}' should be at position {1}");

var expected = diagnostic.WithLocation(13, 22).WithArguments("bar", 2);

await VerifyCSharpDiagnosticAsync(testCode.Replace("$$", p), expected, CancellationToken.None).ConfigureAwait(false);
await VerifyCSharpDiagnosticAsync(testCode.Replace("$$", declaration), expected, CancellationToken.None).ConfigureAwait(false);
}

[Fact]
public async Task TestDelegateWithoutIdentifierWithTooManyDocumentationIsNotReportedAsync()
{
var testCode = @"
public class ClassName
{
/// <summary>
/// Foo
/// </summary>
/// <param name=""foo"">Param 1</param>
/// <param name=""bar"">Param 2</param>
public delegate void (int foo);
}";

await VerifyCSharpDiagnosticAsync(testCode, testSettings: null, DiagnosticResult.EmptyDiagnosticResults, ignoreCompilerDiagnostics: true, CancellationToken.None).ConfigureAwait(false);
}

[Theory]
Expand All @@ -267,11 +331,23 @@ public async Task VerifyInheritedDocumentationReportsNoDiagnosticsAsync(string d
public class ClassName
{
/// <inheritdoc/>
$$
$$
}";
await VerifyCSharpDiagnosticAsync(testCode.Replace("$$", declaration), DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}

[Fact]
public async Task VerifyIncludedClassIsNotReportedAsync()
{
var testCode = @"
/// <include file='MissingParamDocumentation.xml' path='/ClassName/Method/*' />
public class ClassName
{
}";

await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}

[Fact]
public async Task VerifyIncludedMemberWithoutParamsIsNotReportedAsync()
{
Expand Down Expand Up @@ -303,8 +379,9 @@ public class ClassName
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}

[Fact]
public async Task VerifyIncludedMemberWithValidParamsIsNotReportedAsync()
[Theory]
[MemberData(nameof(Declarations))]
public async Task VerifyIncludedMemberWithValidParamsIsNotReportedAsync(string declaration)
{
var testCode = @"
/// <summary>
Expand All @@ -313,13 +390,14 @@ public async Task VerifyIncludedMemberWithValidParamsIsNotReportedAsync()
public class ClassName
{
/// <include file='WithParamDocumentation.xml' path='/ClassName/Method/*' />
public ClassName Method(string foo, string bar, string @new) { return null; }
$$
}";
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
await VerifyCSharpDiagnosticAsync(testCode.Replace("$$", declaration), DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}

[Fact]
public async Task VerifyIncludedMemberWithInvalidParamsIsReportedAsync()
[Theory]
[MemberData(nameof(Declarations))]
public async Task VerifyIncludedMemberWithInvalidParamsIsReportedAsync(string declaration)
{
var testCode = @"
/// <summary>
Expand All @@ -328,17 +406,17 @@ public async Task VerifyIncludedMemberWithInvalidParamsIsReportedAsync()
public class ClassName
{
/// <include file='WithInvalidParamDocumentation.xml' path='/ClassName/Method/*' />
public ClassName Method(string foo, string bar, string @new) { return null; }
$$
}";

var expected = new[]
{
Diagnostic().WithLocation(8, 22).WithArguments("boo"),
Diagnostic().WithLocation(8, 22).WithArguments("far"),
Diagnostic().WithLocation(8, 22).WithArguments("foe"),
Diagnostic().WithLocation(0).WithArguments("boo"),
Diagnostic().WithLocation(0).WithArguments("far"),
Diagnostic().WithLocation(0).WithArguments("foe"),
};

await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
await VerifyCSharpDiagnosticAsync(testCode.Replace("$$", declaration), expected, CancellationToken.None).ConfigureAwait(false);
}

[Fact]
Expand All @@ -351,35 +429,36 @@ public async Task VerifyIncludedMemberWithInvalidParamsThatShouldBeHandledBySA16
public class ClassName
{
/// <include file='WithSA1613ParamDocumentation.xml' path='/ClassName/Method/*' />
public ClassName Method(string foo, string bar, string @new) { return null; }
public ClassName Method(string foo, string bar, string @new) { return null; }
}";
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}

[Fact]
public async Task VerifyIncludedMemberWithAllDocumentationWrongOrderIsReportedAsync()
[Theory]
[MemberData(nameof(Declarations))]
public async Task VerifyIncludedMemberWithAllDocumentationWrongOrderIsReportedAsync(string declaration)
{
var testCode = @"
/// <summary>
/// Foo
/// </summary>
public class ClassName
{
/// <include file='WithParamDocumentation.xml' path='/ClassName/Method/*' />
public ClassName Method(string bar, string @new, string foo) { return null; }
/// <include file='WithWrongOrderParamDocumentation.xml' path='/ClassName/Method/*' />
$$
}";

var diagnostic = Diagnostic()
.WithMessageFormat("The parameter documentation for '{0}' should be at position {1}");

var expected = new[]
{
diagnostic.WithLocation(8, 22).WithArguments("foo", 3),
diagnostic.WithLocation(8, 22).WithArguments("bar", 1),
diagnostic.WithLocation(8, 22).WithArguments("new", 2),
diagnostic.WithLocation(0).WithArguments("new", 3),
diagnostic.WithLocation(0).WithArguments("foo", 1),
diagnostic.WithLocation(0).WithArguments("bar", 2),
};

await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
await VerifyCSharpDiagnosticAsync(testCode.Replace("$$", declaration), expected, CancellationToken.None).ConfigureAwait(false);

// This is even reported if the documentation is not required, except that no warning is reported for the
// first param element (which is actually the last parameter) since it would otherwise be allowed to skip
Expand All @@ -396,15 +475,16 @@ public class ClassName

expected = new[]
{
diagnostic.WithLocation(8, 22).WithArguments("bar", 1),
diagnostic.WithLocation(8, 22).WithArguments("new", 2),
diagnostic.WithLocation(0).WithArguments("foo", 1),
diagnostic.WithLocation(0).WithArguments("bar", 2),
};

await VerifyCSharpDiagnosticAsync(testCode, testSettings, expected, CancellationToken.None).ConfigureAwait(false);
await VerifyCSharpDiagnosticAsync(testCode.Replace("$$", declaration), testSettings, expected, CancellationToken.None).ConfigureAwait(false);
}

[Fact]
public async Task VerifyIncludedMemberWithTooManyDocumentationIsReportedAsync()
[Theory]
[MemberData(nameof(Declarations))]
public async Task VerifyIncludedMemberWithTooManyDocumentationIsReportedAsync(string declaration)
{
var testCode = @"
/// <summary>
Expand All @@ -413,15 +493,31 @@ public async Task VerifyIncludedMemberWithTooManyDocumentationIsReportedAsync()
public class ClassName
{
/// <include file='WithTooManyParamDocumentation.xml' path='/ClassName/Method/*' />
public ClassName Method(string foo, string bar, string @new) { return null; }
$$
}";

var diagnostic = Diagnostic()
.WithMessageFormat("The parameter documentation for '{0}' should be at position {1}");

var expected = diagnostic.WithLocation(8, 22).WithArguments("bar", 2);
var expected = diagnostic.WithLocation(0).WithArguments("bar", 2);

await VerifyCSharpDiagnosticAsync(testCode.Replace("$$", declaration), expected, CancellationToken.None).ConfigureAwait(false);
}

[Fact]
public async Task VerifyIncludedDelegateWithoutIdentifierWithTooManyDocumentationIsNotReportedAsync()
{
var testCode = @"
/// <summary>
/// Foo
/// </summary>
public class ClassName
{
/// <include file='WithTooManyParamDocumentation.xml' path='/ClassName/Method/*' />
public delegate void (int foo);
}";

await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
await VerifyCSharpDiagnosticAsync(testCode, testSettings: null, DiagnosticResult.EmptyDiagnosticResults, ignoreCompilerDiagnostics: true, CancellationToken.None).ConfigureAwait(false);
}

[Fact]
Expand All @@ -440,12 +536,15 @@ public class ClassName
}

private static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult expected, CancellationToken cancellationToken)
=> VerifyCSharpDiagnosticAsync(source, testSettings: null, new[] { expected }, cancellationToken);
=> VerifyCSharpDiagnosticAsync(source, testSettings: null, new[] { expected }, false, cancellationToken);

private static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult[] expected, CancellationToken cancellationToken)
=> VerifyCSharpDiagnosticAsync(source, testSettings: null, expected, cancellationToken);
=> VerifyCSharpDiagnosticAsync(source, testSettings: null, expected, false, cancellationToken);

private static Task VerifyCSharpDiagnosticAsync(string source, string testSettings, DiagnosticResult[] expected, CancellationToken cancellationToken)
=> VerifyCSharpDiagnosticAsync(source, testSettings, expected, false, cancellationToken);

private static Task VerifyCSharpDiagnosticAsync(string source, string testSettings, DiagnosticResult[] expected, bool ignoreCompilerDiagnostics, CancellationToken cancellationToken)
{
string contentWithoutParamDocumentation = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<ClassName>
Expand All @@ -467,6 +566,18 @@ private static Task VerifyCSharpDiagnosticAsync(string source, string testSettin
<param name=""new"">Param 3</param>
</Method>
</ClassName>
";
string contentWithWrongOrderParamDocumentation = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<ClassName>
<Method>
<summary>
Foo
</summary>
<param name=""new"">Param 3</param>
<param name=""foo"">Param 1</param>
<param name=""bar"">Param 2</param>
</Method>
</ClassName>
";
string contentWithInvalidParamDocumentation = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<ClassName>
Expand Down Expand Up @@ -523,13 +634,19 @@ private static Task VerifyCSharpDiagnosticAsync(string source, string testSettin
{
{ "MissingParamDocumentation.xml", contentWithoutParamDocumentation },
{ "WithParamDocumentation.xml", contentWithParamDocumentation },
{ "WithWrongOrderParamDocumentation.xml", contentWithWrongOrderParamDocumentation },
{ "WithInvalidParamDocumentation.xml", contentWithInvalidParamDocumentation },
{ "WithSA1613ParamDocumentation.xml", contentWithSA1613ParamDocumentation },
{ "WithTooManyParamDocumentation.xml", contentWithTooManyParamDocumentation },
{ "WithInheritedDocumentation.xml", contentWithInheritedDocumentation },
},
};

if (ignoreCompilerDiagnostics)
{
test.CompilerDiagnostics = CompilerDiagnostics.None;
}

test.ExpectedDiagnostics.AddRange(expected);
return test.RunAsync(cancellationToken);
}
Expand Down

0 comments on commit f66d17d

Please sign in to comment.