Skip to content
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
12 changes: 6 additions & 6 deletions TUnit.Analyzers.Tests/TUnit.Analyzers.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@

<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" VersionOverride="9.0.0" PrivateAssets="all" GeneratePathProperty="true" />
<Reference Include="$(PkgMicrosoft_CodeAnalysis_NetAnalyzers)\analyzers\dotnet\cs\Microsoft.CodeAnalysis.NetAnalyzers.dll" />
<Reference Include="$(PkgMicrosoft_CodeAnalysis_NetAnalyzers)\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.NetAnalyzers.dll" />
<Reference Include="$(PkgMicrosoft_CodeAnalysis_NetAnalyzers)\analyzers\dotnet\cs\Microsoft.CodeAnalysis.NetAnalyzers.dll" Analyzer="false" />
<Reference Include="$(PkgMicrosoft_CodeAnalysis_NetAnalyzers)\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.NetAnalyzers.dll" Analyzer="false" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" VersionOverride="9.0.0" PrivateAssets="all" GeneratePathProperty="true" />
<Reference Include="$(PkgMicrosoft_CodeAnalysis_NetAnalyzers)\analyzers\dotnet\cs\Microsoft.CodeAnalysis.NetAnalyzers.dll" />
<Reference Include="$(PkgMicrosoft_CodeAnalysis_NetAnalyzers)\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.NetAnalyzers.dll" />
<Reference Include="$(PkgMicrosoft_CodeAnalysis_NetAnalyzers)\analyzers\dotnet\cs\Microsoft.CodeAnalysis.NetAnalyzers.dll" Analyzer="false" />
<Reference Include="$(PkgMicrosoft_CodeAnalysis_NetAnalyzers)\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.NetAnalyzers.dll" Analyzer="false" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net10.0'">
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" VersionOverride="9.0.0" PrivateAssets="all" GeneratePathProperty="true" />
<Reference Include="$(PkgMicrosoft_CodeAnalysis_NetAnalyzers)\analyzers\dotnet\cs\Microsoft.CodeAnalysis.NetAnalyzers.dll" />
<Reference Include="$(PkgMicrosoft_CodeAnalysis_NetAnalyzers)\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.NetAnalyzers.dll" />
<Reference Include="$(PkgMicrosoft_CodeAnalysis_NetAnalyzers)\analyzers\dotnet\cs\Microsoft.CodeAnalysis.NetAnalyzers.dll" Analyzer="false" />
<Reference Include="$(PkgMicrosoft_CodeAnalysis_NetAnalyzers)\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.NetAnalyzers.dll" Analyzer="false" />
</ItemGroup>

<Import Project="..\TestProject.targets" />
Expand Down
7 changes: 6 additions & 1 deletion TUnit.Analyzers.Tests/Verifiers/CSharpAnalyzerVerifier.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Testing;
Expand Down Expand Up @@ -42,7 +43,11 @@ public Test()
}

compilationOptions = compilationOptions
.WithSpecificDiagnosticOptions(compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings));
.WithSpecificDiagnosticOptions(compilationOptions.SpecificDiagnosticOptions
.SetItems(CSharpVerifierHelper.NullableWarnings)
// Suppress analyzer release tracking warnings - we're testing TUnit analyzers, not release tracking
.SetItem("RS2007", ReportDiagnostic.Suppress)
.SetItem("RS2008", ReportDiagnostic.Suppress));

solution = solution.WithProjectCompilationOptions(projectId, compilationOptions)
.WithProjectParseOptions(projectId, parseOptions
Expand Down
9 changes: 8 additions & 1 deletion TUnit.Analyzers.Tests/Verifiers/CSharpCodeFixVerifier.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Testing;
Expand Down Expand Up @@ -35,7 +37,12 @@ public Test()
return solution;
}

compilationOptions = compilationOptions.WithSpecificDiagnosticOptions(compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings));
compilationOptions = compilationOptions
.WithSpecificDiagnosticOptions(compilationOptions.SpecificDiagnosticOptions
.SetItems(CSharpVerifierHelper.NullableWarnings)
// Suppress analyzer release tracking warnings - we're testing TUnit analyzers, not release tracking
.SetItem("RS2007", ReportDiagnostic.Suppress)
.SetItem("RS2008", ReportDiagnostic.Suppress));

solution = solution.WithProjectCompilationOptions(projectId, compilationOptions)
.WithProjectParseOptions(projectId, parseOptions.WithLanguageVersion(LanguageVersion.Preview));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Testing;
Expand Down Expand Up @@ -33,7 +34,12 @@ public Test()
return solution;
}

compilationOptions = compilationOptions.WithSpecificDiagnosticOptions(compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings));
compilationOptions = compilationOptions
.WithSpecificDiagnosticOptions(compilationOptions.SpecificDiagnosticOptions
.SetItems(CSharpVerifierHelper.NullableWarnings)
// Suppress analyzer release tracking warnings - we're testing TUnit analyzers, not release tracking
.SetItem("RS2007", ReportDiagnostic.Suppress)
.SetItem("RS2008", ReportDiagnostic.Suppress));

solution = solution.WithProjectCompilationOptions(projectId, compilationOptions)
.WithProjectParseOptions(projectId, parseOptions.WithLanguageVersion(LanguageVersion.Preview));
Expand Down
186 changes: 186 additions & 0 deletions TUnit.Assertions.Analyzers.Tests/AnalyzerTestHelpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
using System.Collections.Immutable;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Testing;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Testing;

namespace TUnit.Assertions.Analyzers.Tests;

public static class AnalyzerTestHelpers
{
public static CSharpAnalyzerTest<TAnalyzer, DefaultVerifier> CreateAnalyzerTest<TAnalyzer>(
[StringSyntax("c#-test")] string inputSource
)
where TAnalyzer : DiagnosticAnalyzer, new()
{
var csTest = new CSharpAnalyzerTest<TAnalyzer, DefaultVerifier>
{
TestState =
{
Sources = { inputSource },
ReferenceAssemblies = new ReferenceAssemblies(
"net8.0",
new PackageIdentity(
"Microsoft.NETCore.App.Ref",
"8.0.0"),
Path.Combine("ref", "net8.0")),
},
};

csTest.TestState.AdditionalReferences
.AddRange(
[
MetadataReference.CreateFromFile(typeof(TUnitAttribute).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Assert).Assembly.Location),
]
);

return csTest;
}

public sealed class CSharpSuppressorTest<TSuppressor, TVerifier> : CSharpAnalyzerTest<TSuppressor, TVerifier>
where TSuppressor : DiagnosticSuppressor, new()
where TVerifier : IVerifier, new()
{
private readonly List<DiagnosticAnalyzer> _analyzers = [];

protected override IEnumerable<DiagnosticAnalyzer> GetDiagnosticAnalyzers()
{
return base.GetDiagnosticAnalyzers().Concat(_analyzers);
}

public CSharpSuppressorTest<TSuppressor, TVerifier> WithAnalyzer<TAnalyzer>(bool enableDiagnostics = false)
where TAnalyzer : DiagnosticAnalyzer, new()
{
var analyzer = new TAnalyzer();
_analyzers.Add(analyzer);

if (enableDiagnostics)
{
var diagnosticOptions = analyzer.SupportedDiagnostics
.ToImmutableDictionary(
descriptor => descriptor.Id,
descriptor => descriptor.DefaultSeverity.ToReportDiagnostic()
);

SolutionTransforms.Clear();
SolutionTransforms.Add(EnableDiagnostics(diagnosticOptions));
}

return this;
}

public CSharpSuppressorTest<TSuppressor, TVerifier> WithSpecificDiagnostics(
params DiagnosticResult[] diagnostics
)
{
var diagnosticOptions = diagnostics
.ToImmutableDictionary(
descriptor => descriptor.Id,
descriptor => descriptor.Severity.ToReportDiagnostic()
);

SolutionTransforms.Clear();
SolutionTransforms.Add(EnableDiagnostics(diagnosticOptions));
return this;
}

private static Func<Solution, ProjectId, Solution> EnableDiagnostics(
ImmutableDictionary<string, ReportDiagnostic> diagnostics
) =>
(solution, id) =>
{
var options = solution.GetProject(id)?.CompilationOptions
?? throw new InvalidOperationException("Compilation options missing.");

return solution
.WithProjectCompilationOptions(
id,
options
.WithSpecificDiagnosticOptions(diagnostics)
);
};

public CSharpSuppressorTest<TSuppressor, TVerifier> WithExpectedDiagnosticsResults(
params DiagnosticResult[] diagnostics
)
{
ExpectedDiagnostics.AddRange(diagnostics);
return this;
}

public CSharpSuppressorTest<TSuppressor, TVerifier> WithCompilerDiagnostics(
CompilerDiagnostics diagnostics
)
{
CompilerDiagnostics = diagnostics;
return this;
}

public CSharpSuppressorTest<TSuppressor, TVerifier> IgnoringDiagnostics(params string[] diagnostics)
{
DisabledDiagnostics.AddRange(diagnostics);
return this;
}
}

public static CSharpSuppressorTest<TSuppressor, DefaultVerifier> CreateSuppressorTest<TSuppressor>(
[StringSyntax("c#-test")] string inputSource
)
where TSuppressor : DiagnosticSuppressor, new()
{
var test = new CSharpSuppressorTest<TSuppressor, DefaultVerifier>
{
TestCode = inputSource,
ReferenceAssemblies = GetReferenceAssemblies()
};

test.TestState.AdditionalReferences
.AddRange([
MetadataReference.CreateFromFile(typeof(TUnitAttribute).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Assert).Assembly.Location),
]);

return test;
}

private static ReferenceAssemblies GetReferenceAssemblies()
{
#if NET472
return ReferenceAssemblies.NetFramework.Net472.Default;
#elif NET8_0
return ReferenceAssemblies.Net.Net80;
#elif NET9_0
return ReferenceAssemblies.Net.Net90;
#elif NET10_0_OR_GREATER
return ReferenceAssemblies.Net.Net90;
#else
return ReferenceAssemblies.Net.Net80; // Default fallback
#endif
}

public static CSharpSuppressorTest<TSuppressor, DefaultVerifier> CreateSuppressorTest<TSuppressor, TAnalyzer>(
[StringSyntax("c#-test")] string inputSource
)
where TSuppressor : DiagnosticSuppressor, new()
where TAnalyzer : DiagnosticAnalyzer, new()
{
return CreateSuppressorTest<TSuppressor>(inputSource)
.WithAnalyzer<TAnalyzer>(enableDiagnostics: true);
}
}

static file class DiagnosticSeverityExtensions
{
public static ReportDiagnostic ToReportDiagnostic(this DiagnosticSeverity severity)
=> severity switch
{
DiagnosticSeverity.Hidden => ReportDiagnostic.Hidden,
DiagnosticSeverity.Info => ReportDiagnostic.Info,
DiagnosticSeverity.Warning => ReportDiagnostic.Warn,
DiagnosticSeverity.Error => ReportDiagnostic.Error,
_ => throw new InvalidEnumArgumentException(nameof(severity), (int) severity, typeof(DiagnosticSeverity)),
};
}
Loading
Loading