Skip to content

Commit b2f4e68

Browse files
Detect more Classic Assert (#791)
* Add ClassicModel Analyzer/CodeFixes for Postive and Negative * Add ClassicModel Analyzer/CodeFixes for (Not)AssignableFrom * "Fix" markdown long lines * Code review changes
1 parent 405d2c4 commit b2f4e68

22 files changed

+2047
-35
lines changed

documentation/NUnit2051.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# NUnit2051
2+
3+
## Consider using Assert.That(expr, Is.Positive) instead of ClassicAssert.Positive(expr)
4+
5+
| Topic | Value
6+
| :-- | :--
7+
| Id | NUnit2051
8+
| Severity | Info
9+
| Enabled | True
10+
| Category | Assertion
11+
| Code | [ClassicModelAssertUsageAnalyzer](https://github.com/nunit/nunit.analyzers/blob/master/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageAnalyzer.cs)
12+
13+
## Description
14+
15+
Consider using the constraint model, `Assert.That(expr, Is.Positive)`, instead of the classic model,
16+
`ClassicAssert.Positive(expr)`.
17+
18+
## Motivation
19+
20+
The classic Assert model contains less flexibility than the constraint model,
21+
so this analyzer marks usages of `ClassicAssert.Positive` from the classic Assert model.
22+
23+
```csharp
24+
[Test]
25+
public void Test()
26+
{
27+
ClassicAssert.Positive(expression);
28+
}
29+
```
30+
31+
## How to fix violations
32+
33+
The analyzer comes with a code fix that will replace `ClassicAssert.Positive(expression)` with
34+
`Assert.That(expression, Is.Positive)`. So the code block above will be changed into.
35+
36+
```csharp
37+
[Test]
38+
public void Test()
39+
{
40+
Assert.That(expression, Is.Positive);
41+
}
42+
```
43+
44+
<!-- start generated config severity -->
45+
## Configure severity
46+
47+
### Via ruleset file
48+
49+
Configure the severity per project, for more info see
50+
[MSDN](https://learn.microsoft.com/en-us/visualstudio/code-quality/using-rule-sets-to-group-code-analysis-rules?view=vs-2022).
51+
52+
### Via .editorconfig file
53+
54+
```ini
55+
# NUnit2051: Consider using Assert.That(expr, Is.Positive) instead of ClassicAssert.Positive(expr)
56+
dotnet_diagnostic.NUnit2051.severity = chosenSeverity
57+
```
58+
59+
where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, or `error`.
60+
61+
### Via #pragma directive
62+
63+
```csharp
64+
#pragma warning disable NUnit2051 // Consider using Assert.That(expr, Is.Positive) instead of ClassicAssert.Positive(expr)
65+
Code violating the rule here
66+
#pragma warning restore NUnit2051 // Consider using Assert.That(expr, Is.Positive) instead of ClassicAssert.Positive(expr)
67+
```
68+
69+
Or put this at the top of the file to disable all instances.
70+
71+
```csharp
72+
#pragma warning disable NUnit2051 // Consider using Assert.That(expr, Is.Positive) instead of ClassicAssert.Positive(expr)
73+
```
74+
75+
### Via attribute `[SuppressMessage]`
76+
77+
```csharp
78+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion",
79+
"NUnit2051:Consider using Assert.That(expr, Is.Positive) instead of ClassicAssert.Positive(expr)",
80+
Justification = "Reason...")]
81+
```
82+
<!-- end generated config severity -->

documentation/NUnit2052.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# NUnit2052
2+
3+
## Consider using Assert.That(expr, Is.Negative) instead of ClassicAssert.Negative(expr)
4+
5+
| Topic | Value
6+
| :-- | :--
7+
| Id | NUnit2052
8+
| Severity | Info
9+
| Enabled | True
10+
| Category | Assertion
11+
| Code | [ClassicModelAssertUsageAnalyzer](https://github.com/nunit/nunit.analyzers/blob/master/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageAnalyzer.cs)
12+
13+
## Description
14+
15+
Consider using the constraint model, `Assert.That(expr, Is.Negative)`, instead of the classic model,
16+
`ClassicAssert.Negative(expr)`.
17+
18+
## Motivation
19+
20+
The classic Assert model contains less flexibility than the constraint model,
21+
so this analyzer marks usages of `ClassicAssert.Negative` from the classic Assert model.
22+
23+
```csharp
24+
[Test]
25+
public void Test()
26+
{
27+
ClassicAssert.Negative(expression);
28+
}
29+
```
30+
31+
## How to fix violations
32+
33+
The analyzer comes with a code fix that will replace `ClassicAssert.Negative(expression)` with
34+
`Assert.That(expression, Is.Negative)`. So the code block above will be changed into.
35+
36+
```csharp
37+
[Test]
38+
public void Test()
39+
{
40+
Assert.That(expression, Is.Negative);
41+
}
42+
```
43+
44+
<!-- start generated config severity -->
45+
## Configure severity
46+
47+
### Via ruleset file
48+
49+
Configure the severity per project, for more info see
50+
[MSDN](https://learn.microsoft.com/en-us/visualstudio/code-quality/using-rule-sets-to-group-code-analysis-rules?view=vs-2022).
51+
52+
### Via .editorconfig file
53+
54+
```ini
55+
# NUnit2052: Consider using Assert.That(expr, Is.Negative) instead of ClassicAssert.Negative(expr)
56+
dotnet_diagnostic.NUnit2052.severity = chosenSeverity
57+
```
58+
59+
where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, or `error`.
60+
61+
### Via #pragma directive
62+
63+
```csharp
64+
#pragma warning disable NUnit2052 // Consider using Assert.That(expr, Is.Negative) instead of ClassicAssert.Negative(expr)
65+
Code violating the rule here
66+
#pragma warning restore NUnit2052 // Consider using Assert.That(expr, Is.Negative) instead of ClassicAssert.Negative(expr)
67+
```
68+
69+
Or put this at the top of the file to disable all instances.
70+
71+
```csharp
72+
#pragma warning disable NUnit2052 // Consider using Assert.That(expr, Is.Negative) instead of ClassicAssert.Negative(expr)
73+
```
74+
75+
### Via attribute `[SuppressMessage]`
76+
77+
```csharp
78+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion",
79+
"NUnit2052:Consider using Assert.That(expr, Is.Negative) instead of ClassicAssert.Negative(expr)",
80+
Justification = "Reason...")]
81+
```
82+
<!-- end generated config severity -->

documentation/NUnit2053.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# NUnit2053
2+
3+
## Consider using Assert.That(actual, Is.AssignableFrom(expected)) instead of ClassicAssert.IsAssignableFrom(expected, actual)
4+
5+
| Topic | Value
6+
| :-- | :--
7+
| Id | NUnit2053
8+
| Severity | Info
9+
| Enabled | True
10+
| Category | Assertion
11+
| Code | [ClassicModelAssertUsageAnalyzer](https://github.com/nunit/nunit.analyzers/blob/master/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageAnalyzer.cs)
12+
13+
## Description
14+
15+
Consider using the constraint model, `Assert.That(actual, Is.AssignableFrom(expected))`, instead of the classic model,
16+
`ClassicAssert.IsAssignableFrom(expected, actual)`.
17+
18+
## Motivation
19+
20+
The assert `ClassicAssert.IsAssignableFrom` from the classic Assert model makes it easy to confuse the `expected` and the
21+
`actual` argument, so this analyzer marks usages of `ClassicAssert.IsAssignableFrom`.
22+
23+
```csharp
24+
[Test]
25+
public void Test()
26+
{
27+
ClassicAssert.IsAssignableFrom(expected, actual);
28+
}
29+
```
30+
31+
## How to fix violations
32+
33+
The analyzer comes with a code fix that will replace `ClassicAssert.IsAssignableFrom(expected, actual)` with
34+
`Assert.That(actual, Is.AssignableFrom(expected))`. So the code block above will be changed into.
35+
36+
```csharp
37+
[Test]
38+
public void Test()
39+
{
40+
Assert.That(actual, Is.AssignableFrom(expected));
41+
}
42+
```
43+
44+
<!-- start generated config severity -->
45+
## Configure severity
46+
47+
### Via ruleset file
48+
49+
Configure the severity per project, for more info see
50+
[MSDN](https://learn.microsoft.com/en-us/visualstudio/code-quality/using-rule-sets-to-group-code-analysis-rules?view=vs-2022).
51+
52+
### Via .editorconfig file
53+
54+
```ini
55+
# NUnit2053: Consider using Assert.That(actual, Is.AssignableFrom(expected)) instead of ClassicAssert.IsAssignableFrom(expected, actual)
56+
dotnet_diagnostic.NUnit2053.severity = chosenSeverity
57+
```
58+
59+
where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, or `error`.
60+
61+
### Via #pragma directive
62+
63+
```csharp
64+
#pragma warning disable NUnit2053 // Consider using Assert.That(actual, Is.AssignableFrom(expected)) instead of ClassicAssert.IsAssignableFrom(expected, actual)
65+
Code violating the rule here
66+
#pragma warning restore NUnit2053 // Consider using Assert.That(actual, Is.AssignableFrom(expected)) instead of ClassicAssert.IsAssignableFrom(expected, actual)
67+
```
68+
69+
Or put this at the top of the file to disable all instances.
70+
71+
```csharp
72+
#pragma warning disable NUnit2053 // Consider using Assert.That(actual, Is.AssignableFrom(expected)) instead of ClassicAssert.IsAssignableFrom(expected, actual)
73+
```
74+
75+
### Via attribute `[SuppressMessage]`
76+
77+
```csharp
78+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion",
79+
"NUnit2053:Consider using Assert.That(actual, Is.AssignableFrom(expected)) instead of ClassicAssert.IsAssignableFrom(expected, actual)",
80+
Justification = "Reason...")]
81+
```
82+
<!-- end generated config severity -->

documentation/NUnit2054.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# NUnit2054
2+
3+
<!-- markdownlint-disable-next-line MD013 -->
4+
## Consider using Assert.That(actual, Is.Not.AssignableFrom(expected)) instead of ClassicAssert.IsNotAssignableFrom(expected, actual)
5+
6+
| Topic | Value
7+
| :-- | :--
8+
| Id | NUnit2054
9+
| Severity | Info
10+
| Enabled | True
11+
| Category | Assertion
12+
| Code | [ClassicModelAssertUsageAnalyzer](https://github.com/nunit/nunit.analyzers/blob/master/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageAnalyzer.cs)
13+
14+
## Description
15+
16+
Consider using the constraint model, `Assert.That(actual, Is.Not.AssignableFrom(expected))`, instead of the classic model,
17+
`ClassicAssert.IsNotAssignableFrom(expected, actual)`.
18+
19+
## Motivation
20+
21+
The assert `ClassicAssert.IsNotAssignableFrom` from the classic Assert model makes it easy to confuse the `expected`
22+
and the `actual` argument, so this analyzer marks usages of `ClassicAssert.IsNotAssignableFrom`.
23+
24+
```csharp
25+
[Test]
26+
public void Test()
27+
{
28+
ClassicAssert.IsNotAssignableFrom(expected, actual);
29+
}
30+
```
31+
32+
## How to fix violations
33+
34+
The analyzer comes with a code fix that will replace `ClassicAssert.IsNotAssignableFrom(expected, actual)` with
35+
`Assert.That(actual, Is.Not.AssignableFrom(expected))`. So the code block above will be changed into.
36+
37+
```csharp
38+
[Test]
39+
public void Test()
40+
{
41+
Assert.That(actual, Is.Not.AssignableFrom(expected));
42+
}
43+
```
44+
45+
<!-- start generated config severity -->
46+
## Configure severity
47+
48+
### Via ruleset file
49+
50+
Configure the severity per project, for more info see
51+
[MSDN](https://learn.microsoft.com/en-us/visualstudio/code-quality/using-rule-sets-to-group-code-analysis-rules?view=vs-2022).
52+
53+
### Via .editorconfig file
54+
55+
```ini
56+
# NUnit2054: Consider using Assert.That(actual, Is.Not.AssignableFrom(expected)) instead of ClassicAssert.IsNotAssignableFrom(expected, actual)
57+
dotnet_diagnostic.NUnit2054.severity = chosenSeverity
58+
```
59+
60+
where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, or `error`.
61+
62+
### Via #pragma directive
63+
64+
```csharp
65+
#pragma warning disable NUnit2054 // Consider using Assert.That(actual, Is.Not.AssignableFrom(expected)) instead of ClassicAssert.IsNotAssignableFrom(expected, actual)
66+
Code violating the rule here
67+
#pragma warning restore NUnit2054 // Consider using Assert.That(actual, Is.Not.AssignableFrom(expected)) instead of ClassicAssert.IsNotAssignableFrom(expected, actual)
68+
```
69+
70+
Or put this at the top of the file to disable all instances.
71+
72+
```csharp
73+
#pragma warning disable NUnit2054 // Consider using Assert.That(actual, Is.Not.AssignableFrom(expected)) instead of ClassicAssert.IsNotAssignableFrom(expected, actual)
74+
```
75+
76+
### Via attribute `[SuppressMessage]`
77+
78+
```csharp
79+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion",
80+
"NUnit2054:Consider using Assert.That(actual, Is.Not.AssignableFrom(expected)) instead of ClassicAssert.IsNotAssignableFrom(expected, actual)",
81+
Justification = "Reason...")]
82+
```
83+
<!-- end generated config severity -->

documentation/index.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ Rules which improve assertions in the test code.
109109
| [NUnit2048](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2048.md) | Consider using Assert.That(...) instead of StringAssert(...) | :white_check_mark: | :warning: | :white_check_mark: |
110110
| [NUnit2049](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2049.md) | Consider using Assert.That(...) instead of CollectionAssert(...) | :white_check_mark: | :warning: | :white_check_mark: |
111111
| [NUnit2050](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2050.md) | NUnit 4 no longer supports string.Format specification | :white_check_mark: | :exclamation: | :white_check_mark: |
112+
| [NUnit2051](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2051.md) | Consider using Assert.That(expr, Is.Positive) instead of ClassicAssert.Positive(expr) | :white_check_mark: | :information_source: | :white_check_mark: |
113+
| [NUnit2052](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2052.md) | Consider using Assert.That(expr, Is.Negative) instead of ClassicAssert.Negative(expr) | :white_check_mark: | :information_source: | :white_check_mark: |
114+
| [NUnit2053](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2053.md) | Consider using Assert.That(actual, Is.AssignableFrom(expected)) instead of ClassicAssert.IsAssignableFrom(expected, actual) | :white_check_mark: | :information_source: | :white_check_mark: |
115+
| [NUnit2054](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2054.md) | Consider using Assert.That(actual, Is.Not.AssignableFrom(expected)) instead of ClassicAssert.IsNotAssignableFrom(expected, actual) | :white_check_mark: | :information_source: | :white_check_mark: |
112116

113117
## Suppressor Rules (NUnit3001 - )
114118

src/nunit.analyzers.sln

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio Version 17
3+
# 17
44
VisualStudioVersion = 17.2.32210.308
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "nunit.analyzers", "nunit.analyzers\nunit.analyzers.csproj", "{74151914-3C12-4EAC-8FD5-5766EBEA35A3}"
@@ -93,6 +93,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "documentation", "documentat
9393
..\documentation\NUnit2048.md = ..\documentation\NUnit2048.md
9494
..\documentation\NUnit2049.md = ..\documentation\NUnit2049.md
9595
..\documentation\NUnit2050.md = ..\documentation\NUnit2050.md
96+
..\documentation\NUnit2051.md = ..\documentation\NUnit2051.md
97+
..\documentation\NUnit2052.md = ..\documentation\NUnit2052.md
98+
..\documentation\NUnit2053.md = ..\documentation\NUnit2053.md
99+
..\documentation\NUnit2054.md = ..\documentation\NUnit2054.md
96100
..\documentation\NUnit3001.md = ..\documentation\NUnit3001.md
97101
..\documentation\NUnit3002.md = ..\documentation\NUnit3002.md
98102
..\documentation\NUnit3003.md = ..\documentation\NUnit3003.md

0 commit comments

Comments
 (0)