diff --git a/src/xunit.assert/Asserts b/src/xunit.assert/Asserts index 3b8edcbf1..574aebac4 160000 --- a/src/xunit.assert/Asserts +++ b/src/xunit.assert/Asserts @@ -1 +1 @@ -Subproject commit 3b8edcbf114cf0c0f27750c5bd94a9d06ce33a64 +Subproject commit 574aebac41dbbbf9e5e98bb9c65c6c5fab9b47f5 diff --git a/test/test.xunit.assert/Asserts/CollectionAssertsTests.cs b/test/test.xunit.assert/Asserts/CollectionAssertsTests.cs index b8f8b6323..e05edee10 100644 --- a/test/test.xunit.assert/Asserts/CollectionAssertsTests.cs +++ b/test/test.xunit.assert/Asserts/CollectionAssertsTests.cs @@ -324,15 +324,22 @@ public static void NullsAllowedInContainer() } [Fact] - public static void HashSetIsTreatedSpecially() + public static void SetsAreTreatedSpecially() { - // HashSet.Contains() is a custom implementation since the comparer is passed - // to the constructor. If this comes in via the IEnumerable overload, we want - // to make sure it still gets treated like a HashSet. IEnumerable set = new HashSet(StringComparer.OrdinalIgnoreCase) { "Hi there" }; Assert.Contains("HI THERE", set); } + +#if NET5_0_OR_GREATER + [Fact] + public static void ReadOnlySetsAreTreatedSpecially() + { + IEnumerable set = new ReadOnlySet(StringComparer.OrdinalIgnoreCase, "Hi there"); + + Assert.Contains("HI THERE", set); + } +#endif } public class Contains_Comparer @@ -536,11 +543,8 @@ public static void NullsAllowedInContainer() } [Fact] - public static void HashSetIsTreatedSpecially() + public static void SetsAreTreatedSpecially() { - // HashSet.Contains() is a custom implementation since the comparer is passed - // to the constructor. If this comes in via the IEnumerable overload, we want - // to make sure it still gets treated like a HashSet. IEnumerable set = new HashSet(StringComparer.OrdinalIgnoreCase) { "Hi there" }; var ex = Record.Exception(() => Assert.DoesNotContain("HI THERE", set)); @@ -554,6 +558,25 @@ public static void HashSetIsTreatedSpecially() ex.Message ); } + +#if NET5_0_OR_GREATER + [Fact] + public static void ReadOnlySetsAreTreatedSpecially() + { + IEnumerable set = new ReadOnlySet(StringComparer.OrdinalIgnoreCase, "Hi there"); + + var ex = Record.Exception(() => Assert.DoesNotContain("HI THERE", set)); + + Assert.IsType(ex); + // Note: There is no pointer for sets, unlike other collections + Assert.Equal( + "Assert.DoesNotContain() Failure: Item found in set" + Environment.NewLine + + "Set: [\"Hi there\"]" + Environment.NewLine + + "Found: \"HI THERE\"", + ex.Message + ); + } +#endif } public class DoesNotContain_Comparer diff --git a/test/test.xunit.assert/Utility/ReadOnlySet.cs b/test/test.xunit.assert/Utility/ReadOnlySet.cs new file mode 100644 index 000000000..e7064c99b --- /dev/null +++ b/test/test.xunit.assert/Utility/ReadOnlySet.cs @@ -0,0 +1,28 @@ +#if NET5_0_OR_GREATER + +using System.Collections; +using System.Collections.Generic; + +public class ReadOnlySet : IReadOnlySet +{ + readonly HashSet hashSet; + + public ReadOnlySet( + IEqualityComparer comparer, + params T[] items) => + hashSet = new HashSet(items, comparer); + + public int Count => hashSet.Count; + + public bool Contains(T item) => hashSet.Contains(item); + public IEnumerator GetEnumerator() => hashSet.GetEnumerator(); + public bool IsProperSubsetOf(IEnumerable other) => hashSet.IsProperSubsetOf(other); + public bool IsProperSupersetOf(IEnumerable other) => hashSet.IsProperSupersetOf(other); + public bool IsSubsetOf(IEnumerable other) => hashSet.IsSubsetOf(other); + public bool IsSupersetOf(IEnumerable other) => hashSet.IsSupersetOf(other); + public bool Overlaps(IEnumerable other) => hashSet.Overlaps(other); + public bool SetEquals(IEnumerable other) => hashSet.SetEquals(other); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); +} + +#endif