Skip to content

Commit

Permalink
Merge pull request #710 from matode/nunit1032ConsiderExplicitInterfac…
Browse files Browse the repository at this point in the history
…eImplementation

Nunit1032 - consider dispose of a type having explicit interface implementation
  • Loading branch information
mikkelbu committed Mar 27, 2024
2 parents d53e02e + 7573fb6 commit e52e3a1
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ sealed class DummyDisposable : IDisposable
public void Dispose() {}
}";

private const string DummyExplicitDisposable = @"
sealed class DummyExplicitDisposable : IAnotherInterface, IDisposable
{
void IDisposable.Dispose() {}
}
public interface IAnotherInterface
{
}";

// CA2000 allows transfer of ownership using ICollection<IDisposable>.Add
private const string Disposer = @"
private sealed class Disposer : IDisposable
Expand Down Expand Up @@ -114,6 +123,29 @@ public void TearDownMethod()
RoslynAssert.Valid(analyzer, testCode);
}

[Test]
public void AnalyzeWhenExplicitlyInterfaceImplementedDisposableFieldSetInConstructorIsDisposedInOneTimeTearDownMethod()
{
var testCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@"
private IAnotherInterface field;
public TestClass()
{{
field = new DummyExplicitDisposable();
}}
[OneTimeTearDown]
public void TearDownMethod()
{{
((IDisposable)field).Dispose();
}}
{DummyExplicitDisposable}
");

RoslynAssert.Valid(analyzer, testCode);
}

[TestCase("", "OneTime")]
[TestCase("OneTime", "")]
public void AnalyzeWhenFieldIsDisposedInWrongMethod(string attributePrefix1, string attributePrefix2)
Expand Down Expand Up @@ -1005,10 +1037,10 @@ public void TearDown()
public partial class TestFixture
{
[Test]
public void SomeTest()
{
SomeAsserts();
}
public void SomeTest()
{
SomeAsserts();
}
}");

RoslynAssert.Valid(analyzer, testCodePart1, testCodePart2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,16 @@ private static void DisposedIn(Parameters parameters, HashSet<string> disposals,
return memberAccessExpression.Name.Identifier.Text;
}

// considering cast to IDisposable, e.g. in case of explicit interface implementation of IDisposable.Dispose()
else if (expression is ParenthesizedExpressionSyntax parenthesizedExpression &&
parenthesizedExpression.Expression is CastExpressionSyntax castExpression &&
castExpression.Expression is IdentifierNameSyntax castIdentifierName &&
castExpression.Type is IdentifierNameSyntax typeIdentifierName &&
typeIdentifierName.Identifier.Text.Equals("IDisposable", StringComparison.Ordinal))
{
return castIdentifierName.Identifier.Text;
}

return null;
}

Expand Down

0 comments on commit e52e3a1

Please sign in to comment.