Skip to content

Commit bb52ea8

Browse files
authored
add support for xunit StringAsserts Empty (#226)
* add support for xunit StringAsserts Empty
1 parent 65f5fc5 commit bb52ea8

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,19 @@ public void AssertStringDoesNotMatch_Regex_TestAnalyzer(string assertion) =>
424424
public void AssertStringDoesNotMatch_Regex_TestCodeFix(string oldAssertion, string newAssertion)
425425
=> VerifyCSharpFix<AssertDoesNotMatchCodeFix, AssertDoesNotMatchAnalyzer>("string actual, Regex expectedRegex", oldAssertion, newAssertion);
426426

427+
[DataTestMethod]
428+
[DataRow("Assert.Empty(actual);")]
429+
[Implemented]
430+
public void AssertEmpty_String_TestAnalyzer(string assertion) =>
431+
VerifyCSharpDiagnostic<AssertEmptyAnalyzer>("string actual", assertion);
432+
433+
[DataTestMethod]
434+
[DataRow(
435+
/* oldAssertion: */ "Assert.Empty(actual);",
436+
/* newAssertion: */ "actual.Should().BeEmpty();")]
437+
[Implemented]
438+
public void AssertEmpty_String_TestCodeFix(string oldAssertion, string newAssertion)
439+
=> VerifyCSharpFix<AssertEmptyCodeFix, AssertEmptyAnalyzer>("string actual", oldAssertion, newAssertion);
427440

428441
private void VerifyCSharpDiagnostic<TDiagnosticAnalyzer>(string methodArguments, string assertion) where TDiagnosticAnalyzer : Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer, new()
429442
{

src/FluentAssertions.Analyzers/Constants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ public static class Xunit
133133
public const string AssertDoesNotContain = $"{DiagnosticProperties.IdPrefix}0711";
134134
public const string AssertMatches = $"{DiagnosticProperties.IdPrefix}0712";
135135
public const string AssertDoesNotMatch = $"{DiagnosticProperties.IdPrefix}0713";
136+
public const string AssertEmpty = $"{DiagnosticProperties.IdPrefix}0714";
136137
}
137138
}
138139

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using System.Collections.Generic;
2+
using System.Collections.Immutable;
3+
using System.Composition;
4+
using FluentAssertions.Analyzers.Utilities;
5+
using Microsoft.CodeAnalysis;
6+
using Microsoft.CodeAnalysis.CodeFixes;
7+
using Microsoft.CodeAnalysis.CSharp.Syntax;
8+
using Microsoft.CodeAnalysis.Diagnostics;
9+
10+
namespace FluentAssertions.Analyzers.Xunit;
11+
12+
[DiagnosticAnalyzer(LanguageNames.CSharp)]
13+
public class AssertEmptyAnalyzer : XunitAnalyzer
14+
{
15+
public const string DiagnosticId = Constants.Tips.Xunit.AssertEmpty;
16+
public const string Category = Constants.Tips.Category;
17+
18+
public const string Message = "Use .Should().NotMatchRegex()";
19+
20+
protected override DiagnosticDescriptor Rule => new(DiagnosticId, Title, Message, Category, DiagnosticSeverity.Info, true);
21+
22+
protected override IEnumerable<FluentAssertionsCSharpSyntaxVisitor> Visitors => new FluentAssertionsCSharpSyntaxVisitor[]
23+
{
24+
new AssertEmptyStringSyntaxVisitor()
25+
};
26+
27+
//public static void Empty(string value)
28+
public class AssertEmptyStringSyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
29+
{
30+
public AssertEmptyStringSyntaxVisitor() : base(
31+
MemberValidator.ArgumentsMatch("Empty",
32+
ArgumentValidator.IsType(TypeSelector.GetStringType))
33+
)
34+
{
35+
}
36+
}
37+
}
38+
39+
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(AssertEmptyCodeFix)), Shared]
40+
public class AssertEmptyCodeFix : XunitCodeFixProvider
41+
{
42+
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(AssertEmptyAnalyzer.DiagnosticId);
43+
44+
protected override ExpressionSyntax GetNewExpression(
45+
ExpressionSyntax expression,
46+
FluentAssertionsDiagnosticProperties properties)
47+
{
48+
switch (properties.VisitorName)
49+
{
50+
case nameof(AssertEmptyAnalyzer.AssertEmptyStringSyntaxVisitor):
51+
return RenameMethodAndReplaceWithSubjectShould(expression, "Empty", "BeEmpty");
52+
default:
53+
throw new System.InvalidOperationException($"Invalid visitor name - {properties.VisitorName}");
54+
}
55+
}
56+
}

0 commit comments

Comments
 (0)