diff --git a/src/xunit.analyzers.fixes/X2000/BooleanAssertsShouldNotBeNegatedFixer.cs b/src/xunit.analyzers.fixes/X2000/BooleanAssertsShouldNotBeNegatedFixer.cs index b8a9b6bb..1be3bed7 100644 --- a/src/xunit.analyzers.fixes/X2000/BooleanAssertsShouldNotBeNegatedFixer.cs +++ b/src/xunit.analyzers.fixes/X2000/BooleanAssertsShouldNotBeNegatedFixer.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Composition; using System.Linq; using System.Threading; @@ -57,13 +58,26 @@ static async Task UseSuggestedAssert( var editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false); if (invocation.Expression is MemberAccessExpressionSyntax memberAccess) + { if (invocation.ArgumentList.Arguments[0].Expression is PrefixUnaryExpressionSyntax prefixUnaryExpression) + { + var originalArguments = invocation.ArgumentList.Arguments; + var newFirstArgument = Argument(prefixUnaryExpression.Operand); + + var newArguments = new List { newFirstArgument }; + if (originalArguments.Count > 1) + { + newArguments.AddRange(originalArguments.Skip(1)); + } + editor.ReplaceNode( invocation, invocation - .WithArgumentList(ArgumentList(SeparatedList([Argument(prefixUnaryExpression.Operand)]))) + .WithArgumentList(ArgumentList(SeparatedList(newArguments))) .WithExpression(memberAccess.WithName(IdentifierName(replacement))) ); + } + } return editor.GetChangedDocument(); } diff --git a/src/xunit.analyzers.tests/Fixes/X2000/BooleanAssertsShouldNotBeNegatedFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/BooleanAssertsShouldNotBeNegatedFixerTests.cs index cdc8c9db..e950b9a9 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/BooleanAssertsShouldNotBeNegatedFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/BooleanAssertsShouldNotBeNegatedFixerTests.cs @@ -6,17 +6,17 @@ public class BooleanAssertsShouldNotBeNegatedFixerTests { const string template = /* lang=c#-test */ """ - using Xunit; + using Xunit; - public class TestClass {{ - [Fact] - public void TestMethod() {{ - bool condition = true; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + bool condition = true; - {0}; - }} + {0}; }} - """; + }} + """; [Theory] [InlineData("False", "True")] @@ -30,4 +30,66 @@ public async Task ReplacesBooleanAssert( await Verify.VerifyCodeFix(before, after, BooleanAssertsShouldNotBeNegatedFixer.Key_UseSuggestedAssert); } + + [Theory] + [InlineData("False", "True")] + [InlineData("True", "False")] + public async Task PreservesUserMessageNamedParameter( + string assertion, + string replacement) + { + var before = string.Format(template, $"[|Assert.{assertion}(!condition, userMessage: \"test message\")|]"); + var after = string.Format(template, $"Assert.{replacement}(condition, userMessage: \"test message\")"); + + await Verify.VerifyCodeFix(before, after, BooleanAssertsShouldNotBeNegatedFixer.Key_UseSuggestedAssert); + } + + [Theory] + [InlineData("False", "True")] + [InlineData("True", "False")] + public async Task PreservesUserMessagePositionalParameter( + string assertion, + string replacement) + { + var before = string.Format(template, $"[|Assert.{assertion}(!condition, \"test message\")|]"); + var after = string.Format(template, $"Assert.{replacement}(condition, \"test message\")"); + + await Verify.VerifyCodeFix(before, after, BooleanAssertsShouldNotBeNegatedFixer.Key_UseSuggestedAssert); + } + + [Fact] + public async Task PreservesWhitespace() + { + var before = string.Format(template, "[|Assert.True( !condition )|]"); + var after = string.Format(template, "Assert.False(condition)"); + + await Verify.VerifyCodeFix(before, after, BooleanAssertsShouldNotBeNegatedFixer.Key_UseSuggestedAssert); + } + + [Fact] + public async Task NegatedLiteral() + { + var before = string.Format(template, "[|Assert.True(!false)|]"); + var after = string.Format(template, "Assert.False(false)"); + + await Verify.VerifyCodeFix(before, after, BooleanAssertsShouldNotBeNegatedFixer.Key_UseSuggestedAssert); + } + + [Fact] + public async Task NegatedPropertyAccess() + { + var before = string.Format(template, "[|Assert.True(!condition)|]"); + var after = string.Format(template, "Assert.False(condition)"); + + await Verify.VerifyCodeFix(before, after, BooleanAssertsShouldNotBeNegatedFixer.Key_UseSuggestedAssert); + } + + [Fact] + public async Task PreservesUserMessageWithComplexExpression() + { + var before = string.Format(template, "[|Assert.True(!false, userMessage: \"test\")|]"); + var after = string.Format(template, "Assert.False(false, userMessage: \"test\")"); + + await Verify.VerifyCodeFix(before, after, BooleanAssertsShouldNotBeNegatedFixer.Key_UseSuggestedAssert); + } }