Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using null conditional in assertion should be reported as code smell #21

Closed
krajek opened this issue Jan 9, 2018 · 2 comments · Fixed by #22
Closed

Using null conditional in assertion should be reported as code smell #21

krajek opened this issue Jan 9, 2018 · 2 comments · Fixed by #22

Comments

@krajek
Copy link

krajek commented Jan 9, 2018

In main FA repository, there was an issue reported fluentassertions/fluentassertions#569.

To keep it short, the user used ?. operator:

int? val = null;
val?.Should().Be(400);

instead of regular

val.Should().Be(400);

Do you think it is possible to detect such scenario and suggest code fix?

@jnyrup
Copy link
Member

jnyrup commented Jan 9, 2018

That is not only a code smell for Nullable but for all reference types where null conditional operator is used before calling Should()

In this example Should() is never called, as the null conditional operator short-circuits the expression.

string str = null;
str?.Should().NotBeNull();

There is SyntaxKind.ConditionalAccessExpression to check for usages of a?.b and a?[1].

@Meir017
Copy link
Member

Meir017 commented Jan 11, 2018

I have a working sample for this.
image

class ConditionalAccessExpressionVisitor : CSharpSyntaxWalker
{
    public bool CodeSmells { get; private set; }
    public Location ConditionalAccess { get; private set; }

    public override void VisitConditionalAccessExpression(ConditionalAccessExpressionSyntax node)
    {
        if (CodeSmells) return;

        CodeSmells = node.WhenNotNull is InvocationExpressionSyntax invocation
            && invocation.Expression is MemberAccessExpressionSyntax memberAccess && memberAccess.IsKind(SyntaxKind.SimpleMemberAccessExpression)
            && memberAccess.Expression is InvocationExpressionSyntax shouldInvocation
            && shouldInvocation.Expression is MemberBindingExpressionSyntax memberBinding
            && memberBinding.Name.Identifier.ValueText == "Should";
        if (CodeSmells)
        {
            ConditionalAccess = node.GetLocation();
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants