-
Notifications
You must be signed in to change notification settings - Fork 284
Implement assert contains overload to accept non-generic collection #6417
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
base: main
Are you sure you want to change the base?
Implement assert contains overload to accept non-generic collection #6417
Conversation
…_to_accept_non-generic_collection
src/TestFramework/TestFramework/PublicAPI/PublicAPI.Shipped.txt
Outdated
Show resolved
Hide resolved
test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.Contains.cs
Outdated
Show resolved
Hide resolved
…c_collection' of https://github.com/AtolagbeMuiz/testfx into Implement_Assert_contains_overload_to_accept_non-generic_collection
/// </summary> | ||
/// <param name="expected">The expected item.</param> | ||
/// <param name="collection">The non-generic collection (like ArrayList).</param> | ||
public static void Contains(object expected, IEnumerable collection) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need similar non-generic overloads also for IsEmpty
and HasCount
. Then MSTEST0037 analyzer need to be adjusted as well to account for the existence of the non-generic overloads:
testfx/src/Analyzers/MSTest.Analyzers/UseProperAssertMethodsAnalyzer.cs
Lines 464 to 471 in 8f99258
private static bool IsBCLCollectionType(ITypeSymbol type, INamedTypeSymbol objectTypeSymbol) | |
// Check if the type implements IEnumerable<T> (but is not string) | |
// Note: Assert.Contains/IsEmpty/HasCount for collections accept IEnumerable<T>, but not IEnumerable. | |
=> type.SpecialType != SpecialType.System_String && type.AllInterfaces.Any(i => | |
i.OriginalDefinition.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T) && | |
// object is coming from BCL and it's expected to always have a public key. | |
type.ContainingAssembly.Identity.HasPublicKey == objectTypeSymbol.ContainingAssembly.Identity.HasPublicKey && | |
type.ContainingAssembly.Identity.PublicKey.SequenceEqual(objectTypeSymbol.ContainingAssembly.Identity.PublicKey); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I intend to implement this for IsEmpty etc. as well.. still yet to have a good understanding of the Analyzer part.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once you add the overload for HasCount
, this analyzer test will fail:
testfx/test/UnitTests/MSTest.Analyzers.UnitTests/UseProperAssertMethodsAnalyzerTests.cs
Line 2134 in 8f99258
public async Task WhenAssertAreEqualWithCollectionCountUsingNonGenericCollection() |
The test will need to be updated as following (note: I'm writing it directly on GitHub so there might be small mistakes):
[TestMethod]
public async Task WhenAssertAreEqualWithCollectionCountUsingNonGenericCollection()
{
string code = """
using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class MyTestClass
{
[TestMethod]
public void MyTestMethod()
{
var x = new Hashtable();
{|#0:Assert.AreEqual(4, x.Count)|};
}
}
""";
string fixedCode = """
using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class MyTestClass
{
[TestMethod]
public void MyTestMethod()
{
var x = new Hashtable();
Assert.HasCount(4, x);
}
}
""";
await VerifyCS.VerifyCodeFixAsync(
code,
// /0/Test0.cs(13,9): info MSTEST0037: Use 'Assert.HasCount' instead of 'Assert.AreEqual'
VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("HasCount", "AreEqual"),
fixedCode);
}
The analyzer implementation then will need to check System_Collections_Generic_IEnumerable
instead of System_Collections_Generic_IEnumerable_T
Note: because we use AllInterfaces
, and IEnumerable<T>
is IEnumerable
, we need only IEnumerable
check. We don't need both IEnumerable<T>
and IEnumerable
.
Note 2: OriginalDefinition
access will become redundant, because we are no longer dealing with generics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i will revert back to this once I want to implement for HasCount
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @AtolagbeMuiz.
Are you planning to continue that soon? It's best to have all the overloads in the same PR as the analyzer is likely handling all these methods in the same way (even if we have only test coverage for HasCount
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Youssef1313, should the implementation for other Assert methods like HasCount be in this same PR and branch and not as a different branch??
was intending to work on it on a different branch.. I should commence work on it this week.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I prefer if it's the same PR in this case. Thanks @AtolagbeMuiz!
…c_collection' of https://github.com/AtolagbeMuiz/testfx into Implement_Assert_contains_overload_to_accept_non-generic_collection
This Pull Request fixes Collection assert methods should accept IEnumerable collections #6184
This implementation involves an overload of
Assert.Contains
which allows non-generic IEnumerable collection like ArrayList and Stack.Current Behaviour
Currently, the
Assert.Contains
function doesn't allow non-generic collection like ArrayList as this throws compile time error as seen belowExpected Behaviour
With this Implementation,
Assert.Contains
will allow non-generic collection as seen below;