Skip to content

Commit

Permalink
feat: nunit numeric assertions (#294)
Browse files Browse the repository at this point in the history
* feat: add nunit numeric assertions
  • Loading branch information
Meir017 authored Jan 17, 2024
1 parent 5481668 commit 9fd07fb
Show file tree
Hide file tree
Showing 3 changed files with 261 additions and 25 deletions.
195 changes: 195 additions & 0 deletions src/FluentAssertions.Analyzers.Tests/Tips/NunitTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using FluentAssertions.Analyzers.TestUtils;
using Microsoft.CodeAnalysis;
using Microsoft.VisualStudio.TestTools.UnitTesting;
Expand Down Expand Up @@ -192,6 +193,200 @@ public class NunitTests
[Implemented]
public void Nunit4_AssertNotNull_TestCodeFix(string oldAssertion, string newAssertion) => Nunit4VerifyFix("object actual", oldAssertion, newAssertion);

[DataTestMethod]
[AssertionDiagnostic("Assert.Greater(arg1, arg2{0});")]
[Implemented]
public void Nunit3_AssertGreater_TestAnalyzer(string assertion)
{
foreach (var comparableArgument in ComparableArguments)
{
Nunit3VerifyDiagnostic(comparableArgument, assertion);
}
}

[DataTestMethod]
[AssertionDiagnostic("ClassicAssert.Greater(arg1, arg2{0});")]
[Implemented]
public void Nunit4_AssertGreater_TestAnalyzer(string assertion)
{
foreach (var comparableArgument in ComparableArguments)
{
Nunit4VerifyDiagnostic(comparableArgument, assertion);
}
}

[DataTestMethod]
[AssertionCodeFix(
oldAssertion: "Assert.Greater(arg1, arg2{0});",
newAssertion: "arg1.Should().BeGreaterThan(arg2{0});")]
[Implemented]
public void Nunit3_AssertGreater_TestCodeFix(string oldAssertion, string newAssertion)
{
foreach (var comparableArgument in ComparableArguments)
{
Nunit3VerifyFix(comparableArgument, oldAssertion, newAssertion);
}
}

[DataTestMethod]
[AssertionCodeFix(
oldAssertion: "ClassicAssert.Greater(arg1, arg2{0});",
newAssertion: "arg1.Should().BeGreaterThan(arg2{0});")]
[Implemented]
public void Nunit4_AssertGreater_TestCodeFix(string oldAssertion, string newAssertion)
{
foreach (var comparableArgument in ComparableArguments)
{
Nunit4VerifyFix(comparableArgument, oldAssertion, newAssertion);
}
}

[DataTestMethod]
[AssertionDiagnostic("Assert.GreaterOrEqual(arg1, arg2{0});")]
[Implemented]
public void Nunit3_AssertGreaterOrEqual_TestAnalyzer(string assertion)
{
foreach (var comparableArgument in ComparableArguments)
{
Nunit3VerifyDiagnostic(comparableArgument, assertion);
}
}

[DataTestMethod]
[AssertionDiagnostic("ClassicAssert.GreaterOrEqual(arg1, arg2{0});")]
[Implemented]
public void Nunit4_AssertGreaterOrEqual_TestAnalyzer(string assertion)
{
foreach (var comparableArgument in ComparableArguments)
{
Nunit4VerifyDiagnostic(comparableArgument, assertion);
}
}

[DataTestMethod]
[AssertionCodeFix(
oldAssertion: "Assert.GreaterOrEqual(arg1, arg2{0});",
newAssertion: "arg1.Should().BeGreaterOrEqualTo(arg2{0});")]
[Implemented]
public void Nunit3_AssertGreaterOrEqual_TestCodeFix(string oldAssertion, string newAssertion)
{
foreach (var comparableArgument in ComparableArguments)
{
Nunit3VerifyFix(comparableArgument, oldAssertion, newAssertion);
}
}

[DataTestMethod]
[AssertionCodeFix(
oldAssertion: "ClassicAssert.GreaterOrEqual(arg1, arg2{0});",
newAssertion: "arg1.Should().BeGreaterOrEqualTo(arg2{0});")]
[Implemented]
public void Nunit4_AssertGreaterOrEqual_TestCodeFix(string oldAssertion, string newAssertion)
{
foreach (var comparableArgument in ComparableArguments)
{
Nunit4VerifyFix(comparableArgument, oldAssertion, newAssertion);
}
}

[DataTestMethod]
[AssertionDiagnostic("Assert.Less(arg1, arg2{0});")]
[Implemented]
public void Nunit3_AssertLess_TestAnalyzer(string assertion)
{
foreach (var comparableArgument in ComparableArguments)
{
Nunit3VerifyDiagnostic(comparableArgument, assertion);
}
}

[DataTestMethod]
[AssertionDiagnostic("ClassicAssert.Less(arg1, arg2{0});")]
[Implemented]
public void Nunit4_AssertLess_TestAnalyzer(string assertion)
{
foreach (var comparableArgument in ComparableArguments)
{
Nunit4VerifyDiagnostic(comparableArgument, assertion);
}
}

[DataTestMethod]
[AssertionCodeFix(
oldAssertion: "Assert.Less(arg1, arg2{0});",
newAssertion: "arg1.Should().BeLessThan(arg2{0});")]
[Implemented]
public void Nunit3_AssertLess_TestCodeFix(string oldAssertion, string newAssertion)
{
foreach (var comparableArgument in ComparableArguments)
{
Nunit3VerifyFix(comparableArgument, oldAssertion, newAssertion);
}
}

[DataTestMethod]
[AssertionCodeFix(
oldAssertion: "ClassicAssert.Less(arg1, arg2{0});",
newAssertion: "arg1.Should().BeLessThan(arg2{0});")]
[Implemented]
public void Nunit4_AssertLess_TestCodeFix(string oldAssertion, string newAssertion)
{
foreach (var comparableArgument in ComparableArguments)
{
Nunit4VerifyFix(comparableArgument, oldAssertion, newAssertion);
}
}

[DataTestMethod]
[AssertionDiagnostic("Assert.LessOrEqual(arg1, arg2{0});")]
[Implemented]
public void Nunit3_AssertLessOrEqual_TestAnalyzer(string assertion)
{
foreach (var comparableArgument in ComparableArguments)
{
Nunit3VerifyDiagnostic(comparableArgument, assertion);
}
}

[DataTestMethod]
[AssertionDiagnostic("ClassicAssert.LessOrEqual(arg1, arg2{0});")]
[Implemented]
public void Nunit4_AssertLessOrEqual_TestAnalyzer(string assertion)
{
foreach (var comparableArgument in ComparableArguments)
{
Nunit4VerifyDiagnostic(comparableArgument, assertion);
}
}

[DataTestMethod]
[AssertionCodeFix(
oldAssertion: "Assert.LessOrEqual(arg1, arg2{0});",
newAssertion: "arg1.Should().BeLessOrEqualTo(arg2{0});")]
[Implemented]
public void Nunit3_AssertLessOrEqual_TestCodeFix(string oldAssertion, string newAssertion)
{
foreach (var comparableArgument in ComparableArguments)
{
Nunit3VerifyFix(comparableArgument, oldAssertion, newAssertion);
}
}

[DataTestMethod]
[AssertionCodeFix(
oldAssertion: "ClassicAssert.LessOrEqual(arg1, arg2{0});",
newAssertion: "arg1.Should().BeLessOrEqualTo(arg2{0});")]
[Implemented]
public void Nunit4_AssertLessOrEqual_TestCodeFix(string oldAssertion, string newAssertion)
{
foreach (var comparableArgument in ComparableArguments)
{
Nunit4VerifyFix(comparableArgument, oldAssertion, newAssertion);
}
}

private static readonly string[] ComparableArguments = Array.ConvertAll(new string[] { "int", "uint", "long", "ulong", "float", "double", "decimal" }, x => $"{x} arg1, {x} arg2");

private void Nunit3VerifyDiagnostic(string methodArguments, string assertion)
=> VerifyDiagnostic(GenerateCode.Nunit3Assertion(methodArguments, assertion), PackageReference.Nunit_3_14_0);
private void Nunit3VerifyFix(string methodArguments, string oldAssertion, string newAssertion)
Expand Down
88 changes: 63 additions & 25 deletions src/FluentAssertions.Analyzers/Tips/NunitCodeFixProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ protected override CreateChangedDocument TryComputeFixCore(IInvocationOperation

return assertType.Name switch
{
"Assert" when isNunit3 => TryComputeFixForNunit3Assert(invocation, context, t),
"ClassicAssert" when isNunit4 => TryComputeFixForNunit4ClassicAssert(invocation, context, t),
"Assert" when isNunit3 => TryComputeFixForNunitClassicAssert(invocation, context, t),
"ClassicAssert" when isNunit4 => TryComputeFixForNunitClassicAssert(invocation, context, t),
//"StringAssert" => TryComputeFixForStringAssert(invocation, context, testContext),
//"CollectionAssert" => TryComputeFixForCollectionAssert(invocation, context, testContext),
_ => null
};
}

private CreateChangedDocument TryComputeFixForNunit3Assert(IInvocationOperation invocation, CodeFixContext context, TestingFrameworkCodeFixContext t)
private CreateChangedDocument TryComputeFixForNunitClassicAssert(IInvocationOperation invocation, CodeFixContext context, TestingFrameworkCodeFixContext t)
{
switch (invocation.TargetMethod.Name)
{
Expand All @@ -46,29 +46,67 @@ private CreateChangedDocument TryComputeFixForNunit3Assert(IInvocationOperation
case "NotNull": // Assert.NotNull(object anObject)
case "IsNotNull": // Assert.IsNotNull(object anObject)
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "NotBeNull", subjectIndex: 0, argumentsToRemove: []);
case "Greater" when ArgumentsAreTypeOf(invocation, t.Int32, t.Int32): // Assert.Greater(int arg1, int arg2)
case "Greater" when ArgumentsAreTypeOf(invocation, t.UInt32, t.UInt32): // Assert.Greater(uint arg1, uint arg2)
case "Greater" when ArgumentsAreTypeOf(invocation, t.Long, t.Long): // Assert.Greater(long arg1, long arg2)
case "Greater" when ArgumentsAreTypeOf(invocation, t.ULong, t.ULong): // Assert.Greater(ulong arg1, ulong arg2)
case "Greater" when ArgumentsAreTypeOf(invocation, t.Float, t.Float): // Assert.Greater(float arg1, float arg2)
case "Greater" when ArgumentsAreTypeOf(invocation, t.Double, t.Double): // Assert.Greater(double arg1, double arg2)
case "Greater" when ArgumentsAreTypeOf(invocation, t.Decimal, t.Decimal): // Assert.Greater(decimal arg1, decimal arg2)
case "Greater" when ArgumentsAreTypeOf(invocation, t.Int32, t.Int32, t.String, t.ObjectArray): // Assert.Greater(int arg1, int arg2, string message, params object[] parms)
case "Greater" when ArgumentsAreTypeOf(invocation, t.UInt32, t.UInt32, t.String, t.ObjectArray): // Assert.Greater(uint arg1, uint arg2, string message, params object[] parms)
case "Greater" when ArgumentsAreTypeOf(invocation, t.Long, t.Long, t.String, t.ObjectArray): // Assert.Greater(long arg1, long arg2, string message, params object[] parms)
case "Greater" when ArgumentsAreTypeOf(invocation, t.ULong, t.ULong, t.String, t.ObjectArray): // Assert.Greater(ulong arg1, ulong arg2, string message, params object[] parms)
case "Greater" when ArgumentsAreTypeOf(invocation, t.Float, t.Float, t.String, t.ObjectArray): // Assert.Greater(float arg1, float arg2, string message, params object[] parms)
case "Greater" when ArgumentsAreTypeOf(invocation, t.Double, t.Double, t.String, t.ObjectArray): // Assert.Greater(double arg1, double arg2, string message, params object[] parms)
case "Greater" when ArgumentsAreTypeOf(invocation, t.Decimal, t.Decimal, t.String, t.ObjectArray): // Assert.Greater(decimal arg1, decimal arg2, string message, params object[] parms)
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "BeGreaterThan", subjectIndex: 0, argumentsToRemove: []);
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Int32, t.Int32): // Assert.GreaterOrEqual(int arg1, int arg2)
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.UInt32, t.UInt32): // Assert.GreaterOrEqual(uint arg1, uint arg2)
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Long, t.Long): // Assert.GreaterOrEqual(long arg1, long arg2)
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.ULong, t.ULong): // Assert.GreaterOrEqual(ulong arg1, ulong arg2)
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Float, t.Float): // Assert.GreaterOrEqual(float arg1, float arg2)
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Double, t.Double): // Assert.GreaterOrEqual(double arg1, double arg2)
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Decimal, t.Decimal): // Assert.GreaterOrEqual(decimal arg1, decimal arg2)
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Int32, t.Int32, t.String, t.ObjectArray): // Assert.GreaterOrEqual(int arg1, int arg2, string message, params object[] parms)
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.UInt32, t.UInt32, t.String, t.ObjectArray): // Assert.GreaterOrEqual(uint arg1, uint arg2, string message, params object[] parms)
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Long, t.Long, t.String, t.ObjectArray): // Assert.GreaterOrEqual(long arg1, long arg2, string message, params object[] parms)
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.ULong, t.ULong, t.String, t.ObjectArray): // Assert.GreaterOrEqual(ulong arg1, ulong arg2, string message, params object[] parms)
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Float, t.Float, t.String, t.ObjectArray): // Assert.GreaterOrEqual(float arg1, float arg2, string message, params object[] parms)
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Double, t.Double, t.String, t.ObjectArray): // Assert.GreaterOrEqual(double arg1, double arg2, string message, params object[] parms)
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Decimal, t.Decimal, t.String, t.ObjectArray): // Assert.GreaterOrEqual(decimal arg1, decimal arg2, string message, params object[] parms)
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "BeGreaterOrEqualTo", subjectIndex: 0, argumentsToRemove: []);
case "Less" when ArgumentsAreTypeOf(invocation, t.Int32, t.Int32): // Assert.Less(int arg1, int arg2)
case "Less" when ArgumentsAreTypeOf(invocation, t.UInt32, t.UInt32): // Assert.Less(uint arg1, uint arg2)
case "Less" when ArgumentsAreTypeOf(invocation, t.Long, t.Long): // Assert.Less(long arg1, long arg2)
case "Less" when ArgumentsAreTypeOf(invocation, t.ULong, t.ULong): // Assert.Less(ulong arg1, ulong arg2)
case "Less" when ArgumentsAreTypeOf(invocation, t.Float, t.Float): // Assert.Less(float arg1, float arg2)
case "Less" when ArgumentsAreTypeOf(invocation, t.Double, t.Double): // Assert.Less(double arg1, double arg2)
case "Less" when ArgumentsAreTypeOf(invocation, t.Decimal, t.Decimal): // Assert.Less(decimal arg1, decimal arg2)
case "Less" when ArgumentsAreTypeOf(invocation, t.Int32, t.Int32, t.String, t.ObjectArray): // Assert.Less(int arg1, int arg2, string message, params object[] parms)
case "Less" when ArgumentsAreTypeOf(invocation, t.UInt32, t.UInt32, t.String, t.ObjectArray): // Assert.Less(uint arg1, uint arg2, string message, params object[] parms)
case "Less" when ArgumentsAreTypeOf(invocation, t.Long, t.Long, t.String, t.ObjectArray): // Assert.Less(long arg1, long arg2, string message, params object[] parms)
case "Less" when ArgumentsAreTypeOf(invocation, t.ULong, t.ULong, t.String, t.ObjectArray): // Assert.Less(ulong arg1, ulong arg2, string message, params object[] parms)
case "Less" when ArgumentsAreTypeOf(invocation, t.Float, t.Float, t.String, t.ObjectArray): // Assert.Less(float arg1, float arg2, string message, params object[] parms)
case "Less" when ArgumentsAreTypeOf(invocation, t.Double, t.Double, t.String, t.ObjectArray): // Assert.Less(double arg1, double arg2, string message, params object[] parms)
case "Less" when ArgumentsAreTypeOf(invocation, t.Decimal, t.Decimal, t.String, t.ObjectArray): // Assert.Less(decimal arg1, decimal arg2, string message, params object[] parms)
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "BeLessThan", subjectIndex: 0, argumentsToRemove: []);
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Int32, t.Int32): // Assert.LessOrEqual(int arg1, int arg2)
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.UInt32, t.UInt32): // Assert.LessOrEqual(uint arg1, uint arg2)
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Long, t.Long): // Assert.LessOrEqual(long arg1, long arg2)
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.ULong, t.ULong): // Assert.LessOrEqual(ulong arg1, ulong arg2)
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Float, t.Float): // Assert.LessOrEqual(float arg1, float arg2)
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Double, t.Double): // Assert.LessOrEqual(double arg1, double arg2)
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Decimal, t.Decimal): // Assert.LessOrEqual(decimal arg1, decimal arg2)
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Int32, t.Int32, t.String, t.ObjectArray): // Assert.LessOrEqual(int arg1, int arg2, string message, params object[] parms)
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.UInt32, t.UInt32, t.String, t.ObjectArray): // Assert.LessOrEqual(uint arg1, uint arg2, string message, params object[] parms)
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Long, t.Long, t.String, t.ObjectArray): // Assert.LessOrEqual(long arg1, long arg2, string message, params object[] parms)
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.ULong, t.ULong, t.String, t.ObjectArray): // Assert.LessOrEqual(ulong arg1, ulong arg2, string message, params object[] parms)
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Float, t.Float, t.String, t.ObjectArray): // Assert.LessOrEqual(float arg1, float arg2, string message, params object[] parms)
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Double, t.Double, t.String, t.ObjectArray): // Assert.LessOrEqual(double arg1, double arg2, string message, params object[] parms)
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Decimal, t.Decimal, t.String, t.ObjectArray): // Assert.LessOrEqual(decimal arg1, decimal arg2, string message, params object[] parms)
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "BeLessOrEqualTo", subjectIndex: 0, argumentsToRemove: []);
}

return null;
}

private CreateChangedDocument TryComputeFixForNunit4ClassicAssert(IInvocationOperation invocation, CodeFixContext context, TestingFrameworkCodeFixContext t)
{
switch (invocation.TargetMethod.Name)
{
case "True": // Assert.True(bool condition)
case "IsTrue": // Assert.IsTrue(bool condition)
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "BeTrue", subjectIndex: 0, argumentsToRemove: []);
case "False": // Assert.False(bool condition)
case "IsFalse": // Assert.IsFalse(bool condition)
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "BeFalse", subjectIndex: 0, argumentsToRemove: []);
case "Null": // Assert.Null(object anObject)
case "IsNull": // Assert.IsNull(object anObject)
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "BeNull", subjectIndex: 0, argumentsToRemove: []);
case "NotNull": // Assert.NotNull(object anObject)
case "IsNotNull": // Assert.IsNotNull(object anObject)
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "NotBeNull", subjectIndex: 0, argumentsToRemove: []);
}

return null;
}
}
Loading

0 comments on commit 9fd07fb

Please sign in to comment.