Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions src/FluentAssertions.Analyzers.Tests/Tips/MsTestTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,32 @@ public void AssertIsNotInstanceOfType_TestCodeFix(string oldAssertion, string ne
public void AssertObjectAreEqual_TestCodeFix(string oldAssertion, string newAssertion)
=> VerifyCSharpFix<AssertAreEqualCodeFix, AssertAreEqualAnalyzer>("object actual, object expected", oldAssertion, newAssertion);

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

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

[AssertionDataTestMethod]
[AssertionDiagnostic("Assert.AreEqual(actual, null{0});")]
[Implemented]
public void AssertOptionalIntAndNullAreEqual_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)
=> VerifyCSharpFix<AssertAreEqualCodeFix, AssertAreEqualAnalyzer>("int? actual", oldAssertion, newAssertion);

[AssertionDataTestMethod]
[AssertionDiagnostic("Assert.AreEqual(expected, actual, delta{0});")]
[AssertionDiagnostic("Assert.AreEqual(expected, actual, 0.6{0});")]
Expand Down Expand Up @@ -403,6 +429,33 @@ public void AssertObjectAreNotEqual_TestCodeFix(string oldAssertion, string newA
public void AssertDoubleAreNotEqual_TestCodeFix(string oldAssertion, string newAssertion)
=> VerifyCSharpFix<AssertAreNotEqualCodeFix, AssertAreNotEqualAnalyzer>("double actual, double expected, double delta", oldAssertion, newAssertion);


[AssertionDataTestMethod]
[AssertionDiagnostic("Assert.AreNotEqual(expected, actual{0});")]
[Implemented]
public void AssertOptionalIntAreNotEqual_TestAnalyzer(string assertion) => VerifyCSharpDiagnostic<AssertAreNotEqualAnalyzer>("int? actual, int? expected", assertion);

[AssertionDataTestMethod]
[AssertionCodeFix(
oldAssertion: "Assert.AreNotEqual(expected, actual{0});",
newAssertion: "actual.Should().NotBe(expected{0});")]
[Implemented]
public void AssertOptionalIntAreNotEqual_TestCodeFix(string oldAssertion, string newAssertion)
=> VerifyCSharpFix<AssertAreNotEqualCodeFix, AssertAreNotEqualAnalyzer>("int? actual, int? expected", oldAssertion, newAssertion);

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

[AssertionDataTestMethod]
[AssertionCodeFix(
oldAssertion: "Assert.AreNotEqual(actual, null{0});",
newAssertion: "actual.Should().NotBeNull({0});")]
[Implemented]
public void AssertOptionalIntAndNullAreNotEqual_TestCodeFix(string oldAssertion, string newAssertion)
=> VerifyCSharpFix<AssertAreNotEqualCodeFix, AssertAreNotEqualAnalyzer>("int? actual", oldAssertion, newAssertion);

[AssertionDataTestMethod]
[AssertionDiagnostic("Assert.AreNotEqual(expected, actual, delta{0});")]
[AssertionDiagnostic("Assert.AreNotEqual(expected, actual, 0.6f{0});")]
Expand Down
14 changes: 14 additions & 0 deletions src/FluentAssertions.Analyzers/Tips/MsTest/AssertAreEqual.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ protected override IEnumerable<FluentAssertionsCSharpSyntaxVisitor> Visitors
yield return new AssertFloatAreEqualWithDeltaSyntaxVisitor();
yield return new AssertDoubleAreEqualWithDeltaSyntaxVisitor();
yield return new AssertStringAreEqualSyntaxVisitor();
yield return new AssertObjectAreEqualNullSyntaxVisitor();
yield return new AssertObjectAreEqualSyntaxVisitor();
}
}
Expand Down Expand Up @@ -69,6 +70,16 @@ public AssertStringAreEqualSyntaxVisitor() : base(
}
}

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

// 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 @@ -96,6 +107,9 @@ 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):
expression = RenameMethodAndReplaceWithSubjectShould(expression, "AreEqual", "BeNull");
return GetNewExpression(expression, NodeReplacement.RemoveFirstArgument("BeNull"));
default:
throw new System.InvalidOperationException($"Invalid visitor name - {properties.VisitorName}");
}
Expand Down
14 changes: 14 additions & 0 deletions src/FluentAssertions.Analyzers/Tips/MsTest/AssertAreNotEqual.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ protected override IEnumerable<FluentAssertionsCSharpSyntaxVisitor> Visitors
yield return new AssertFloatAreNotEqualWithDeltaSyntaxVisitor();
yield return new AssertDoubleAreNotEqualWithDeltaSyntaxVisitor();
yield return new AssertStringAreNotEqualSyntaxVisitor();
yield return new AssertObjectAreNotEqualNullSyntaxVisitor();
yield return new AssertObjectAreNotEqualSyntaxVisitor();
}
}
Expand Down Expand Up @@ -57,6 +58,16 @@ public AssertDoubleAreNotEqualWithDeltaSyntaxVisitor() : base(
}
}

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

// public static void AreNotEqual(string expected, string actual, bool ignoreCase, CultureInfo culture
public class AssertStringAreNotEqualSyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
{
Expand Down Expand Up @@ -97,6 +108,9 @@ protected override async Task<ExpressionSyntax> GetNewExpressionAsync(Expression
case nameof(AssertAreNotEqualAnalyzer.AssertStringAreNotEqualSyntaxVisitor):
var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
return GetNewExpressionForAreNotEqualOrAreEqualStrings(expression, semanticModel, "AreNotEqual", "NotBe", "NotBeEquivalentTo");
case nameof(AssertAreNotEqualAnalyzer.AssertObjectAreNotEqualNullSyntaxVisitor):
expression = RenameMethodAndReplaceWithSubjectShould(expression, "AreNotEqual", "NotBeNull");
return GetNewExpression(expression, NodeReplacement.RemoveFirstArgument("NotBeNull"));
default:
throw new System.InvalidOperationException($"Invalid visitor name - {properties.VisitorName}");
}
Expand Down
17 changes: 17 additions & 0 deletions src/FluentAssertions.Analyzers/Utilities/ArgumentValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;

namespace FluentAssertions.Analyzers
{
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);
public static ArgumentPredicate IsNull()
=> (argument, semanticModel) => argument.Expression is LiteralExpressionSyntax literal && literal.Token.IsKind(SyntaxKind.NullKeyword);
}
}
12 changes: 0 additions & 12 deletions src/FluentAssertions.Analyzers/Utilities/MemberValidator.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
using System.Diagnostics;

namespace FluentAssertions.Analyzers
Expand Down Expand Up @@ -105,15 +104,4 @@ public static bool ArgumentsMatchPredicate(SeparatedSyntaxList<ArgumentSyntax> a
return true;
}
}

public class ArgumentValidator
{
public static ArgumentPredicate IsType(Func<SemanticModel, INamedTypeSymbol> typeSelector)
{
return (argument, semanticModel) =>
{
return semanticModel.GetTypeInfo(argument.Expression).Type.Equals(typeSelector(semanticModel), SymbolEqualityComparer.Default);
};
}
}
}