Skip to content

Commit

Permalink
add support for StringAsserts DoesNotContain (#223)
Browse files Browse the repository at this point in the history
  • Loading branch information
Meir017 authored Sep 26, 2023
1 parent 53a18f2 commit dba288b
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/FluentAssertions.Analyzers.Tests/Tips/XunitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,21 @@ public void AssertStringContains_TestAnalyzer(string assertion) =>
public void AssertStringContains_TestCodeFix(string oldAssertion, string newAssertion)
=> VerifyCSharpFix<AssertContainsCodeFix, AssertContainsAnalyzer>("string actual, string expected", oldAssertion, newAssertion);

[DataTestMethod]
[DataRow("Assert.DoesNotContain(expected, actual);")]
[Implemented]
public void AssertStringDoesNotContain_TestAnalyzer(string assertion) =>
VerifyCSharpDiagnostic<AssertDoesNotContainAnalyzer>("string actual, string expected", assertion);

[DataTestMethod]
[DataRow(
/* oldAssertion: */ "Assert.DoesNotContain(expected, actual);",
/* newAssertion: */ "actual.Should().NotContain(expected);")]
[Implemented]
public void AssertStringDoesNotContain_TestCodeFix(string oldAssertion, string newAssertion)
=> VerifyCSharpFix<AssertDoesNotContainCodeFix, AssertDoesNotContainAnalyzer>("string actual, string expected", oldAssertion, newAssertion);


private void VerifyCSharpDiagnostic<TDiagnosticAnalyzer>(string methodArguments, string assertion) where TDiagnosticAnalyzer : Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer, new()
{
var source = GenerateCode.XunitAssertion(methodArguments, assertion);
Expand Down
1 change: 1 addition & 0 deletions src/FluentAssertions.Analyzers/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ public static class Xunit
public const string AssertNull = $"{DiagnosticProperties.IdPrefix}0708";
public const string AssertNotNull = $"{DiagnosticProperties.IdPrefix}0709";
public const string AssertContains = $"{DiagnosticProperties.IdPrefix}0710";
public const string AssertDoesNotContain = $"{DiagnosticProperties.IdPrefix}0711";
}
}

Expand Down
57 changes: 57 additions & 0 deletions src/FluentAssertions.Analyzers/Tips/Xunit/AssertDoesNotContain.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using FluentAssertions.Analyzers.Utilities;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;

namespace FluentAssertions.Analyzers.Xunit;

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class AssertDoesNotContainAnalyzer : XunitAnalyzer
{
public const string DiagnosticId = Constants.Tips.Xunit.AssertDoesNotContain;
public const string Category = Constants.Tips.Category;

public const string Message = "Use .Should().NotContain().";

protected override DiagnosticDescriptor Rule => new(DiagnosticId, Title, Message, Category, DiagnosticSeverity.Info, true);

protected override IEnumerable<FluentAssertionsCSharpSyntaxVisitor> Visitors => new FluentAssertionsCSharpSyntaxVisitor[]
{
new AssertDoesNotContainStringSyntaxVisitor()
};

//public static void DoesNotContain(string expectedSubstring, string? actualString)
public class AssertDoesNotContainStringSyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
{
public AssertDoesNotContainStringSyntaxVisitor() : base(
MemberValidator.ArgumentsMatch("DoesNotContain",
ArgumentValidator.IsType(TypeSelector.GetStringType),
ArgumentValidator.IsType(TypeSelector.GetStringType))
)
{
}
}
}

[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(AssertDoesNotContainCodeFix)), Shared]
public class AssertDoesNotContainCodeFix : XunitCodeFixProvider
{
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(AssertDoesNotContainAnalyzer.DiagnosticId);

protected override ExpressionSyntax GetNewExpression(
ExpressionSyntax expression,
FluentAssertionsDiagnosticProperties properties)
{
switch (properties.VisitorName)
{
case nameof(AssertDoesNotContainAnalyzer.AssertDoesNotContainStringSyntaxVisitor):
return RenameMethodAndReorderActualExpectedAndReplaceWithSubjectShould(expression, "DoesNotContain", "NotContain");
default:
throw new System.InvalidOperationException($"Invalid visitor name - {properties.VisitorName}");
}
}
}

0 comments on commit dba288b

Please sign in to comment.