Skip to content

Commit

Permalink
Detect more Classic Assert (#791)
Browse files Browse the repository at this point in the history
* Add ClassicModel Analyzer/CodeFixes for Postive and Negative

* Add ClassicModel Analyzer/CodeFixes for (Not)AssignableFrom

* "Fix" markdown long lines

* Code review changes
  • Loading branch information
manfred-brands authored Nov 12, 2024
1 parent 405d2c4 commit b2f4e68
Show file tree
Hide file tree
Showing 22 changed files with 2,047 additions and 35 deletions.
82 changes: 82 additions & 0 deletions documentation/NUnit2051.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# NUnit2051

## Consider using Assert.That(expr, Is.Positive) instead of ClassicAssert.Positive(expr)

| Topic | Value
| :-- | :--
| Id | NUnit2051
| Severity | Info
| Enabled | True
| Category | Assertion
| Code | [ClassicModelAssertUsageAnalyzer](https://github.com/nunit/nunit.analyzers/blob/master/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageAnalyzer.cs)

## Description

Consider using the constraint model, `Assert.That(expr, Is.Positive)`, instead of the classic model,
`ClassicAssert.Positive(expr)`.

## Motivation

The classic Assert model contains less flexibility than the constraint model,
so this analyzer marks usages of `ClassicAssert.Positive` from the classic Assert model.

```csharp
[Test]
public void Test()
{
ClassicAssert.Positive(expression);
}
```

## How to fix violations

The analyzer comes with a code fix that will replace `ClassicAssert.Positive(expression)` with
`Assert.That(expression, Is.Positive)`. So the code block above will be changed into.

```csharp
[Test]
public void Test()
{
Assert.That(expression, Is.Positive);
}
```

<!-- start generated config severity -->
## Configure severity

### Via ruleset file

Configure the severity per project, for more info see
[MSDN](https://learn.microsoft.com/en-us/visualstudio/code-quality/using-rule-sets-to-group-code-analysis-rules?view=vs-2022).

### Via .editorconfig file

```ini
# NUnit2051: Consider using Assert.That(expr, Is.Positive) instead of ClassicAssert.Positive(expr)
dotnet_diagnostic.NUnit2051.severity = chosenSeverity
```

where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, or `error`.

### Via #pragma directive

```csharp
#pragma warning disable NUnit2051 // Consider using Assert.That(expr, Is.Positive) instead of ClassicAssert.Positive(expr)
Code violating the rule here
#pragma warning restore NUnit2051 // Consider using Assert.That(expr, Is.Positive) instead of ClassicAssert.Positive(expr)
```

Or put this at the top of the file to disable all instances.

```csharp
#pragma warning disable NUnit2051 // Consider using Assert.That(expr, Is.Positive) instead of ClassicAssert.Positive(expr)
```

### Via attribute `[SuppressMessage]`

```csharp
[System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion",
"NUnit2051:Consider using Assert.That(expr, Is.Positive) instead of ClassicAssert.Positive(expr)",
Justification = "Reason...")]
```
<!-- end generated config severity -->
82 changes: 82 additions & 0 deletions documentation/NUnit2052.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# NUnit2052

## Consider using Assert.That(expr, Is.Negative) instead of ClassicAssert.Negative(expr)

| Topic | Value
| :-- | :--
| Id | NUnit2052
| Severity | Info
| Enabled | True
| Category | Assertion
| Code | [ClassicModelAssertUsageAnalyzer](https://github.com/nunit/nunit.analyzers/blob/master/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageAnalyzer.cs)

## Description

Consider using the constraint model, `Assert.That(expr, Is.Negative)`, instead of the classic model,
`ClassicAssert.Negative(expr)`.

## Motivation

The classic Assert model contains less flexibility than the constraint model,
so this analyzer marks usages of `ClassicAssert.Negative` from the classic Assert model.

```csharp
[Test]
public void Test()
{
ClassicAssert.Negative(expression);
}
```

## How to fix violations

The analyzer comes with a code fix that will replace `ClassicAssert.Negative(expression)` with
`Assert.That(expression, Is.Negative)`. So the code block above will be changed into.

```csharp
[Test]
public void Test()
{
Assert.That(expression, Is.Negative);
}
```

<!-- start generated config severity -->
## Configure severity

### Via ruleset file

Configure the severity per project, for more info see
[MSDN](https://learn.microsoft.com/en-us/visualstudio/code-quality/using-rule-sets-to-group-code-analysis-rules?view=vs-2022).

### Via .editorconfig file

```ini
# NUnit2052: Consider using Assert.That(expr, Is.Negative) instead of ClassicAssert.Negative(expr)
dotnet_diagnostic.NUnit2052.severity = chosenSeverity
```

where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, or `error`.

### Via #pragma directive

```csharp
#pragma warning disable NUnit2052 // Consider using Assert.That(expr, Is.Negative) instead of ClassicAssert.Negative(expr)
Code violating the rule here
#pragma warning restore NUnit2052 // Consider using Assert.That(expr, Is.Negative) instead of ClassicAssert.Negative(expr)
```

Or put this at the top of the file to disable all instances.

```csharp
#pragma warning disable NUnit2052 // Consider using Assert.That(expr, Is.Negative) instead of ClassicAssert.Negative(expr)
```

### Via attribute `[SuppressMessage]`

```csharp
[System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion",
"NUnit2052:Consider using Assert.That(expr, Is.Negative) instead of ClassicAssert.Negative(expr)",
Justification = "Reason...")]
```
<!-- end generated config severity -->
82 changes: 82 additions & 0 deletions documentation/NUnit2053.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# NUnit2053

## Consider using Assert.That(actual, Is.AssignableFrom(expected)) instead of ClassicAssert.IsAssignableFrom(expected, actual)

| Topic | Value
| :-- | :--
| Id | NUnit2053
| Severity | Info
| Enabled | True
| Category | Assertion
| Code | [ClassicModelAssertUsageAnalyzer](https://github.com/nunit/nunit.analyzers/blob/master/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageAnalyzer.cs)

## Description

Consider using the constraint model, `Assert.That(actual, Is.AssignableFrom(expected))`, instead of the classic model,
`ClassicAssert.IsAssignableFrom(expected, actual)`.

## Motivation

The assert `ClassicAssert.IsAssignableFrom` from the classic Assert model makes it easy to confuse the `expected` and the
`actual` argument, so this analyzer marks usages of `ClassicAssert.IsAssignableFrom`.

```csharp
[Test]
public void Test()
{
ClassicAssert.IsAssignableFrom(expected, actual);
}
```

## How to fix violations

The analyzer comes with a code fix that will replace `ClassicAssert.IsAssignableFrom(expected, actual)` with
`Assert.That(actual, Is.AssignableFrom(expected))`. So the code block above will be changed into.

```csharp
[Test]
public void Test()
{
Assert.That(actual, Is.AssignableFrom(expected));
}
```

<!-- start generated config severity -->
## Configure severity

### Via ruleset file

Configure the severity per project, for more info see
[MSDN](https://learn.microsoft.com/en-us/visualstudio/code-quality/using-rule-sets-to-group-code-analysis-rules?view=vs-2022).

### Via .editorconfig file

```ini
# NUnit2053: Consider using Assert.That(actual, Is.AssignableFrom(expected)) instead of ClassicAssert.IsAssignableFrom(expected, actual)
dotnet_diagnostic.NUnit2053.severity = chosenSeverity
```

where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, or `error`.

### Via #pragma directive

```csharp
#pragma warning disable NUnit2053 // Consider using Assert.That(actual, Is.AssignableFrom(expected)) instead of ClassicAssert.IsAssignableFrom(expected, actual)
Code violating the rule here
#pragma warning restore NUnit2053 // Consider using Assert.That(actual, Is.AssignableFrom(expected)) instead of ClassicAssert.IsAssignableFrom(expected, actual)
```

Or put this at the top of the file to disable all instances.

```csharp
#pragma warning disable NUnit2053 // Consider using Assert.That(actual, Is.AssignableFrom(expected)) instead of ClassicAssert.IsAssignableFrom(expected, actual)
```

### Via attribute `[SuppressMessage]`

```csharp
[System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion",
"NUnit2053:Consider using Assert.That(actual, Is.AssignableFrom(expected)) instead of ClassicAssert.IsAssignableFrom(expected, actual)",
Justification = "Reason...")]
```
<!-- end generated config severity -->
83 changes: 83 additions & 0 deletions documentation/NUnit2054.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# NUnit2054

<!-- markdownlint-disable-next-line MD013 -->
## Consider using Assert.That(actual, Is.Not.AssignableFrom(expected)) instead of ClassicAssert.IsNotAssignableFrom(expected, actual)

| Topic | Value
| :-- | :--
| Id | NUnit2054
| Severity | Info
| Enabled | True
| Category | Assertion
| Code | [ClassicModelAssertUsageAnalyzer](https://github.com/nunit/nunit.analyzers/blob/master/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageAnalyzer.cs)

## Description

Consider using the constraint model, `Assert.That(actual, Is.Not.AssignableFrom(expected))`, instead of the classic model,
`ClassicAssert.IsNotAssignableFrom(expected, actual)`.

## Motivation

The assert `ClassicAssert.IsNotAssignableFrom` from the classic Assert model makes it easy to confuse the `expected`
and the `actual` argument, so this analyzer marks usages of `ClassicAssert.IsNotAssignableFrom`.

```csharp
[Test]
public void Test()
{
ClassicAssert.IsNotAssignableFrom(expected, actual);
}
```

## How to fix violations

The analyzer comes with a code fix that will replace `ClassicAssert.IsNotAssignableFrom(expected, actual)` with
`Assert.That(actual, Is.Not.AssignableFrom(expected))`. So the code block above will be changed into.

```csharp
[Test]
public void Test()
{
Assert.That(actual, Is.Not.AssignableFrom(expected));
}
```

<!-- start generated config severity -->
## Configure severity

### Via ruleset file

Configure the severity per project, for more info see
[MSDN](https://learn.microsoft.com/en-us/visualstudio/code-quality/using-rule-sets-to-group-code-analysis-rules?view=vs-2022).

### Via .editorconfig file

```ini
# NUnit2054: Consider using Assert.That(actual, Is.Not.AssignableFrom(expected)) instead of ClassicAssert.IsNotAssignableFrom(expected, actual)
dotnet_diagnostic.NUnit2054.severity = chosenSeverity
```

where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, or `error`.

### Via #pragma directive

```csharp
#pragma warning disable NUnit2054 // Consider using Assert.That(actual, Is.Not.AssignableFrom(expected)) instead of ClassicAssert.IsNotAssignableFrom(expected, actual)
Code violating the rule here
#pragma warning restore NUnit2054 // Consider using Assert.That(actual, Is.Not.AssignableFrom(expected)) instead of ClassicAssert.IsNotAssignableFrom(expected, actual)
```

Or put this at the top of the file to disable all instances.

```csharp
#pragma warning disable NUnit2054 // Consider using Assert.That(actual, Is.Not.AssignableFrom(expected)) instead of ClassicAssert.IsNotAssignableFrom(expected, actual)
```

### Via attribute `[SuppressMessage]`

```csharp
[System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion",
"NUnit2054:Consider using Assert.That(actual, Is.Not.AssignableFrom(expected)) instead of ClassicAssert.IsNotAssignableFrom(expected, actual)",
Justification = "Reason...")]
```
<!-- end generated config severity -->
4 changes: 4 additions & 0 deletions documentation/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ Rules which improve assertions in the test code.
| [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: |
| [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: |
| [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: |
| [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: |
| [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: |
| [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: |
| [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: |

## Suppressor Rules (NUnit3001 - )

Expand Down
6 changes: 5 additions & 1 deletion src/nunit.analyzers.sln
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
# 17
VisualStudioVersion = 17.2.32210.308
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "nunit.analyzers", "nunit.analyzers\nunit.analyzers.csproj", "{74151914-3C12-4EAC-8FD5-5766EBEA35A3}"
Expand Down Expand Up @@ -93,6 +93,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "documentation", "documentat
..\documentation\NUnit2048.md = ..\documentation\NUnit2048.md
..\documentation\NUnit2049.md = ..\documentation\NUnit2049.md
..\documentation\NUnit2050.md = ..\documentation\NUnit2050.md
..\documentation\NUnit2051.md = ..\documentation\NUnit2051.md
..\documentation\NUnit2052.md = ..\documentation\NUnit2052.md
..\documentation\NUnit2053.md = ..\documentation\NUnit2053.md
..\documentation\NUnit2054.md = ..\documentation\NUnit2054.md
..\documentation\NUnit3001.md = ..\documentation\NUnit3001.md
..\documentation\NUnit3002.md = ..\documentation\NUnit3002.md
..\documentation\NUnit3003.md = ..\documentation\NUnit3003.md
Expand Down
Loading

0 comments on commit b2f4e68

Please sign in to comment.