Skip to content

Commit d1228ea

Browse files
authored
fix: support first argument being the null keyword (#201)
1 parent da0f60f commit d1228ea

File tree

3 files changed

+34
-7
lines changed

3 files changed

+34
-7
lines changed

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

+15-2
Original file line numberDiff line numberDiff line change
@@ -326,14 +326,27 @@ public void AssertOptionalIntAreEqual_TestCodeFix(string oldAssertion, string ne
326326
[AssertionDataTestMethod]
327327
[AssertionDiagnostic("Assert.AreEqual(actual, null{0});")]
328328
[Implemented]
329-
public void AssertOptionalIntAndNullAreEqual_TestAnalyzer(string assertion) => VerifyCSharpDiagnostic<AssertAreEqualAnalyzer>("int? actual", assertion);
329+
public void AssertOptionalIntAndNullAreEqual1_TestAnalyzer(string assertion) => VerifyCSharpDiagnostic<AssertAreEqualAnalyzer>("int? actual", assertion);
330330

331331
[AssertionDataTestMethod]
332332
[AssertionCodeFix(
333333
oldAssertion: "Assert.AreEqual(actual, null{0});",
334334
newAssertion: "actual.Should().BeNull({0});")]
335335
[Implemented]
336-
public void AssertOptionalIntAndNullAreEqual_TestCodeFix(string oldAssertion, string newAssertion)
336+
public void AssertOptionalIntAndNullAreEqual1_TestCodeFix(string oldAssertion, string newAssertion)
337+
=> VerifyCSharpFix<AssertAreEqualCodeFix, AssertAreEqualAnalyzer>("int? actual", oldAssertion, newAssertion);
338+
339+
[AssertionDataTestMethod]
340+
[AssertionDiagnostic("Assert.AreEqual(null, actual{0});")]
341+
[Implemented]
342+
public void AssertOptionalIntAndNullAreEqual2_TestAnalyzer(string assertion) => VerifyCSharpDiagnostic<AssertAreEqualAnalyzer>("int? actual", assertion);
343+
344+
[AssertionDataTestMethod]
345+
[AssertionCodeFix(
346+
oldAssertion: "Assert.AreEqual(null, actual{0});",
347+
newAssertion: "actual.Should().BeNull({0});")]
348+
[Implemented]
349+
public void AssertOptionalIntAndNullAreEqual2_TestCodeFix(string oldAssertion, string newAssertion)
337350
=> VerifyCSharpFix<AssertAreEqualCodeFix, AssertAreEqualAnalyzer>("int? actual", oldAssertion, newAssertion);
338351

339352
[AssertionDataTestMethod]

src/FluentAssertions.Analyzers/Tips/MsTest/AssertAreEqual.cs

+18-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ protected override IEnumerable<FluentAssertionsCSharpSyntaxVisitor> Visitors
2727
yield return new AssertFloatAreEqualWithDeltaSyntaxVisitor();
2828
yield return new AssertDoubleAreEqualWithDeltaSyntaxVisitor();
2929
yield return new AssertStringAreEqualSyntaxVisitor();
30-
yield return new AssertObjectAreEqualNullSyntaxVisitor();
30+
yield return new AssertObjectAreEqualNull1SyntaxVisitor();
31+
yield return new AssertObjectAreEqualNull2SyntaxVisitor();
3132
yield return new AssertObjectAreEqualSyntaxVisitor();
3233
}
3334
}
@@ -70,16 +71,26 @@ public AssertStringAreEqualSyntaxVisitor() : base(
7071
}
7172
}
7273

73-
public class AssertObjectAreEqualNullSyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
74+
public class AssertObjectAreEqualNull1SyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
7475
{
75-
public AssertObjectAreEqualNullSyntaxVisitor() : base(
76+
public AssertObjectAreEqualNull1SyntaxVisitor() : base(
7677
MemberValidator.ArgumentsMatch("AreEqual",
7778
ArgumentValidator.IsIdentifier(),
7879
ArgumentValidator.IsNull()))
7980
{
8081
}
8182
}
8283

84+
public class AssertObjectAreEqualNull2SyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
85+
{
86+
public AssertObjectAreEqualNull2SyntaxVisitor() : base(
87+
MemberValidator.ArgumentsMatch("AreEqual",
88+
ArgumentValidator.IsNull(),
89+
ArgumentValidator.IsIdentifier()))
90+
{
91+
}
92+
}
93+
8394
// public static void AreEqual<T>(T expected, T actual)
8495
// public static void AreEqual(object expected, object actual)
8596
public class AssertObjectAreEqualSyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
@@ -107,9 +118,12 @@ protected override async Task<ExpressionSyntax> GetNewExpressionAsync(Expression
107118
case nameof(AssertAreEqualAnalyzer.AssertStringAreEqualSyntaxVisitor):
108119
var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
109120
return GetNewExpressionForAreNotEqualOrAreEqualStrings(expression, semanticModel, "AreEqual", "Be", "BeEquivalentTo");
110-
case nameof(AssertAreEqualAnalyzer.AssertObjectAreEqualNullSyntaxVisitor):
121+
case nameof(AssertAreEqualAnalyzer.AssertObjectAreEqualNull1SyntaxVisitor):
111122
expression = RenameMethodAndReplaceWithSubjectShould(expression, "AreEqual", "BeNull");
112123
return GetNewExpression(expression, NodeReplacement.RemoveFirstArgument("BeNull"));
124+
case nameof(AssertAreEqualAnalyzer.AssertObjectAreEqualNull2SyntaxVisitor):
125+
expression = GetNewExpression(expression, NodeReplacement.RemoveFirstArgument("AreEqual"));
126+
return RenameMethodAndReplaceWithSubjectShould(expression, "AreEqual", "BeNull");
113127
default:
114128
throw new System.InvalidOperationException($"Invalid visitor name - {properties.VisitorName}");
115129
}

src/FluentAssertions.Analyzers/Utilities/ArgumentValidator.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public class ArgumentValidator
1010
public static ArgumentPredicate IsIdentifier()
1111
=> (argument, semanticModel) => argument.Expression.IsKind(SyntaxKind.IdentifierName);
1212
public static ArgumentPredicate IsType(Func<SemanticModel, INamedTypeSymbol> typeSelector)
13-
=> (argument, semanticModel) => semanticModel.GetTypeInfo(argument.Expression).Type.Equals(typeSelector(semanticModel), SymbolEqualityComparer.Default);
13+
=> (argument, semanticModel) => semanticModel.GetTypeInfo(argument.Expression).Type?.Equals(typeSelector(semanticModel), SymbolEqualityComparer.Default) ?? false;
1414
public static ArgumentPredicate IsNull()
1515
=> (argument, semanticModel) => argument.Expression is LiteralExpressionSyntax literal && literal.Token.IsKind(SyntaxKind.NullKeyword);
1616
}

0 commit comments

Comments
 (0)