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

forbid deep inheritance #7

Merged
merged 1 commit into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NUnit.Analyzers/Constants/AnalyzerIdentifiers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ internal static class AnalyzerIdentifiers
{
internal const string TestFieldIsNotReadonly = "NU0001";
internal const string TestUsesSetupAttributes = "NU0002";
internal const string TestDeepInheritanceChain = "NU0003";
}
}
1 change: 1 addition & 0 deletions NUnit.Analyzers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
Couple of nunit analyzers, helpful for parallel tests:
- NU0001 Warning: TestFieldIsNotReadonly
- NU0002 Warning: TestUsesSetupAttributes
- NU0003 Warning: TestDeepInheritanceChain
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System.Collections.Immutable;
using System.Linq;

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;

using SkbKontur.NUnit.Analyzers.Constants;
using SkbKontur.NUnit.Analyzers.Extensions;

namespace SkbKontur.NUnit.Analyzers.TestDeepInheritanceChain
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class TestDeepInheritanceChainAnalyzer : DiagnosticAnalyzer
{
public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
context.EnableConcurrentExecution();
context.RegisterSymbolAction(AnalyzeType, SymbolKind.NamedType);
}

private static void AnalyzeType(SymbolAnalysisContext context)
{
var typeSymbol = (INamedTypeSymbol)context.Symbol;

var hasTests = typeSymbol
.GetMembers()
.OfType<IMethodSymbol>()
.Any(x => x.MethodKind == MethodKind.Ordinary && x.IsTestRelatedMethod(context.Compilation));

if (!hasTests)
return;

var testBase = typeSymbol.BaseType?.BaseType;
if (testBase != null && !knownRoots.Any(r => testBase.IsType(r, context.Compilation)))
context.ReportDiagnostic(Diagnostic.Create(testDeepInheritanceChain, typeSymbol.Locations[0]));
}

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
ImmutableArray.Create(testDeepInheritanceChain);

private static readonly DiagnosticDescriptor testDeepInheritanceChain = new DiagnosticDescriptor(
AnalyzerIdentifiers.TestDeepInheritanceChain,

Check warning on line 43 in NUnit.Analyzers/TestDeepInheritanceChain/TestDeepInheritanceChainAnalyzer.cs

View workflow job for this annotation

GitHub Actions / test

Enable analyzer release tracking for the analyzer project containing rule 'NU0003' (https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md)

Check warning on line 43 in NUnit.Analyzers/TestDeepInheritanceChain/TestDeepInheritanceChainAnalyzer.cs

View workflow job for this annotation

GitHub Actions / test

Enable analyzer release tracking for the analyzer project containing rule 'NU0003' (https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md)

Check warning on line 43 in NUnit.Analyzers/TestDeepInheritanceChain/TestDeepInheritanceChainAnalyzer.cs

View workflow job for this annotation

GitHub Actions / test

Enable analyzer release tracking for the analyzer project containing rule 'NU0003' (https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md)

Check warning on line 43 in NUnit.Analyzers/TestDeepInheritanceChain/TestDeepInheritanceChainAnalyzer.cs

View workflow job for this annotation

GitHub Actions / test

Enable analyzer release tracking for the analyzer project containing rule 'NU0003' (https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md)
TestDeepInheritanceChainConstants.TestDeepInheritanceChainTitle,
TestDeepInheritanceChainConstants.TestDeepInheritanceChainMessage,
Categories.ParallelExecution,
DiagnosticSeverity.Warning,
true,
TestDeepInheritanceChainConstants.TestDeepInheritanceChainDescription,
TestDeepInheritanceChainConstants.TestDeepInheritanceChainUri
);

private static readonly string[] knownRoots =
{
"System.Object",
"SkbKontur.NUnit.Middlewares.SimpleTestBase",
"SkbKontur.NUnit.Middlewares.SimpleSuiteBase",
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace SkbKontur.NUnit.Analyzers.TestDeepInheritanceChain
{
internal static class TestDeepInheritanceChainConstants
{
internal const string TestDeepInheritanceChainTitle = "Test base inheritance chain is too deep";
internal const string TestDeepInheritanceChainMessage = "Test base inheritance chain is too deep";
internal const string TestDeepInheritanceChainDescription = "Test fixture class should have only one base class for clarity.";
internal const string TestDeepInheritanceChainUri = "https://en.wikipedia.org/wiki/Composition_over_inheritance";
}
}
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

A collection of extensions for NUnit.

| | Build Status |
|-------------------------------------|:--------------: |
| NUnit.Middlewares | [![NuGet Status](https://img.shields.io/nuget/v/SkbKontur.NUnit.Middlewares.svg)](https://www.nuget.org/packages/SkbKontur.NUnit.Middlewares/) |
| NUnit.Retries | [![NuGet Status](https://img.shields.io/nuget/v/SkbKontur.NUnit.Retries.svg)](https://www.nuget.org/packages/SkbKontur.NUnit.Retries/) |
| | Build Status |
|-------------------|:--------------: |
| NUnit.Analyzers | [![NuGet Status](https://img.shields.io/nuget/v/SkbKontur.NUnit.Analyzers.svg)](https://www.nuget.org/packages/SkbKontur.NUnit.Analyzers/) |
| NUnit.Middlewares | [![NuGet Status](https://img.shields.io/nuget/v/SkbKontur.NUnit.Middlewares.svg)](https://www.nuget.org/packages/SkbKontur.NUnit.Middlewares/) |
| NUnit.Retries | [![NuGet Status](https://img.shields.io/nuget/v/SkbKontur.NUnit.Retries.svg)](https://www.nuget.org/packages/SkbKontur.NUnit.Retries/) |
| Build | [![Build status](https://github.com/skbkontur/nunit-extensions/actions/workflows/actions.yml/badge.svg)](https://github.com/skbkontur/nunit-extensions/actions) |

## Release Notes
Expand Down
Loading