In the current implementations of BeSubsetOf and BeEquivalentTo there is an explicit check to see if the source is Empty and asserts failure if so. I think this is wrong for two reasons. First, an empty set is mathematically a subset of any set (in that there are no members of the subset that do no exist in the superset). Secondly, and this is the more important point, there is no way to achieve that functionality (that I've found) without writing my own wrapper around Fluent Extensions. To give an example:
emptySet.Should().BeSubsetOf(someOtherSet); // fails
If the implementation were changed such that an empty set did not fail the assert, the existing functionality could be achieved with .And:
emptySet.Should().BeSubsetOf(someOtherSet).And.NotBeEmpty(); // fails, like before
emptySet.Should().BeSubsetOf(someOtherSet); // happily succeeds
Similarly, with BeEquivalentTo, and empty set is equivalent to another empty set, but the implementation explicitly fails the test.
Since the existing functionality can be achieved with .And and there is no way to achieve the other functionality without implementing it special, I suggest the design be changed such that empty sets do not fail these methods (or any others that are similar).
For reference, here is the work around I had to employ:
public static AndConstraint<GenericCollectionAssertions<T>> BeEmptyOrSubsetOf<T>(
this GenericCollectionAssertions<T> source, IEnumerable<T> expected, string reason = null, params object[] reasonArgs)
{
var subject = source.Subject.ToList();
return subject.Any()
? subject.Should().BeSubsetOf(expected, reason, reasonArgs)
: subject.Should().BeEmpty(reason, reasonArgs);
}
Thank you.
Comments: ** Comment from web user: dennisdoomen **
emptySet.Should().BeSubsetOf(someOtherSet); // fails
If the implementation were changed such that an empty set did not fail the assert, the existing functionality could be achieved with .And:
emptySet.Should().BeSubsetOf(someOtherSet).And.NotBeEmpty(); // fails, like before
emptySet.Should().BeSubsetOf(someOtherSet); // happily succeeds
Similarly, with BeEquivalentTo, and empty set is equivalent to another empty set, but the implementation explicitly fails the test.
Since the existing functionality can be achieved with .And and there is no way to achieve the other functionality without implementing it special, I suggest the design be changed such that empty sets do not fail these methods (or any others that are similar).
For reference, here is the work around I had to employ:
public static AndConstraint<GenericCollectionAssertions<T>> BeEmptyOrSubsetOf<T>(
this GenericCollectionAssertions<T> source, IEnumerable<T> expected, string reason = null, params object[] reasonArgs)
{
var subject = source.Subject.ToList();
return subject.Any()
? subject.Should().BeSubsetOf(expected, reason, reasonArgs)
: subject.Should().BeEmpty(reason, reasonArgs);
}
Thank you.
Comments: ** Comment from web user: dennisdoomen **
Even though this is a breaking change, I agree that this behavior is better.