Skip to content

Commit

Permalink
Detect using (Assert.EnterMultipleScope()) as an Assert.Multiple
Browse files Browse the repository at this point in the history
…context.
  • Loading branch information
manfred-brands committed Jan 8, 2025
1 parent 568d5ea commit 804395a
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,10 @@ public sealed class NUnitFrameworkConstantsTests
(nameof(NUnitFrameworkConstants.NameOfMultiple), nameof(Assert.Multiple)),
#if NUNIT4
(nameof(NUnitFrameworkConstants.NameOfMultipleAsync), nameof(Assert.MultipleAsync)),
(nameof(NUnitFrameworkConstants.NameOfEnterMultipleScope), nameof(Assert.EnterMultipleScope)),
#else
(nameof(NUnitFrameworkConstants.NameOfMultipleAsync), "MultipleAsync"),
(nameof(NUnitFrameworkConstants.NameOfEnterMultipleScope), "EnterMultipleScope"),
#endif

(nameof(NUnitFrameworkConstants.NameOfOut), nameof(TestContext.Out)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,38 @@ await Assert.MultipleAsync(async () =>
}");
RoslynAssert.Valid(this.analyzer, testCode);
}

#if WOULD_SOMEONE_ACTUALLY_USE_THIS
[Test]
public void AnalyzeWhenMultipleScopeDeclarationIsUsed()
{
var testCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@"
public void Test()
{
using IDisposable disposable = Assert.EnterMultipleScope();
Assert.That(true, Is.True);
disposable.Dispose();
Assert.That(false, Is.False);
}");
RoslynAssert.Valid(this.analyzer, testCode);
}
#endif

[Test]
public void AnalyzeWhenMultipleScopeStatementIsUsed()
{
var testCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@"
public void Test()
{
using (Assert.EnterMultipleScope())
{
Assert.That(true, Is.True);
Assert.That(false, Is.False);
}
}");
RoslynAssert.Valid(this.analyzer, testCode);
}
#endif

[Test]
Expand Down
1 change: 1 addition & 0 deletions src/nunit.analyzers/Constants/NUnitFrameworkConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public static class NUnitFrameworkConstants

public const string NameOfMultiple = "Multiple";
public const string NameOfMultipleAsync = "MultipleAsync";
public const string NameOfEnterMultipleScope = "EnterMultipleScope";

public const string NameOfOut = "Out";
public const string NameOfWrite = "Write";
Expand Down
27 changes: 22 additions & 5 deletions src/nunit.analyzers/Helpers/AssertHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,35 @@ public static bool IsLiteralOperation(IOperation operation)
/// </summary>
public static bool IsInsideAssertMultiple(SyntaxNode node)
{
InvocationExpressionSyntax? possibleAssertMultiple;

while ((possibleAssertMultiple = node.Ancestors().OfType<InvocationExpressionSyntax>().FirstOrDefault()) is not null)
// Look for Assert.Multiple(delegate) invocation.
SyntaxNode currentNode = node;
InvocationExpressionSyntax? possibleAssertMultipleInvocation;
while ((possibleAssertMultipleInvocation = currentNode.Ancestors().OfType<InvocationExpressionSyntax>().FirstOrDefault()) is not null)
{
// Is the statement inside a Block which is part of an Assert.Multiple.
if (IsAssert(possibleAssertMultiple, NUnitFrameworkConstants.NameOfMultiple, NUnitFrameworkConstants.NameOfMultipleAsync))
if (IsAssert(possibleAssertMultipleInvocation, NUnitFrameworkConstants.NameOfMultiple, NUnitFrameworkConstants.NameOfMultipleAsync))
{
return true;
}

// Keep looking at possible parent nested expression.
currentNode = possibleAssertMultipleInvocation;
}

// Look for using (Assert.EnterMultipleScope()) invocation.
currentNode = node;
UsingStatementSyntax? usingStatement;
while ((usingStatement = currentNode.Ancestors().OfType<UsingStatementSyntax>().FirstOrDefault()) is not null)
{
// Is the using expression an Assert.EnterMultipleScope.
if (usingStatement.Expression is InvocationExpressionSyntax usingInvocation &&
IsAssert(usingInvocation, NUnitFrameworkConstants.NameOfEnterMultipleScope))
{
return true;
}

// Keep looking at possible parent nested expression.
node = possibleAssertMultiple;
currentNode = usingStatement;
}

return false;
Expand Down

0 comments on commit 804395a

Please sign in to comment.