Skip to content

Commit

Permalink
Fix discard handling for newer Assert.Throws codefix (#5117)
Browse files Browse the repository at this point in the history
  • Loading branch information
Youssef1313 authored Feb 24, 2025
1 parent 149076d commit b3a19f7
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ private static SyntaxNode UpdateMethodName(SyntaxEditor editor, InvocationExpres
{
editor.ReplaceNode(
lambdaSyntax.ExpressionBody,
AssignToDiscard(lambdaSyntax.ExpressionBody));
AssignToDiscardIfNeeded(lambdaSyntax.ExpressionBody));
}
else if (lambdaSyntax.Block is not null)
{
Expand All @@ -126,7 +126,7 @@ private static SyntaxNode UpdateMethodName(SyntaxEditor editor, InvocationExpres
continue;
}

ExpressionStatementSyntax returnReplacement = SyntaxFactory.ExpressionStatement(AssignToDiscard(returnStatement.Expression));
ExpressionStatementSyntax returnReplacement = SyntaxFactory.ExpressionStatement(AssignToDiscardIfNeeded(returnStatement.Expression));

if (returnStatement.Parent is BlockSyntax blockSyntax)
{
Expand All @@ -151,12 +151,24 @@ private static SyntaxNode UpdateMethodName(SyntaxEditor editor, InvocationExpres
SyntaxFactory.ParenthesizedLambdaExpression(
SyntaxFactory.ParameterList(),
block: null,
expressionBody: AssignToDiscard(SyntaxFactory.InvocationExpression(SyntaxFactory.ParenthesizedExpression(expressionSyntax).WithAdditionalAnnotations(Simplifier.Annotation)))));
expressionBody: SyntaxFactory.InvocationExpression(SyntaxFactory.ParenthesizedExpression(expressionSyntax).WithAdditionalAnnotations(Simplifier.Annotation))));
}

return editor.GetChangedRoot();
}

private static AssignmentExpressionSyntax AssignToDiscard(ExpressionSyntax expression)
=> SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, SyntaxFactory.IdentifierName("_"), expression);
private static ExpressionSyntax AssignToDiscardIfNeeded(ExpressionSyntax expression)
=> NeedsDiscard(expression)
? SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, SyntaxFactory.IdentifierName("_"), expression)
: expression;

private static bool NeedsDiscard(ExpressionSyntax expression)
=> expression is not InvocationExpressionSyntax &&
expression is not AssignmentExpressionSyntax &&
!expression.IsKind(SyntaxKind.PostIncrementExpression) &&
!expression.IsKind(SyntaxKind.PostDecrementExpression) &&
!expression.IsKind(SyntaxKind.PreIncrementExpression) &&
!expression.IsKind(SyntaxKind.PreDecrementExpression) &&
expression is not AwaitExpressionSyntax &&
expression is not ObjectCreationExpressionSyntax;
}
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ public class MyTestClass
public void MyTestMethod()
{
Func<object> action = () => _ = 5;
Assert.ThrowsExactly<Exception>(() => _ = action());
Assert.ThrowsExactly<Exception>(() => action());
}
}
""";
Expand Down Expand Up @@ -288,11 +288,85 @@ public class MyTestClass
public void MyTestMethod()
{
Func<object> action = () => _ = 5;
Assert.ThrowsExactly<Exception>(() => _ = (action + action)());
Assert.ThrowsExactly<Exception>(() => (action + action)());
}
}
""";

await VerifyCS.VerifyCodeFixAsync(code, fixedCode);
}

[TestMethod]
public async Task VariousTestCasesForDiscard()
{
string code = """
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public sealed class Test1
{
[TestMethod]
public void TestMethod1()
{
int[] numbers = [1];
int x = 0;
string s = "";
[|Assert.ThrowsException<ArgumentException>(() => VoidMethod(1))|];
[|Assert.ThrowsException<ArgumentException>(() => NonVoidMethod(1))|];
[|Assert.ThrowsException<ArgumentException>(() => _ = NonVoidMethod(1))|];
[|Assert.ThrowsException<ArgumentException>(() => new Test1())|];
[|Assert.ThrowsException<ArgumentException>(() => _ = new Test1())|];
[|Assert.ThrowsException<ArgumentException>(() => numbers[0] = 4)|];
[|Assert.ThrowsException<ArgumentException>(() => x++)|];
[|Assert.ThrowsException<ArgumentException>(() => x--)|];
[|Assert.ThrowsException<ArgumentException>(() => ++x)|];
[|Assert.ThrowsException<ArgumentException>(() => --x)|];
[|Assert.ThrowsException<ArgumentException>(() => s!)|];
[|Assert.ThrowsException<ArgumentException>(() => !true)|];
}
private void VoidMethod(object o) => _ = o;
private int NonVoidMethod(int i) => i;
}
""";

string fixedCode = """
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public sealed class Test1
{
[TestMethod]
public void TestMethod1()
{
int[] numbers = [1];
int x = 0;
string s = "";
Assert.ThrowsExactly<ArgumentException>(() => VoidMethod(1));
Assert.ThrowsExactly<ArgumentException>(() => NonVoidMethod(1));
Assert.ThrowsExactly<ArgumentException>(() => _ = NonVoidMethod(1));
Assert.ThrowsExactly<ArgumentException>(() => new Test1());
Assert.ThrowsExactly<ArgumentException>(() => _ = new Test1());
Assert.ThrowsExactly<ArgumentException>(() => numbers[0] = 4);
Assert.ThrowsExactly<ArgumentException>(() => x++);
Assert.ThrowsExactly<ArgumentException>(() => x--);
Assert.ThrowsExactly<ArgumentException>(() => ++x);
Assert.ThrowsExactly<ArgumentException>(() => --x);
Assert.ThrowsExactly<ArgumentException>(() => _ = s!);
Assert.ThrowsExactly<ArgumentException>(() => _ = !true);
}
private void VoidMethod(object o) => _ = o;
private int NonVoidMethod(int i) => i;
}
""";

await VerifyCS.VerifyCodeFixAsync(code, fixedCode);
}
}

0 comments on commit b3a19f7

Please sign in to comment.