Skip to content

Commit df2d4ec

Browse files
committed
Fix documentation check for Expression Body Properties
Introduce DisplayName on tests for better overview in VS2015 test explorer
1 parent d6344b6 commit df2d4ec

2 files changed

Lines changed: 62 additions & 16 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1624UnitTests.cs

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class SA1624UnitTests : CodeFixVerifier
2727
/// <param name="expectedArgument1">The first expected argument for the diagnostic.</param>
2828
/// <param name="expectedArgument2">The second expected argument for the diagnostic.</param>
2929
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
30-
[Theory]
30+
[Theory(DisplayName = "Property Findings")]
3131
[InlineData("public", "int", "get; internal set;", "Gets or sets", "get", "Gets")]
3232
[InlineData("public", "int", "get; private set;", "Gets or sets", "get", "Gets")]
3333
[InlineData("public", "int", "internal get; set;", "Gets or sets", "set", "Sets")]
@@ -85,13 +85,13 @@ public class TestClass
8585
/// <param name="type">The type to use for the property.</param>
8686
/// <param name="summaryPrefix">The prefix to use in the summary text.</param>
8787
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
88-
[Theory]
89-
[InlineData("public", "int", "Gets or sets")]
90-
[InlineData("public", "bool", "Gets or sets a value indicating whether")]
91-
[InlineData("protected", "int", "Gets or sets")]
92-
[InlineData("protected internal", "int", "Gets or sets")]
93-
[InlineData("internal", "int", "Gets or sets")]
94-
public async Task VerifyThatInvalidDocumentationWillReportDiagnosticForExpressionBodyAsync(string accessibility, string type, string summaryPrefix)
88+
[Theory(DisplayName = "ExpressionBody Gets")]
89+
[InlineData("public", "int", "Gets")]
90+
[InlineData("public", "bool", "Gets a value indicating whether")]
91+
[InlineData("protected", "int", "Gets")]
92+
[InlineData("protected internal", "int", "Gets")]
93+
[InlineData("internal", "int", "Gets")]
94+
public async Task VerifyThatValidDocumentationOnExpressionBodyIsAcceptedAsync(string accessibility, string type, string summaryPrefix)
9595
{
9696
var testCode = $@"
9797
public class TestClass
@@ -107,12 +107,58 @@ public class TestClass
107107
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
108108
}
109109

110+
/// <summary>
111+
/// Verifies that documentation that starts with the proper text for multiple accessors will produce a diagnostic for expression body properties.
112+
/// </summary>
113+
/// <param name="accessibility">The accessibility of the property.</param>
114+
/// <param name="type">The type to use for the property.</param>
115+
/// <param name="summaryPrefix">The prefix to use in the summary text.</param>
116+
/// <param name="expectedArgument1">The first expected argument for the diagnostic.</param>
117+
/// <param name="expectedArgument2">The second expected argument for the diagnostic.</param>
118+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
119+
[Theory(DisplayName = "ExpressionBody Gets&Sets")]
120+
[InlineData("public", "int", "Gets or sets", "get", "Gets")]
121+
[InlineData("public", "bool", "Gets or sets a value indicating whether", "get", "Gets a value indicating whether")]
122+
[InlineData("protected", "int", "Gets or sets", "get", "Gets")]
123+
[InlineData("protected internal", "int", "Gets or sets", "get", "Gets")]
124+
[InlineData("internal", "int", "Gets or sets", "get", "Gets")]
125+
public async Task VerifyThatInvalidDocumentationWillReportDiagnosticForExpressionBodyAsync(string accessibility, string type, string summaryPrefix, string expectedArgument1, string expectedArgument2)
126+
{
127+
var testCode = $@"
128+
public class TestClass
129+
{{
130+
/// <summary>
131+
/// {summaryPrefix} the test property.
132+
/// </summary>
133+
{accessibility} {type} TestProperty =>
134+
default({type});
135+
}}
136+
";
137+
138+
var fixedTestCode = $@"
139+
public class TestClass
140+
{{
141+
/// <summary>
142+
/// {expectedArgument2} the test property.
143+
/// </summary>
144+
{accessibility} {type} TestProperty =>
145+
default({type});
146+
}}
147+
";
148+
149+
var expected = this.CSharpDiagnostic(PropertySummaryDocumentationAnalyzer.SA1624Descriptor).WithLocation(7, 7 + accessibility.Length + type.Length).WithArguments(expectedArgument1, expectedArgument2);
150+
151+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
152+
await this.VerifyCSharpDiagnosticAsync(fixedTestCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
153+
await this.VerifyCSharpFixAsync(testCode, fixedTestCode).ConfigureAwait(false);
154+
}
155+
110156
/// <summary>
111157
/// Verify that no diagnostic will be reported when a public and a private accessor are present within a property that is defined in a contained class of a private class.
112158
/// </summary>
113159
/// <param name="typeKeyword">The type keyword to use.</param>
114160
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
115-
[Theory]
161+
[Theory(DisplayName = "PrivateContainer Findings")]
116162
[InlineData("class")]
117163
[InlineData("struct")]
118164
public async Task VerifyPrivateAccessorInPrivateContainerAsync(string typeKeyword)
@@ -139,12 +185,6 @@ public int TestProperty
139185
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
140186
}
141187

142-
/// <inheritdoc/>
143-
protected override IEnumerable<string> GetDisabledDiagnostics()
144-
{
145-
yield return PropertySummaryDocumentationAnalyzer.SA1623Descriptor.Id;
146-
}
147-
148188
/// <inheritdoc/>
149189
protected override CodeFixProvider GetCSharpCodeFixProvider()
150190
{

StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/PropertySummaryDocumentationAnalyzer.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,13 @@ private static void AnalyzeSummaryElement(SyntaxNodeAnalysisContext context, Xml
241241
}
242242
else
243243
{
244-
if (startsWithGetOrSet || !text.StartsWith(startingTextGets, StringComparison.Ordinal))
244+
if (startsWithGetOrSet)
245+
{
246+
diagnosticProperties.Add(ExpectedTextKey, startingTextGets);
247+
diagnosticProperties.Add(TextToRemoveKey, startingTextGetsOrSets);
248+
context.ReportDiagnostic(Diagnostic.Create(SA1624Descriptor, diagnosticLocation, diagnosticProperties.ToImmutable(), "get", startingTextGets));
249+
}
250+
else if (!text.StartsWith(startingTextGets, StringComparison.Ordinal))
245251
{
246252
diagnosticProperties.Add(ExpectedTextKey, startingTextGets);
247253
context.ReportDiagnostic(Diagnostic.Create(SA1623Descriptor, diagnosticLocation, diagnosticProperties.ToImmutable(), startingTextGets));

0 commit comments

Comments
 (0)