Skip to content

Commit

Permalink
fix: support first argument being the null keyword (#201)
Browse files Browse the repository at this point in the history
  • Loading branch information
Meir017 authored Jun 28, 2023
1 parent da0f60f commit d1228ea
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 7 deletions.
17 changes: 15 additions & 2 deletions src/FluentAssertions.Analyzers.Tests/Tips/MsTestTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -326,14 +326,27 @@ public void AssertOptionalIntAreEqual_TestCodeFix(string oldAssertion, string ne
[AssertionDataTestMethod]
[AssertionDiagnostic("Assert.AreEqual(actual, null{0});")]
[Implemented]
public void AssertOptionalIntAndNullAreEqual_TestAnalyzer(string assertion) => VerifyCSharpDiagnostic<AssertAreEqualAnalyzer>("int? actual", assertion);
public void AssertOptionalIntAndNullAreEqual1_TestAnalyzer(string assertion) => VerifyCSharpDiagnostic<AssertAreEqualAnalyzer>("int? actual", assertion);

[AssertionDataTestMethod]
[AssertionCodeFix(
oldAssertion: "Assert.AreEqual(actual, null{0});",
newAssertion: "actual.Should().BeNull({0});")]
[Implemented]
public void AssertOptionalIntAndNullAreEqual_TestCodeFix(string oldAssertion, string newAssertion)
public void AssertOptionalIntAndNullAreEqual1_TestCodeFix(string oldAssertion, string newAssertion)
=> VerifyCSharpFix<AssertAreEqualCodeFix, AssertAreEqualAnalyzer>("int? actual", oldAssertion, newAssertion);

[AssertionDataTestMethod]
[AssertionDiagnostic("Assert.AreEqual(null, actual{0});")]
[Implemented]
public void AssertOptionalIntAndNullAreEqual2_TestAnalyzer(string assertion) => VerifyCSharpDiagnostic<AssertAreEqualAnalyzer>("int? actual", assertion);

[AssertionDataTestMethod]
[AssertionCodeFix(
oldAssertion: "Assert.AreEqual(null, actual{0});",
newAssertion: "actual.Should().BeNull({0});")]
[Implemented]
public void AssertOptionalIntAndNullAreEqual2_TestCodeFix(string oldAssertion, string newAssertion)
=> VerifyCSharpFix<AssertAreEqualCodeFix, AssertAreEqualAnalyzer>("int? actual", oldAssertion, newAssertion);

[AssertionDataTestMethod]
Expand Down
22 changes: 18 additions & 4 deletions src/FluentAssertions.Analyzers/Tips/MsTest/AssertAreEqual.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ protected override IEnumerable<FluentAssertionsCSharpSyntaxVisitor> Visitors
yield return new AssertFloatAreEqualWithDeltaSyntaxVisitor();
yield return new AssertDoubleAreEqualWithDeltaSyntaxVisitor();
yield return new AssertStringAreEqualSyntaxVisitor();
yield return new AssertObjectAreEqualNullSyntaxVisitor();
yield return new AssertObjectAreEqualNull1SyntaxVisitor();
yield return new AssertObjectAreEqualNull2SyntaxVisitor();
yield return new AssertObjectAreEqualSyntaxVisitor();
}
}
Expand Down Expand Up @@ -70,16 +71,26 @@ public AssertStringAreEqualSyntaxVisitor() : base(
}
}

public class AssertObjectAreEqualNullSyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
public class AssertObjectAreEqualNull1SyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
{
public AssertObjectAreEqualNullSyntaxVisitor() : base(
public AssertObjectAreEqualNull1SyntaxVisitor() : base(
MemberValidator.ArgumentsMatch("AreEqual",
ArgumentValidator.IsIdentifier(),
ArgumentValidator.IsNull()))
{
}
}

public class AssertObjectAreEqualNull2SyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
{
public AssertObjectAreEqualNull2SyntaxVisitor() : base(
MemberValidator.ArgumentsMatch("AreEqual",
ArgumentValidator.IsNull(),
ArgumentValidator.IsIdentifier()))
{
}
}

// public static void AreEqual<T>(T expected, T actual)
// public static void AreEqual(object expected, object actual)
public class AssertObjectAreEqualSyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
Expand Down Expand Up @@ -107,9 +118,12 @@ protected override async Task<ExpressionSyntax> GetNewExpressionAsync(Expression
case nameof(AssertAreEqualAnalyzer.AssertStringAreEqualSyntaxVisitor):
var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
return GetNewExpressionForAreNotEqualOrAreEqualStrings(expression, semanticModel, "AreEqual", "Be", "BeEquivalentTo");
case nameof(AssertAreEqualAnalyzer.AssertObjectAreEqualNullSyntaxVisitor):
case nameof(AssertAreEqualAnalyzer.AssertObjectAreEqualNull1SyntaxVisitor):
expression = RenameMethodAndReplaceWithSubjectShould(expression, "AreEqual", "BeNull");
return GetNewExpression(expression, NodeReplacement.RemoveFirstArgument("BeNull"));
case nameof(AssertAreEqualAnalyzer.AssertObjectAreEqualNull2SyntaxVisitor):
expression = GetNewExpression(expression, NodeReplacement.RemoveFirstArgument("AreEqual"));
return RenameMethodAndReplaceWithSubjectShould(expression, "AreEqual", "BeNull");
default:
throw new System.InvalidOperationException($"Invalid visitor name - {properties.VisitorName}");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class ArgumentValidator
public static ArgumentPredicate IsIdentifier()
=> (argument, semanticModel) => argument.Expression.IsKind(SyntaxKind.IdentifierName);
public static ArgumentPredicate IsType(Func<SemanticModel, INamedTypeSymbol> typeSelector)
=> (argument, semanticModel) => semanticModel.GetTypeInfo(argument.Expression).Type.Equals(typeSelector(semanticModel), SymbolEqualityComparer.Default);
=> (argument, semanticModel) => semanticModel.GetTypeInfo(argument.Expression).Type?.Equals(typeSelector(semanticModel), SymbolEqualityComparer.Default) ?? false;
public static ArgumentPredicate IsNull()
=> (argument, semanticModel) => argument.Expression is LiteralExpressionSyntax literal && literal.Token.IsKind(SyntaxKind.NullKeyword);
}
Expand Down

0 comments on commit d1228ea

Please sign in to comment.