Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create rule S6513: ExcludeFromCodeCoverage attributes should include a justification #1624

Merged
merged 9 commits into from
Mar 14, 2023
2 changes: 2 additions & 0 deletions rules/S6513/csharp/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
49 changes: 49 additions & 0 deletions rules/S6513/csharp/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
include::../description.adoc[]

== Noncompliant Code Example

[source,csharp]
----
public struct Coordinates
{
public int X { get; }
public int Y { get; }

[ExcludeFromCodeCoverage] // Noncompliant
public override bool Equals(object obj) => obj is Coordinates coordinates && X == coordinates.X && Y == coordinates.Y;

[ExcludeFromCodeCoverage] // Noncompliant
public override int GetHashCode()
{
var hashCode = 1861411795;
hashCode = hashCode * -1521134295 + X.GetHashCode();
hashCode = hashCode * -1521134295 + Y.GetHashCode();
return hashCode;
}
}
----

== Compliant Solution

[source,csharp]
----
public struct Coordinates
{
public int X { get; }
public int Y { get; }

[ExcludeFromCodeCoverage(Justification = "Code generated by Visual Studio refactoring")] // Compliant
public override bool Equals(object obj) => obj is Coordinates coordinates && X == coordinates.X && Y == coordinates.Y;

[ExcludeFromCodeCoverage(Justification = "Code generated by Visual Studio refactoring")] // Compliant
public override int GetHashCode()
{
var hashCode = 1861411795;
hashCode = hashCode * -1521134295 + X.GetHashCode();
hashCode = hashCode * -1521134295 + Y.GetHashCode();
return hashCode;
}
}
----

include::../see.adoc[]
1 change: 1 addition & 0 deletions rules/S6513/description.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The https://learn.microsoft.com/dotnet/api/system.diagnostics.codeanalysis.excludefromcodecoverageattribute[ExcludeFromCodeCoverageAttribute] is used to exclude portions of code from https://learn.microsoft.com/dotnet/core/testing/unit-testing-code-coverage[code coverage reporting]. Code that is not covered by unit tests is a bad practice. In .Net 5, the `Justification` property was added to the `ExcludeFromCodeCoverageAttribute` as an opportunity to document the rationale for the exclusion. This rule raises an issue when no such justification is given.
20 changes: 20 additions & 0 deletions rules/S6513/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"title": "\"ExcludeFromCodeCoverage\" attributes should include a justification",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"bad-practice"
],
"extra": {
},
"defaultSeverity": "Minor",
"ruleSpecification": "RSPEC-6513",
"sqKey": "S6513",
"scope": "Main",
"defaultQualityProfiles": [],
"quickfix": "unknown"
}
4 changes: 4 additions & 0 deletions rules/S6513/see.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
== See

* https://learn.microsoft.com/dotnet/api/system.diagnostics.codeanalysis.excludefromcodecoverageattribute[API browser] - ExcludeFromCodeCoverageAttribute
* https://learn.microsoft.com/dotnet/core/testing/unit-testing-code-coverage[DevOps and testing] - Code coverage reporting
2 changes: 2 additions & 0 deletions rules/S6513/vbnet/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
63 changes: 63 additions & 0 deletions rules/S6513/vbnet/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
include::../description.adoc[]

== Noncompliant Code Example

[source,vbnet]
----
Public Structure Coordinates

Public ReadOnly Property X As Integer
Public ReadOnly Property Y As Integer

<ExcludeFromCodeCoverage> ' Noncompliant
Public Overrides Function Equals(obj As Object) As Boolean
If Not (TypeOf obj Is Coordinates) Then
Return False
End If

Dim coordinates = DirectCast(obj, Coordinates)
Return X = coordinates.X AndAlso
Y = coordinates.Y
End Function

<ExcludeFromCodeCoverage> ' Noncompliant
Public Overrides Function GetHashCode() As Integer
Dim hashCode As Long = 1861411795
hashCode = (hashCode * -1521134295 + X.GetHashCode()).GetHashCode()
martin-strecker-sonarsource marked this conversation as resolved.
Show resolved Hide resolved
hashCode = (hashCode * -1521134295 + Y.GetHashCode()).GetHashCode()
Return hashCode
End Function
End Structure
----

== Compliant Solution

[source,vbnet]
----
Public Structure Coordinates

Public ReadOnly Property X As Integer
Public ReadOnly Property Y As Integer

<ExcludeFromCodeCoverage(Justification:="Code generated by Visual Studio refactoring")> ' Compliant
Public Overrides Function Equals(obj As Object) As Boolean
If Not (TypeOf obj Is Coordinates) Then
Return False
End If

Dim coordinates = DirectCast(obj, Coordinates)
Return X = coordinates.X AndAlso
Y = coordinates.Y
End Function

<ExcludeFromCodeCoverage(Justification:="Code generated by Visual Studio refactoring")> ' Compliant
Public Overrides Function GetHashCode() As Integer
Dim hashCode As Long = 1861411795
hashCode = (hashCode * -1521134295 + X.GetHashCode()).GetHashCode()
hashCode = (hashCode * -1521134295 + Y.GetHashCode()).GetHashCode()
Return hashCode
End Function
End Structure
----

include::../see.adoc[]