Skip to content

Commit ed15531

Browse files
committed
some progress
1 parent 4d7c385 commit ed15531

17 files changed

+134
-49
lines changed

src/FluentAssertions.Analyzers.Tests/CodeFixVerifierArguments.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using System.Collections.Generic;
2+
using System.Linq;
23
using FluentAssertions.Analyzers.TestUtils;
34
using Microsoft.CodeAnalysis.CodeFixes;
45
using Microsoft.CodeAnalysis.Diagnostics;
6+
using Microsoft.CodeAnalysis.Testing;
57

68
namespace FluentAssertions.Analyzers.Tests;
79

@@ -26,10 +28,28 @@ public CodeFixVerifierArguments() { }
2628
CodeFixProviders.Add(new TCodeFixProvider());
2729
return this;
2830
}
29-
31+
3032
public CodeFixVerifierArguments WithFixedSources(params string[] fixedSources)
3133
{
3234
FixedSources.AddRange(fixedSources);
3335
return this;
3436
}
37+
}
38+
39+
public class CodeFixVerifierNewArguments<TCodeFix, TAnalyzer>
40+
where TAnalyzer : DiagnosticAnalyzer, new()
41+
where TCodeFix : CodeFixProvider, new()
42+
{
43+
public List<string> Sources { get; } = new();
44+
public List<string> FixedSources { get; } = new();
45+
public List<PackageIdentity> PackageReferences { get; } = new();
46+
public DiagnosticResult ExpectedDiagnostic { get; private set; }
47+
48+
public CodeFixVerifierNewArguments(DiagnosticResult expectedDiagnostic) => ExpectedDiagnostic = expectedDiagnostic;
49+
50+
public CodeFixVerifierNewArguments<TCodeFix, TAnalyzer> WithPackages(params PackageReference[] packages)
51+
{
52+
PackageReferences.AddRange(packages.Select(x => new PackageIdentity(x.Name, x.Version)));
53+
return this;
54+
}
3555
}

src/FluentAssertions.Analyzers.Tests/DiagnosticResult.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public DiagnosticResultLocation(string path, int line, int column)
3333
/// <summary>
3434
/// Struct that stores information about a Diagnostic appearing in a source
3535
/// </summary>
36-
public struct DiagnosticResult
36+
public struct LegacyDiagnosticResult
3737
{
3838
private DiagnosticResultLocation[] locations;
3939

src/FluentAssertions.Analyzers.Tests/DiagnosticVerifier.cs

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
using System.Threading;
1313
using Microsoft.CodeAnalysis.Simplification;
1414
using Microsoft.CodeAnalysis.Formatting;
15+
using Microsoft.CodeAnalysis.CSharp.Testing;
16+
using Microsoft.CodeAnalysis.Testing;
17+
using System.Threading.Tasks;
1518

1619
namespace FluentAssertions.Analyzers.Tests
1720
{
@@ -20,6 +23,13 @@ namespace FluentAssertions.Analyzers.Tests
2023
/// </summary>
2124
public static class DiagnosticVerifier
2225
{
26+
private class CodeFixVerifier<TCodeFix, TAnalyzer> : CSharpCodeFixVerifier<TAnalyzer, TCodeFix, DefaultVerifier>
27+
where TAnalyzer : DiagnosticAnalyzer, new()
28+
where TCodeFix : CodeFixProvider, new()
29+
{
30+
31+
}
32+
2333
#region CodeFixVerifier
2434

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

51+
public static async Task VerifyFixAsync<TCodeFix, TAnalyzer>(CodeFixVerifierNewArguments<TCodeFix, TAnalyzer> arguments)
52+
where TAnalyzer : DiagnosticAnalyzer, new()
53+
where TCodeFix : CodeFixProvider, new()
54+
{
55+
var test = new CSharpCodeFixTest<TAnalyzer, TCodeFix, DefaultVerifier>
56+
{
57+
ReferenceAssemblies = ReferenceAssemblies.Net.Net80.AddPackages(arguments.PackageReferences.ToImmutableArray()),
58+
ExpectedDiagnostics = { arguments.ExpectedDiagnostic },
59+
};
60+
foreach (var source in arguments.Sources)
61+
{
62+
test.TestState.Sources.Add(source);
63+
}
64+
foreach (var fixedSource in arguments.FixedSources)
65+
{
66+
test.FixedState.Sources.Add(fixedSource);
67+
}
68+
69+
// TODO: add support for diagnostics (merge test code-fixers with test analyzers).
70+
await test.RunAsync();
71+
}
72+
4173
public static void VerifyNoFix(CodeFixVerifierArguments arguments)
4274
=> VerifyNoFix(arguments, arguments.DiagnosticAnalyzers.Single(), arguments.CodeFixProviders.Single());
4375
private static void VerifyNoFix(CsProjectArguments arguments, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider)
@@ -274,20 +306,6 @@ private static Diagnostic[] GetSortedDiagnosticsFromDocuments(DiagnosticAnalyzer
274306

275307
#region Verifier wrappers
276308

277-
/// <summary>
278-
/// Called to test a C# DiagnosticAnalyzer when applied on the single inputted string as a source
279-
/// Note: input a DiagnosticResult for each Diagnostic expected
280-
/// </summary>
281-
/// <param name="source">A class in the form of a string to run the analyzer on</param>
282-
/// <param name="expected"> DiagnosticResults that should appear after the analyzer is run on the source</param>
283-
public static void VerifyCSharpDiagnostic<TDiagnosticAnalyzer>(string source, params DiagnosticResult[] expected) where TDiagnosticAnalyzer : DiagnosticAnalyzer, new()
284-
{
285-
VerifyDiagnostic(new DiagnosticVerifierArguments()
286-
.WithDiagnosticAnalyzer<TDiagnosticAnalyzer>()
287-
.WithSources(source)
288-
.WithExpectedDiagnostics(expected));
289-
}
290-
291309
public static void VerifyDiagnostic(DiagnosticVerifierArguments arguments)
292310
{
293311
var project = CsProjectGenerator.CreateProject(arguments);
@@ -297,7 +315,7 @@ public static void VerifyDiagnostic(DiagnosticVerifierArguments arguments)
297315
VerifyDiagnosticResults(diagnostics, arguments.DiagnosticAnalyzers.ToArray(), arguments.ExpectedDiagnostics.ToArray());
298316
}
299317

300-
public static void VerifyCSharpDiagnosticUsingAllAnalyzers(string source, params DiagnosticResult[] expected)
318+
public static void VerifyCSharpDiagnosticUsingAllAnalyzers(string source, params LegacyDiagnosticResult[] expected)
301319
{
302320
VerifyDiagnostic(new DiagnosticVerifierArguments()
303321
.WithAllAnalyzers()
@@ -310,7 +328,7 @@ public static void VerifyCSharpDiagnosticUsingAllAnalyzers(string source, params
310328

311329
#region Actual comparisons and verifications
312330

313-
private static void VerifyDiagnosticResults(IEnumerable<Diagnostic> actualResults, DiagnosticAnalyzer[] analyzers, params DiagnosticResult[] expectedResults)
331+
private static void VerifyDiagnosticResults(IEnumerable<Diagnostic> actualResults, DiagnosticAnalyzer[] analyzers, params LegacyDiagnosticResult[] expectedResults)
314332
{
315333
int expectedCount = expectedResults.Length;
316334
int actualCount = actualResults.Count();

src/FluentAssertions.Analyzers.Tests/DiagnosticVerifierArguments.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace FluentAssertions.Analyzers.Tests;
66

77
public class DiagnosticVerifierArguments : CsProjectArguments
88
{
9-
public List<DiagnosticResult> ExpectedDiagnostics { get; } = new();
9+
public List<LegacyDiagnosticResult> ExpectedDiagnostics { get; } = new();
1010

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

@@ -25,7 +25,7 @@ public DiagnosticVerifierArguments WithAllAnalyzers()
2525
return this;
2626
}
2727

28-
public DiagnosticVerifierArguments WithExpectedDiagnostics(params DiagnosticResult[] expectedDiagnostics)
28+
public DiagnosticVerifierArguments WithExpectedDiagnostics(params LegacyDiagnosticResult[] expectedDiagnostics)
2929
{
3030
ExpectedDiagnostics.AddRange(expectedDiagnostics);
3131
return this;

src/FluentAssertions.Analyzers.Tests/FluentAssertions.Analyzers.Tests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
<PackageReference Include="MSTest.TestAdapter" />
1717
<PackageReference Include="MSTest.TestFramework" />
1818
<PackageReference Include="xunit.assert" />
19+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing" />
20+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing" />
1921
</ItemGroup>
2022

2123
<ItemGroup>

src/FluentAssertions.Analyzers.Tests/Tips/AsyncVoidTests.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void AssignAsyncVoidLambdaToAction_TestAnalyzer(string assertion)
3737
{
3838
var source = GenerateCode.AsyncFunctionStatement(assertion);
3939

40-
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new DiagnosticResult
40+
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new LegacyDiagnosticResult
4141
{
4242
Id = AsyncVoidAnalyzer.DiagnosticId,
4343
Message = AsyncVoidAnalyzer.Message,
@@ -59,10 +59,7 @@ public void AssignAsyncVoidLambdaToAction_TestAnalyzer(string assertion)
5959
[NotImplemented]
6060
public void AssignAsyncVoidLambdaToAction_TestCodeFix(string oldAssertion, string newAssertion)
6161
{
62-
var oldSource = GenerateCode.AsyncFunctionStatement(oldAssertion);
63-
var newSource = GenerateCode.AsyncFunctionStatement(newAssertion);
64-
65-
DiagnosticVerifier.VerifyCSharpFix<AsyncVoidCodeFix, AsyncVoidAnalyzer>(oldSource, newSource);
62+
// no-op
6663
}
6764
}
6865
}

src/FluentAssertions.Analyzers.Tests/Tips/CollectionTests.cs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
using System.Text;
2+
using System.Threading.Tasks;
23
using FluentAssertions.Analyzers.TestUtils;
34
using Microsoft.CodeAnalysis;
5+
using Microsoft.CodeAnalysis.Testing;
6+
using Microsoft.CodeAnalysis.Text;
47
using Microsoft.VisualStudio.TestTools.UnitTesting;
58

69
namespace FluentAssertions.Analyzers.Tests
710
{
811
[TestClass]
912
public class CollectionTests
1013
{
11-
[DataTestMethod]
12-
[AssertionDiagnostic("actual.Any().Should().BeTrue({0});")]
13-
[AssertionDiagnostic("actual.AsEnumerable().Any().Should().BeTrue({0}).And.ToString();")]
14-
[AssertionDiagnostic("actual.ToList().Any().Should().BeTrue({0}).And.ToString();")]
15-
[AssertionDiagnostic("actual.ToArray().Any().Should().BeTrue({0}).And.ToString();")]
16-
[Implemented]
17-
public void ExpressionBodyAssertion_TestAnalyzer(string assertion) => VerifyCSharpDiagnosticExpressionBody(assertion, DiagnosticMetadata.CollectionShouldNotBeEmpty_AnyShouldBeTrue);
14+
private static CodeFixVerifierNewArguments<FluentAssertionsCodeFixProvider, FluentAssertionsAnalyzer> CreateCodeFixArguments(string source, string expected, DiagnosticMetadata metadata, LinePosition location)
15+
=> new CodeFixVerifierNewArguments<FluentAssertionsCodeFixProvider, FluentAssertionsAnalyzer>(new DiagnosticResult(FluentAssertionsAnalyzer.DiagnosticId, DiagnosticSeverity.Info)
16+
.WithMessage(metadata.Message)
17+
.WithLocation(location)
18+
)
19+
{
20+
Sources = { source },
21+
FixedSources = { expected },
22+
23+
}.WithPackages(PackageReference.FluentAssertions_6_12_0);
1824

1925
[DataTestMethod]
2026
[AssertionCodeFix(
@@ -30,7 +36,15 @@ public class CollectionTests
3036
oldAssertion: "actual.ToArray().Any().Should().BeTrue({0}).And.ToString();",
3137
newAssertion: "actual.ToArray().Should().NotBeEmpty({0}).And.ToString();")]
3238
[Implemented]
33-
public void ExpressionBodyAssertion_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFixExpressionBody(oldAssertion, newAssertion);
39+
public async Task ExpressionBodyAssertion_TestCodeFix(string oldAssertion, string newAssertion)
40+
{
41+
var oldSource = GenerateCode.GenericIListExpressionBodyAssertion(oldAssertion);
42+
var newSource = GenerateCode.GenericIListExpressionBodyAssertion(newAssertion);
43+
44+
var arguments = CreateCodeFixArguments(oldSource, newSource, DiagnosticMetadata.CollectionShouldNotBeEmpty_AnyShouldBeTrue, new LinePosition(9, 15));
45+
46+
await DiagnosticVerifier.VerifyFixAsync(arguments);
47+
}
3448

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

637-
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new DiagnosticResult
651+
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new LegacyDiagnosticResult
638652
{
639653
Id = FluentAssertionsAnalyzer.DiagnosticId,
640654
Message = DiagnosticMetadata.CollectionShouldContainSingle_ShouldHaveCount1.Message,
@@ -1023,7 +1037,7 @@ private void VerifyCSharpDiagnosticCodeBlock(string sourceAssertion, DiagnosticM
10231037
{
10241038
var source = GenerateCode.GenericIListCodeBlockAssertion(sourceAssertion);
10251039

1026-
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new DiagnosticResult
1040+
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new LegacyDiagnosticResult
10271041
{
10281042
Id = FluentAssertionsAnalyzer.DiagnosticId,
10291043
Message = metadata.Message,
@@ -1040,7 +1054,7 @@ private void VerifyCSharpDiagnosticExpressionBody(string sourceAssertion, Diagno
10401054
{
10411055
var source = GenerateCode.GenericIListExpressionBodyAssertion(sourceAssertion);
10421056

1043-
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new DiagnosticResult
1057+
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new LegacyDiagnosticResult
10441058
{
10451059
Id = FluentAssertionsAnalyzer.DiagnosticId,
10461060
VisitorName = metadata.Name,
@@ -1057,7 +1071,7 @@ private void VerifyArrayCSharpDiagnosticCodeBlock(string sourceAssertion, Diagno
10571071
{
10581072
var source = GenerateCode.GenericArrayCodeBlockAssertion(sourceAssertion);
10591073

1060-
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new DiagnosticResult
1074+
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new LegacyDiagnosticResult
10611075
{
10621076
Id = FluentAssertionsAnalyzer.DiagnosticId,
10631077
Message = metadata.Message,

src/FluentAssertions.Analyzers.Tests/Tips/DictionaryTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ private void VerifyCSharpDiagnostic(string sourceAssersion, DiagnosticMetadata m
188188
{
189189
var source = GenerateCode.GenericIDictionaryAssertion(sourceAssersion);
190190

191-
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new DiagnosticResult
191+
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new LegacyDiagnosticResult
192192
{
193193
Id = FluentAssertionsAnalyzer.DiagnosticId,
194194
Message = metadata.Message,

src/FluentAssertions.Analyzers.Tests/Tips/ExceptionsTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ private void VerifyCSharpDiagnostic(string sourceAssertion, DiagnosticMetadata m
283283
{
284284
var source = GenerateCode.ExceptionAssertion(sourceAssertion);
285285

286-
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new DiagnosticResult
286+
DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source, new LegacyDiagnosticResult
287287
{
288288
Id = FluentAssertionsAnalyzer.DiagnosticId,
289289
Message = metadata.Message,

src/FluentAssertions.Analyzers.Tests/Tips/MsTestTests.cs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,47 @@
11
using FluentAssertions.Analyzers.TestUtils;
22
using Microsoft.CodeAnalysis;
3+
using Microsoft.CodeAnalysis.CSharp;
4+
using Microsoft.CodeAnalysis.Diagnostics;
5+
using Microsoft.CodeAnalysis.Testing;
36
using Microsoft.VisualStudio.TestTools.UnitTesting;
7+
using System.Collections.Generic;
8+
using System.Collections.Immutable;
49
using System.Text;
10+
using System.Threading.Tasks;
511

612
namespace FluentAssertions.Analyzers.Tests.Tips
713
{
814
[TestClass]
915
public class MsTestTests
1016
{
17+
private class AllAnalyzersTest : AnalyzerTest<DefaultVerifier>
18+
{
19+
protected override string DefaultFileExt => "cs";
20+
public override string Language => LanguageNames.CSharp;
21+
private readonly AnalyzerOptions analyzerOptions;
22+
public AllAnalyzersTest(IDictionary<string, string> analyzerConfigOptions = null)
23+
{
24+
analyzerOptions = analyzerConfigOptions != null ? new AnalyzerOptions(ImmutableArray<AdditionalText>.Empty, new TestAnalyzerConfigOptionsProvider(analyzerConfigOptions)) : null;
25+
}
26+
27+
protected override CompilationOptions CreateCompilationOptions() => new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true);
28+
protected override ParseOptions CreateParseOptions() => new CSharpParseOptions(LanguageVersion.Latest, DocumentationMode.Diagnose);
29+
protected override IEnumerable<DiagnosticAnalyzer> GetDiagnosticAnalyzers() => CodeAnalyzersUtils.GetAllAnalyzers();
30+
31+
protected override AnalyzerOptions GetAnalyzerOptions(Project project) => analyzerOptions ?? project.AnalyzerOptions;
32+
}
33+
34+
private class MsTestAnalyzerTest : Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerTest<AssertAnalyzer, DefaultVerifier>
35+
{
36+
private readonly AnalyzerOptions analyzerOptions;
37+
public MsTestAnalyzerTest(IDictionary<string, string> values = null)
38+
{
39+
analyzerOptions = values != null ? new AnalyzerOptions(ImmutableArray<AdditionalText>.Empty, new TestAnalyzerConfigOptionsProvider(values)) : null;
40+
}
41+
42+
protected override AnalyzerOptions GetAnalyzerOptions(Project project) => analyzerOptions;
43+
}
44+
1145
[TestMethod]
1246
[Implemented]
1347
public void SupportExcludingMethods()
@@ -866,7 +900,7 @@ private void VerifyCSharpDiagnostic(string source)
866900
.WithAllAnalyzers()
867901
.WithSources(source)
868902
.WithPackageReferences(PackageReference.FluentAssertions_6_12_0, PackageReference.MSTestTestFramework_3_1_1)
869-
.WithExpectedDiagnostics(new DiagnosticResult
903+
.WithExpectedDiagnostics(new LegacyDiagnosticResult
870904
{
871905
Id = AssertAnalyzer.MSTestsRule.Id,
872906
Message = AssertAnalyzer.Message,

0 commit comments

Comments
 (0)