Skip to content

Commit c9f246f

Browse files
authored
feat: add basic docs for nunit 4 (#343)
1 parent a46d9c2 commit c9f246f

File tree

17 files changed

+547
-231
lines changed

17 files changed

+547
-231
lines changed

FluentAssertions.Analyzers.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{72192514-F
3030
EndProject
3131
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentAssertions.Analyzers.FluentAssertionAnalyzerDocsGenerator", "src\FluentAssertions.Analyzers.FluentAssertionAnalyzerDocsGenerator\FluentAssertions.Analyzers.FluentAssertionAnalyzerDocsGenerator.csproj", "{2871B22C-AEFC-4C33-9BBF-695699E61B57}"
3232
EndProject
33+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentAssertions.Analyzers.FluentAssertionAnalyzerDocs.Nunit4", "src\FluentAssertions.Analyzers.FluentAssertionAnalyzerDocs.Nunit4\FluentAssertions.Analyzers.FluentAssertionAnalyzerDocs.Nunit4.csproj", "{A819A8A5-C8F7-46AD-B0F2-44868070A188}"
34+
EndProject
3335
Global
3436
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3537
Debug|Any CPU = Debug|Any CPU
@@ -60,6 +62,10 @@ Global
6062
{2871B22C-AEFC-4C33-9BBF-695699E61B57}.Debug|Any CPU.Build.0 = Debug|Any CPU
6163
{2871B22C-AEFC-4C33-9BBF-695699E61B57}.Release|Any CPU.ActiveCfg = Release|Any CPU
6264
{2871B22C-AEFC-4C33-9BBF-695699E61B57}.Release|Any CPU.Build.0 = Release|Any CPU
65+
{A819A8A5-C8F7-46AD-B0F2-44868070A188}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
66+
{A819A8A5-C8F7-46AD-B0F2-44868070A188}.Debug|Any CPU.Build.0 = Debug|Any CPU
67+
{A819A8A5-C8F7-46AD-B0F2-44868070A188}.Release|Any CPU.ActiveCfg = Release|Any CPU
68+
{A819A8A5-C8F7-46AD-B0F2-44868070A188}.Release|Any CPU.Build.0 = Release|Any CPU
6369
EndGlobalSection
6470
GlobalSection(SolutionProperties) = preSolution
6571
HideSolutionNode = FALSE
@@ -71,6 +77,7 @@ Global
7177
{FE6D8A05-1383-4BCD-AD65-2EF741E48F44} = {48BE11CB-8BAF-4099-9D93-AE9BB74BB190}
7278
{2F84FE09-8CB4-48AE-A119-671C509213CF} = {72192514-FA22-4699-8EE1-39D34CFE1025}
7379
{2871B22C-AEFC-4C33-9BBF-695699E61B57} = {72192514-FA22-4699-8EE1-39D34CFE1025}
80+
{A819A8A5-C8F7-46AD-B0F2-44868070A188} = {8EFE7955-E63C-4055-A9FF-76C7CE0A1151}
7481
EndGlobalSection
7582
GlobalSection(ExtensibilityGlobals) = postSolution
7683
SolutionGuid = {4BF3D005-625C-4CEC-B3FB-298B956402BE}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ dotnet add package FluentAssertions.Analyzers
3232

3333
- [FluentAssertions Analyzer Docs](docs/FluentAssertionsAnalyzer.md)
3434
- [MsTest Analyzer Docs](docs/MsTestAnalyzer.md)
35+
- [NUnit4 Analyzer Docs](docs/Nunit4Analyzer.md)
3536
- [NUnit3 Analyzer Docs](docs/Nunit3Analyzer.md)
3637

3738
## Getting Started

docs/Nunit4Analyzer.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<!--
2+
This is a generated file, please edit src\FluentAssertions.Analyzers.FluentAssertionAnalyzerDocsGenerator\DocsGenerator.cs to change the contents
3+
-->
4+
5+
# Nunit4 Analyzer Docs
6+
7+
- [BooleanAssertIsTrue](#scenario-booleanassertistrue) - `flag.Should().BeTrue();`
8+
9+
10+
## Scenarios
11+
12+
### scenario: BooleanAssertIsTrue
13+
14+
```cs
15+
// arrange
16+
var flag = true;
17+
18+
// old assertion:
19+
ClassicAssert.IsTrue(flag);
20+
ClassicAssert.True(flag);
21+
Assert.That(flag);
22+
Assert.That(flag, Is.True);
23+
Assert.That(flag, Is.Not.False);
24+
25+
// new assertion:
26+
flag.Should().BeTrue();
27+
```
28+
29+
#### Failure messages
30+
31+
```cs
32+
var flag = false;
33+
34+
// old assertion:
35+
ClassicAssert.True(flag); /* fail message: Assert.That(condition, Is.True)
36+
Expected: True
37+
But was: False
38+
*/
39+
ClassicAssert.IsTrue(flag); /* fail message: Assert.That(condition, Is.True)
40+
Expected: True
41+
But was: False
42+
*/
43+
Assert.That(flag); /* fail message: Assert.That(flag, Is.True)
44+
Expected: True
45+
But was: False
46+
*/
47+
Assert.That(flag, Is.True); /* fail message: Assert.That(flag, Is.True)
48+
Expected: True
49+
But was: False
50+
*/
51+
Assert.That(flag, Is.Not.False); /* fail message: Assert.That(flag, Is.Not.False)
52+
Expected: not False
53+
But was: False
54+
*/
55+
56+
// new assertion:
57+
flag.Should().BeTrue(); /* fail message: Expected flag to be true, but found False. */
58+
```
59+
60+

scripts/generate-docs.ps1

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,6 @@ param (
33
[switch]$ValidateNoChanges
44
)
55

6-
Push-Location src
7-
Push-Location FluentAssertions.Analyzers.FluentAssertionAnalyzerDocsGenerator
8-
dotnet run generate
9-
Pop-Location
10-
Pop-Location
11-
126
if ($ValidateNoChanges) {
137
$output = git status --porcelain=v1 -- docs
148
if ($output) {
@@ -18,4 +12,19 @@ if ($ValidateNoChanges) {
1812
throw "The docs generator has made changes to the docs folder. Please commit these changes and push them to the repository."
1913
}
2014
}
21-
}
15+
}
16+
17+
function GenerateDocs {
18+
param (
19+
[string]$project
20+
)
21+
22+
Push-Location src
23+
Push-Location $project
24+
dotnet run generate
25+
Pop-Location
26+
Pop-Location
27+
}
28+
29+
GenerateDocs -project FluentAssertions.Analyzers.FluentAssertionAnalyzerDocs
30+
GenerateDocs -project FluentAssertions.Analyzers.FluentAssertionAnalyzerDocs.Nunit4

scripts/run-docs-tests.ps1

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,44 @@ param (
22
[switch]$FormatAndExecuteTestsAgain
33
)
44

5-
Push-Location src
6-
Push-Location FluentAssertions.Analyzers.FluentAssertionAnalyzerDocs
7-
dotnet test
8-
Pop-Location
9-
Pop-Location
5+
function RunTestsAndValidate {
6+
param (
7+
[string]$project
8+
)
109

11-
if ($FormatAndExecuteTestsAgain) {
1210
Push-Location src
13-
Push-Location FluentAssertions.Analyzers.FluentAssertionAnalyzerDocs
11+
Push-Location $project
12+
dotnet test
13+
Pop-Location
14+
Pop-Location
1415

15-
$i = 1;
16-
do {
17-
Write-Host "formatting code... - Iteration $i"
18-
$out = dotnet format analyzers --diagnostics FAA0001 FAA0003 FAA0004 --severity info --verbosity normal 2>&1 | Out-String | Join-String
16+
if ($FormatAndExecuteTestsAgain) {
17+
Push-Location src
18+
Push-Location $project
1919

20-
Write-Host "-------------$i-------------"
21-
Write-Host $out
22-
Write-Host "-------------$i-------------"
23-
Write-Host "output length: $($out.Length)"
20+
$i = 1;
21+
do {
22+
Write-Host "formatting code... - Iteration $i"
23+
$out = dotnet format analyzers --diagnostics FAA0001 FAA0003 FAA0004 --severity info --verbosity normal 2>&1 | Out-String | Join-String
2424

25-
$i++
26-
} while ($out.Contains("Unable to fix FAA000"))
25+
Write-Host "-------------$i-------------"
26+
Write-Host $out
27+
Write-Host "-------------$i-------------"
28+
Write-Host "output length: $($out.Length)"
2729

28-
Pop-Location
29-
Pop-Location
30+
$i++
31+
} while ($out.Contains("Unable to fix FAA000"))
3032

31-
Push-Location src
32-
Push-Location FluentAssertions.Analyzers.FluentAssertionAnalyzerDocsGenerator
33-
dotnet run verify
34-
Pop-Location
35-
Pop-Location
33+
Pop-Location
34+
Pop-Location
35+
36+
Push-Location src
37+
Push-Location $project
38+
dotnet test
39+
Pop-Location
40+
Pop-Location
41+
}
3642
}
43+
44+
RunTestsAndValidate -project FluentAssertions.Analyzers.FluentAssertionAnalyzerDocs
45+
RunTestsAndValidate -project FluentAssertions.Analyzers.FluentAssertionAnalyzerDocs.Nunit4
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using System;
2+
using NUnit.Framework;
3+
using NUnit.Framework.Interfaces;
4+
using NUnit.Framework.Internal;
5+
using NUnit.Framework.Internal.Commands;
6+
7+
namespace FluentAssertions.Analyzers.FluentAssertionAnalyzerDocs;
8+
9+
/// <summary>
10+
/// Based on https://github.com/nunit/nunit-csharp-samples/blob/master/ExpectedExceptionExample/ExpectedExceptionAttribute.cs
11+
/// </summary>
12+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
13+
public class ExpectedAssertionExceptionAttribute : NUnitAttribute, IWrapTestMethod
14+
{
15+
public TestCommand Wrap(TestCommand command)
16+
{
17+
return new ExpectedExceptionCommand(command, typeof(AssertionException));
18+
}
19+
20+
private class ExpectedExceptionCommand : DelegatingTestCommand
21+
{
22+
private readonly Type _expectedType;
23+
24+
public ExpectedExceptionCommand(TestCommand innerCommand, Type expectedType)
25+
: base(innerCommand)
26+
{
27+
_expectedType = expectedType;
28+
}
29+
30+
public override TestResult Execute(TestExecutionContext context)
31+
{
32+
Type caughtType = null;
33+
34+
try
35+
{
36+
innerCommand.Execute(context);
37+
}
38+
catch (Exception ex)
39+
{
40+
if (ex is NUnitException)
41+
ex = ex.InnerException;
42+
caughtType = ex.GetType();
43+
}
44+
45+
if (caughtType == _expectedType)
46+
context.CurrentResult.SetResult(ResultState.Success);
47+
else if (caughtType != null)
48+
context.CurrentResult.SetResult(ResultState.Failure,
49+
$"Expected {_expectedType.Name} but got {caughtType.Name}");
50+
else
51+
context.CurrentResult.SetResult(ResultState.Failure,
52+
$"Expected {_expectedType.Name} but no exception was thrown");
53+
54+
return context.CurrentResult;
55+
}
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<IsPackable>false</IsPackable>
7+
<IsTestProject>true</IsTestProject>
8+
<GenerateProgramFile>false</GenerateProgramFile>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
13+
<PackageReference Include="NUnit" Version="4.0.1" />
14+
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
15+
<PackageReference Include="NUnit.Analyzers" Version="3.6.1" />
16+
<PackageReference Include="FluentAssertions" Version="6.12.0" />
17+
<PackageReference Include="coverlet.collector" Version="6.0.0" />
18+
</ItemGroup>
19+
20+
<ItemGroup>
21+
<ProjectReference Include="..\FluentAssertions.Analyzers.FluentAssertionAnalyzerDocsGenerator\FluentAssertions.Analyzers.FluentAssertionAnalyzerDocsGenerator.csproj" />
22+
<ProjectReference Include="..\FluentAssertions.Analyzers\FluentAssertions.Analyzers.csproj" />
23+
<Analyzer Include="..\FluentAssertions.Analyzers\bin\Debug\netstandard2.0\FluentAssertions.Analyzers.dll" />
24+
</ItemGroup>
25+
26+
</Project>
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
using NUnit.Framework;
2+
using NUnit.Framework.Legacy;
3+
4+
namespace FluentAssertions.Analyzers.FluentAssertionAnalyzerDocs;
5+
6+
public class Nunit4AnalyzerTests
7+
{
8+
[Test]
9+
public void BooleanAssertIsTrue()
10+
{
11+
// arrange
12+
var flag = true;
13+
14+
// old assertion:
15+
ClassicAssert.IsTrue(flag);
16+
ClassicAssert.True(flag);
17+
Assert.That(flag);
18+
Assert.That(flag, Is.True);
19+
Assert.That(flag, Is.Not.False);
20+
21+
// new assertion:
22+
flag.Should().BeTrue();
23+
}
24+
25+
[Test, ExpectedAssertionException]
26+
public void BooleanAssertIsTrue_Failure_OldAssertion_0()
27+
{
28+
// arrange
29+
var flag = false;
30+
31+
// old assertion:
32+
ClassicAssert.True(flag);
33+
}
34+
35+
[Test, ExpectedAssertionException]
36+
public void BooleanAssertIsTrue_Failure_OldAssertion_1()
37+
{
38+
// arrange
39+
var flag = false;
40+
41+
// old assertion:
42+
ClassicAssert.IsTrue(flag);
43+
}
44+
45+
[Test, ExpectedAssertionException]
46+
public void BooleanAssertIsTrue_Failure_OldAssertion_2()
47+
{
48+
// arrange
49+
var flag = false;
50+
51+
// old assertion:
52+
Assert.That(flag);
53+
}
54+
55+
[Test, ExpectedAssertionException]
56+
public void BooleanAssertIsTrue_Failure_OldAssertion_3()
57+
{
58+
// arrange
59+
var flag = false;
60+
61+
// old assertion:
62+
Assert.That(flag, Is.True);
63+
}
64+
65+
[Test, ExpectedAssertionException]
66+
public void BooleanAssertIsTrue_Failure_OldAssertion_4()
67+
{
68+
// arrange
69+
var flag = false;
70+
71+
// old assertion:
72+
Assert.That(flag, Is.Not.False);
73+
}
74+
75+
[Test, ExpectedAssertionException]
76+
public void BooleanAssertIsTrue_Failure_NewAssertion()
77+
{
78+
// arrange
79+
var flag = false;
80+
81+
// new assertion:
82+
flag.Should().BeTrue();
83+
}
84+
}

0 commit comments

Comments
 (0)