nunit/nunit.analyzers

[suggestion] NUnit1028 could be improved

Bartleby2718 opened this issue · 5 comments

Problem 1:

private static bool IsPublicOrInternalMethod(IMethodSymbol method)
{
switch (method.DeclaredAccessibility)
{
case Accessibility.Public:
case Accessibility.Internal:
case Accessibility.ProtectedOrInternal:
return true;
default:
return false;
}
}

clearly says that NUnit1028 detects public or internal methods, but the title, message, and description don't mention internal:
internal const string NonTestMethodIsPublicTitle = "The non-test method is public";
internal const string NonTestMethodIsPublicMessage = "Only test methods should be public";
internal const string NonTestMethodIsPublicDescription = "A fixture should not contain any public non-test methods.";

Problem 2:

private static SyntaxTokenList ReplaceModifiersWithPrivate(MethodDeclarationSyntax originalExpression)
{
var firstAccessModifier = true;
var isProtected = false;
var newSyntaxTokens = new List<SyntaxToken>();
foreach (var syntaxToken in originalExpression.Modifiers)
{
if (IsPublicAccessModifier(syntaxToken))
{
if (firstAccessModifier && !isProtected)
{
firstAccessModifier = false;
var newPrivateToken = SyntaxFactory.Token(
syntaxToken.LeadingTrivia,
SyntaxKind.PrivateKeyword,
syntaxToken.TrailingTrivia);
newSyntaxTokens.Add(newPrivateToken);
}
}
else
{
if (syntaxToken.IsKind(SyntaxKind.ProtectedKeyword))
isProtected = true;
newSyntaxTokens.Add(syntaxToken);
}
}
return new SyntaxTokenList(newSyntaxTokens);
}
private static bool HasExplicitPublicAccessModifier(MethodDeclarationSyntax methodDeclarationSyntax)
{
return methodDeclarationSyntax.Modifiers.Any(m => IsPublicAccessModifier(m));
}
private static bool IsPublicAccessModifier(SyntaxToken syntaxToken) =>
syntaxToken.IsKind(SyntaxKind.PublicKeyword) ||
syntaxToken.IsKind(SyntaxKind.InternalKeyword);
}
makes the offending method private, but it should suggest so only if it isn't used anywhere else. Not sure if this can be done, but it should definitely be possible to reduce false positives.

@Bartleby2718 Yes, the wording could be improved, to something like The non-test method is not private.
Unfortunately there is no way to see if the method is used elsewhere. The analyzer pass only knows about the current "file", not about others. The code fix is to help, not blindly follow. If method are really used it would involve moving the method to another helper class or so.