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

Use Microsoft.CodeAnalysis.Testing for tests #389

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
22 changes: 21 additions & 1 deletion src/FluentAssertions.Analyzers.Tests/CodeFixVerifierArguments.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System.Collections.Generic;
using System.Linq;
using FluentAssertions.Analyzers.TestUtils;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Testing;

namespace FluentAssertions.Analyzers.Tests;

Expand All @@ -26,10 +28,28 @@ public CodeFixVerifierArguments() { }
CodeFixProviders.Add(new TCodeFixProvider());
return this;
}

public CodeFixVerifierArguments WithFixedSources(params string[] fixedSources)
{
FixedSources.AddRange(fixedSources);
return this;
}
}

public class CodeFixVerifierNewArguments<TCodeFix, TAnalyzer>
where TAnalyzer : DiagnosticAnalyzer, new()
where TCodeFix : CodeFixProvider, new()
{
public List<string> Sources { get; } = new();
public List<string> FixedSources { get; } = new();
public List<PackageIdentity> PackageReferences { get; } = new();
public DiagnosticResult ExpectedDiagnostic { get; private set; }

public CodeFixVerifierNewArguments(DiagnosticResult expectedDiagnostic) => ExpectedDiagnostic = expectedDiagnostic;

public CodeFixVerifierNewArguments<TCodeFix, TAnalyzer> WithPackages(params PackageReference[] packages)
{
PackageReferences.AddRange(packages.Select(x => new PackageIdentity(x.Name, x.Version)));
return this;
}
}
2 changes: 1 addition & 1 deletion src/FluentAssertions.Analyzers.Tests/DiagnosticResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public DiagnosticResultLocation(string path, int line, int column)
/// <summary>
/// Struct that stores information about a Diagnostic appearing in a source
/// </summary>
public struct DiagnosticResult
public struct LegacyDiagnosticResult
{
private DiagnosticResultLocation[] locations;

Expand Down
50 changes: 34 additions & 16 deletions src/FluentAssertions.Analyzers.Tests/DiagnosticVerifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
using System.Threading;
using Microsoft.CodeAnalysis.Simplification;
using Microsoft.CodeAnalysis.Formatting;
using Microsoft.CodeAnalysis.CSharp.Testing;
using Microsoft.CodeAnalysis.Testing;
using System.Threading.Tasks;

namespace FluentAssertions.Analyzers.Tests
{
Expand All @@ -20,6 +23,13 @@ namespace FluentAssertions.Analyzers.Tests
/// </summary>
public static class DiagnosticVerifier
{
private class CodeFixVerifier<TCodeFix, TAnalyzer> : CSharpCodeFixVerifier<TAnalyzer, TCodeFix, DefaultVerifier>
where TAnalyzer : DiagnosticAnalyzer, new()
where TCodeFix : CodeFixProvider, new()
{

}

#region CodeFixVerifier

public static void VerifyCSharpFix<TCodeFixProvider, TDiagnosticAnalyzer>(string oldSource, string newSource)
Expand All @@ -38,6 +48,28 @@ public static void VerifyCSharpFix<TCodeFixProvider, TDiagnosticAnalyzer>(string
public static void VerifyFix(CodeFixVerifierArguments arguments)
=> VerifyFix(arguments, arguments.DiagnosticAnalyzers.Single(), arguments.CodeFixProviders.Single(), arguments.FixedSources.Single());

public static async Task VerifyFixAsync<TCodeFix, TAnalyzer>(CodeFixVerifierNewArguments<TCodeFix, TAnalyzer> arguments)
where TAnalyzer : DiagnosticAnalyzer, new()
where TCodeFix : CodeFixProvider, new()
{
var test = new CSharpCodeFixTest<TAnalyzer, TCodeFix, DefaultVerifier>
{
ReferenceAssemblies = ReferenceAssemblies.Net.Net80.AddPackages(arguments.PackageReferences.ToImmutableArray()),
ExpectedDiagnostics = { arguments.ExpectedDiagnostic },
};
foreach (var source in arguments.Sources)
{
test.TestState.Sources.Add(source);
}
foreach (var fixedSource in arguments.FixedSources)
{
test.FixedState.Sources.Add(fixedSource);
}

// TODO: add support for diagnostics (merge test code-fixers with test analyzers).
await test.RunAsync();
}

public static void VerifyNoFix(CodeFixVerifierArguments arguments)
=> VerifyNoFix(arguments, arguments.DiagnosticAnalyzers.Single(), arguments.CodeFixProviders.Single());
private static void VerifyNoFix(CsProjectArguments arguments, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider)
Expand Down Expand Up @@ -274,20 +306,6 @@ private static Diagnostic[] GetSortedDiagnosticsFromDocuments(DiagnosticAnalyzer

#region Verifier wrappers

/// <summary>
/// Called to test a C# DiagnosticAnalyzer when applied on the single inputted string as a source
/// Note: input a DiagnosticResult for each Diagnostic expected
/// </summary>
/// <param name="source">A class in the form of a string to run the analyzer on</param>
/// <param name="expected"> DiagnosticResults that should appear after the analyzer is run on the source</param>
public static void VerifyCSharpDiagnostic<TDiagnosticAnalyzer>(string source, params DiagnosticResult[] expected) where TDiagnosticAnalyzer : DiagnosticAnalyzer, new()
{
VerifyDiagnostic(new DiagnosticVerifierArguments()
.WithDiagnosticAnalyzer<TDiagnosticAnalyzer>()
.WithSources(source)
.WithExpectedDiagnostics(expected));
}

public static void VerifyDiagnostic(DiagnosticVerifierArguments arguments)
{
var project = CsProjectGenerator.CreateProject(arguments);
Expand All @@ -297,7 +315,7 @@ public static void VerifyDiagnostic(DiagnosticVerifierArguments arguments)
VerifyDiagnosticResults(diagnostics, arguments.DiagnosticAnalyzers.ToArray(), arguments.ExpectedDiagnostics.ToArray());
}

public static void VerifyCSharpDiagnosticUsingAllAnalyzers(string source, params DiagnosticResult[] expected)
public static void VerifyCSharpDiagnosticUsingAllAnalyzers(string source, params LegacyDiagnosticResult[] expected)
{
VerifyDiagnostic(new DiagnosticVerifierArguments()
.WithAllAnalyzers()
Expand All @@ -310,7 +328,7 @@ public static void VerifyCSharpDiagnosticUsingAllAnalyzers(string source, params

#region Actual comparisons and verifications

private static void VerifyDiagnosticResults(IEnumerable<Diagnostic> actualResults, DiagnosticAnalyzer[] analyzers, params DiagnosticResult[] expectedResults)
private static void VerifyDiagnosticResults(IEnumerable<Diagnostic> actualResults, DiagnosticAnalyzer[] analyzers, params LegacyDiagnosticResult[] expectedResults)
{
int expectedCount = expectedResults.Length;
int actualCount = actualResults.Count();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace FluentAssertions.Analyzers.Tests;

public class DiagnosticVerifierArguments : CsProjectArguments
{
public List<DiagnosticResult> ExpectedDiagnostics { get; } = new();
public List<LegacyDiagnosticResult> ExpectedDiagnostics { get; } = new();

public List<DiagnosticAnalyzer> DiagnosticAnalyzers { get; } = new();

Expand All @@ -25,7 +25,7 @@ public DiagnosticVerifierArguments WithAllAnalyzers()
return this;
}

public DiagnosticVerifierArguments WithExpectedDiagnostics(params DiagnosticResult[] expectedDiagnostics)
public DiagnosticVerifierArguments WithExpectedDiagnostics(params LegacyDiagnosticResult[] expectedDiagnostics)
{
ExpectedDiagnostics.AddRange(expectedDiagnostics);
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
<PackageReference Include="MSTest.TestAdapter" />
<PackageReference Include="MSTest.TestFramework" />
<PackageReference Include="xunit.assert" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing" />
</ItemGroup>

<ItemGroup>
Expand Down
7 changes: 2 additions & 5 deletions src/FluentAssertions.Analyzers.Tests/Tips/AsyncVoidTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public void AssignAsyncVoidLambdaToAction_TestAnalyzer(string assertion)
{
var source = GenerateCode.AsyncFunctionStatement(assertion);

DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new DiagnosticResult
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new LegacyDiagnosticResult
{
Id = AsyncVoidAnalyzer.DiagnosticId,
Message = AsyncVoidAnalyzer.Message,
Expand All @@ -59,10 +59,7 @@ public void AssignAsyncVoidLambdaToAction_TestAnalyzer(string assertion)
[NotImplemented]
public void AssignAsyncVoidLambdaToAction_TestCodeFix(string oldAssertion, string newAssertion)
{
var oldSource = GenerateCode.AsyncFunctionStatement(oldAssertion);
var newSource = GenerateCode.AsyncFunctionStatement(newAssertion);

DiagnosticVerifier.VerifyCSharpFix<AsyncVoidCodeFix, AsyncVoidAnalyzer>(oldSource, newSource);
// no-op
}
}
}
38 changes: 26 additions & 12 deletions src/FluentAssertions.Analyzers.Tests/Tips/CollectionTests.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
using System.Text;
using System.Threading.Tasks;
using FluentAssertions.Analyzers.TestUtils;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Testing;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace FluentAssertions.Analyzers.Tests
{
[TestClass]
public class CollectionTests
{
[DataTestMethod]
[AssertionDiagnostic("actual.Any().Should().BeTrue({0});")]
[AssertionDiagnostic("actual.AsEnumerable().Any().Should().BeTrue({0}).And.ToString();")]
[AssertionDiagnostic("actual.ToList().Any().Should().BeTrue({0}).And.ToString();")]
[AssertionDiagnostic("actual.ToArray().Any().Should().BeTrue({0}).And.ToString();")]
[Implemented]
public void ExpressionBodyAssertion_TestAnalyzer(string assertion) => VerifyCSharpDiagnosticExpressionBody(assertion, DiagnosticMetadata.CollectionShouldNotBeEmpty_AnyShouldBeTrue);
private static CodeFixVerifierNewArguments<FluentAssertionsCodeFixProvider, FluentAssertionsAnalyzer> CreateCodeFixArguments(string source, string expected, DiagnosticMetadata metadata, LinePosition location)
=> new CodeFixVerifierNewArguments<FluentAssertionsCodeFixProvider, FluentAssertionsAnalyzer>(new DiagnosticResult(FluentAssertionsAnalyzer.DiagnosticId, DiagnosticSeverity.Info)
.WithMessage(metadata.Message)
.WithLocation(location)
)
{
Sources = { source },
FixedSources = { expected },

}.WithPackages(PackageReference.FluentAssertions_6_12_0);

[DataTestMethod]
[AssertionCodeFix(
Expand All @@ -30,7 +36,15 @@ public class CollectionTests
oldAssertion: "actual.ToArray().Any().Should().BeTrue({0}).And.ToString();",
newAssertion: "actual.ToArray().Should().NotBeEmpty({0}).And.ToString();")]
[Implemented]
public void ExpressionBodyAssertion_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFixExpressionBody(oldAssertion, newAssertion);
public async Task ExpressionBodyAssertion_TestCodeFix(string oldAssertion, string newAssertion)
{
var oldSource = GenerateCode.GenericIListExpressionBodyAssertion(oldAssertion);
var newSource = GenerateCode.GenericIListExpressionBodyAssertion(newAssertion);

var arguments = CreateCodeFixArguments(oldSource, newSource, DiagnosticMetadata.CollectionShouldNotBeEmpty_AnyShouldBeTrue, new LinePosition(9, 15));

await DiagnosticVerifier.VerifyFixAsync(arguments);
}

[DataTestMethod]
[AssertionDiagnostic("actual.Any().Should().BeTrue({0});")]
Expand Down Expand Up @@ -634,7 +648,7 @@ public void CollectionShouldContainSingle_TestAnalyzer_GenericIEnumerableShouldR
{
var source = GenerateCode.GenericIEnumerableAssertion(assertion);

DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new DiagnosticResult
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new LegacyDiagnosticResult
{
Id = FluentAssertionsAnalyzer.DiagnosticId,
Message = DiagnosticMetadata.CollectionShouldContainSingle_ShouldHaveCount1.Message,
Expand Down Expand Up @@ -1023,7 +1037,7 @@ private void VerifyCSharpDiagnosticCodeBlock(string sourceAssertion, DiagnosticM
{
var source = GenerateCode.GenericIListCodeBlockAssertion(sourceAssertion);

DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new DiagnosticResult
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new LegacyDiagnosticResult
{
Id = FluentAssertionsAnalyzer.DiagnosticId,
Message = metadata.Message,
Expand All @@ -1040,7 +1054,7 @@ private void VerifyCSharpDiagnosticExpressionBody(string sourceAssertion, Diagno
{
var source = GenerateCode.GenericIListExpressionBodyAssertion(sourceAssertion);

DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new DiagnosticResult
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new LegacyDiagnosticResult
{
Id = FluentAssertionsAnalyzer.DiagnosticId,
VisitorName = metadata.Name,
Expand All @@ -1057,7 +1071,7 @@ private void VerifyArrayCSharpDiagnosticCodeBlock(string sourceAssertion, Diagno
{
var source = GenerateCode.GenericArrayCodeBlockAssertion(sourceAssertion);

DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new DiagnosticResult
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new LegacyDiagnosticResult
{
Id = FluentAssertionsAnalyzer.DiagnosticId,
Message = metadata.Message,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ private void VerifyCSharpDiagnostic(string sourceAssersion, DiagnosticMetadata m
{
var source = GenerateCode.GenericIDictionaryAssertion(sourceAssersion);

DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new DiagnosticResult
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new LegacyDiagnosticResult
{
Id = FluentAssertionsAnalyzer.DiagnosticId,
Message = metadata.Message,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ private void VerifyCSharpDiagnostic(string sourceAssertion, DiagnosticMetadata m
{
var source = GenerateCode.ExceptionAssertion(sourceAssertion);

DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new DiagnosticResult
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new LegacyDiagnosticResult
{
Id = FluentAssertionsAnalyzer.DiagnosticId,
Message = metadata.Message,
Expand Down
36 changes: 35 additions & 1 deletion src/FluentAssertions.Analyzers.Tests/Tips/MsTestTests.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,47 @@
using FluentAssertions.Analyzers.TestUtils;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Text;
using System.Threading.Tasks;

namespace FluentAssertions.Analyzers.Tests.Tips
{
[TestClass]
public class MsTestTests
{
private class AllAnalyzersTest : AnalyzerTest<DefaultVerifier>
{
protected override string DefaultFileExt => "cs";
public override string Language => LanguageNames.CSharp;
private readonly AnalyzerOptions analyzerOptions;
public AllAnalyzersTest(IDictionary<string, string> analyzerConfigOptions = null)
{
analyzerOptions = analyzerConfigOptions != null ? new AnalyzerOptions(ImmutableArray<AdditionalText>.Empty, new TestAnalyzerConfigOptionsProvider(analyzerConfigOptions)) : null;
}

protected override CompilationOptions CreateCompilationOptions() => new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true);
protected override ParseOptions CreateParseOptions() => new CSharpParseOptions(LanguageVersion.Latest, DocumentationMode.Diagnose);
protected override IEnumerable<DiagnosticAnalyzer> GetDiagnosticAnalyzers() => CodeAnalyzersUtils.GetAllAnalyzers();

protected override AnalyzerOptions GetAnalyzerOptions(Project project) => analyzerOptions ?? project.AnalyzerOptions;
}

private class MsTestAnalyzerTest : Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerTest<AssertAnalyzer, DefaultVerifier>
{
private readonly AnalyzerOptions analyzerOptions;
public MsTestAnalyzerTest(IDictionary<string, string> values = null)
{
analyzerOptions = values != null ? new AnalyzerOptions(ImmutableArray<AdditionalText>.Empty, new TestAnalyzerConfigOptionsProvider(values)) : null;
}

protected override AnalyzerOptions GetAnalyzerOptions(Project project) => analyzerOptions;
}

[TestMethod]
[Implemented]
public void SupportExcludingMethods()
Expand Down Expand Up @@ -866,7 +900,7 @@ private void VerifyCSharpDiagnostic(string source)
.WithAllAnalyzers()
.WithSources(source)
.WithPackageReferences(PackageReference.FluentAssertions_6_12_0, PackageReference.MSTestTestFramework_3_1_1)
.WithExpectedDiagnostics(new DiagnosticResult
.WithExpectedDiagnostics(new LegacyDiagnosticResult
{
Id = AssertAnalyzer.MSTestsRule.Id,
Message = AssertAnalyzer.Message,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public void NullConditionalMayNotExecuteTest(string assertion)
.WithDiagnosticAnalyzer<FluentAssertionsAnalyzer>()
.WithSources(Code(assertion))
.WithPackageReferences(PackageReference.FluentAssertions_6_12_0)
.WithExpectedDiagnostics(new DiagnosticResult
.WithExpectedDiagnostics(new LegacyDiagnosticResult
{
Id = FluentAssertionsAnalyzer.DiagnosticId,
Message = DiagnosticMetadata.NullConditionalMayNotExecute.Message,
Expand Down
2 changes: 1 addition & 1 deletion src/FluentAssertions.Analyzers.Tests/Tips/NumericTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ private void VerifyCSharpDiagnostic(string sourceAssertion, DiagnosticMetadata m
.WithSources(source)
.WithAllAnalyzers()
.WithPackageReferences(PackageReference.FluentAssertions_6_12_0)
.WithExpectedDiagnostics(new DiagnosticResult
.WithExpectedDiagnostics(new LegacyDiagnosticResult
{
Id = FluentAssertionsAnalyzer.DiagnosticId,
Message = metadata.Message,
Expand Down
2 changes: 1 addition & 1 deletion src/FluentAssertions.Analyzers.Tests/Tips/NunitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1954,7 +1954,7 @@ private void VerifyDiagnostic(string source, PackageReference nunit)
.WithAllAnalyzers()
.WithSources(source)
.WithPackageReferences(PackageReference.FluentAssertions_6_12_0, nunit)
.WithExpectedDiagnostics(new DiagnosticResult
.WithExpectedDiagnostics(new LegacyDiagnosticResult
{
Id = AssertAnalyzer.NUnitRule.Id,
Message = AssertAnalyzer.Message,
Expand Down
Loading
Loading