From 66e1c86c2062c1216c4d10d7393d3ef716d07f33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Verdier?= Date: Mon, 4 Mar 2024 12:18:15 -0500 Subject: [PATCH 1/2] Remove null message in AreEqual code fix ``` Assert.AreEqual(2d, 3d, null); ``` would generate ``` Assert.That(3d, Is.EqualTo(2d), null); ``` which does not compile ``` The call is ambiguous between the following methods or properties: 'Assert.That(TActual, IResolveConstraint, FormattableString, string, string)' and 'Assert.That(TActual, IResolveConstraint, Func, string, string)' ``` --- ...reEqualClassicModelAssertUsageCodeFixTests.cs | 16 ++++++++++++++++ .../ClassicModelAssertUsageCodeFix.cs | 6 ++++++ 2 files changed, 22 insertions(+) diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreEqualClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreEqualClassicModelAssertUsageCodeFixTests.cs index e00ed667..5bf96b52 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreEqualClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreEqualClassicModelAssertUsageCodeFixTests.cs @@ -56,6 +56,22 @@ public void TestMethod() RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } + [Test] + public void VerifyAreEqualFixWithNullMessage() + { + var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" + public void TestMethod() + { + ↓ClassicAssert.AreEqual(2d, 3d, null); + }"); + var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" + public void TestMethod() + { + Assert.That(3d, Is.EqualTo(2d)); + }"); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); + } + [Test] public void VerifyAreEqualFixWithMessageAndParams() { diff --git a/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageCodeFix.cs b/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageCodeFix.cs index a822e7da..400a12f1 100644 --- a/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageCodeFix.cs +++ b/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageCodeFix.cs @@ -55,6 +55,12 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) // Now, replace the arguments. List arguments = invocationNode.ArgumentList.Arguments.ToList(); + // Remove null message to avoid ambiguous calls. + if (arguments.Count == 3 && arguments[2].Expression.Kind() == SyntaxKind.NullLiteralExpression) + { + arguments.RemoveAt(2); + } + // See if we need to cast the arguments when they were using a specific classic overload. arguments[0] = CastIfNecessary(arguments[0]); if (arguments.Count > 1) From 0c12fdb5f25014ce069c59c3bba9cd83f04f5e58 Mon Sep 17 00:00:00 2001 From: verdie-g Date: Mon, 4 Mar 2024 18:47:15 -0500 Subject: [PATCH 2/2] Address PR comments --- ...reEqualClassicModelAssertUsageCodeFixTests.cs | 16 ++++++++++++++++ .../ClassicModelAssertUsageCodeFix.cs | 12 ++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreEqualClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreEqualClassicModelAssertUsageCodeFixTests.cs index 5bf96b52..e1ddfdc6 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreEqualClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreEqualClassicModelAssertUsageCodeFixTests.cs @@ -136,6 +136,22 @@ public void TestMethod() RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } + [Test] + public void VerifyAreEqualFixWhenToleranceExistsWithNullMessage() + { + var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" + public void TestMethod() + { + ↓ClassicAssert.AreEqual(2d, 3d, 0.1, null); + }"); + var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" + public void TestMethod() + { + Assert.That(3d, Is.EqualTo(2d).Within(0.1)); + }"); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); + } + [Test] public void VerifyAreEqualFixWhenToleranceExistsWithMessageAndParams() { diff --git a/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageCodeFix.cs b/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageCodeFix.cs index 400a12f1..881c679d 100644 --- a/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageCodeFix.cs +++ b/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageCodeFix.cs @@ -55,12 +55,6 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) // Now, replace the arguments. List arguments = invocationNode.ArgumentList.Arguments.ToList(); - // Remove null message to avoid ambiguous calls. - if (arguments.Count == 3 && arguments[2].Expression.Kind() == SyntaxKind.NullLiteralExpression) - { - arguments.RemoveAt(2); - } - // See if we need to cast the arguments when they were using a specific classic overload. arguments[0] = CastIfNecessary(arguments[0]); if (arguments.Count > 1) @@ -72,6 +66,12 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) else this.UpdateArguments(diagnostic, arguments, typeArguments); + // Remove null message to avoid ambiguous calls. + if (arguments.Count == 3 && arguments[2].Expression.IsKind(SyntaxKind.NullLiteralExpression)) + { + arguments.RemoveAt(2); + } + // Do the format spec, params to formattable string conversion CodeFixHelper.UpdateStringFormatToFormattableString(arguments, this.MinimumNumberOfParameters);