diff --git a/src/Foundation/NSMutableSet.cs b/src/Foundation/NSMutableSet.cs index a81434cc2d9f..9f225b4488c8 100644 --- a/src/Foundation/NSMutableSet.cs +++ b/src/Foundation/NSMutableSet.cs @@ -29,24 +29,22 @@ using System.Collections; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; -// Disable until we get around to enable + fix any issues. -#nullable disable +#nullable enable namespace Foundation { public partial class NSMutableSet : IEnumerable { - /// To be added. - /// To be added. - /// To be added. + /// Initializes a new mutable set with the specified objects. + /// The objects to add to the set. public NSMutableSet (params NSObject [] objs) : this (NSArray.FromNSObjects (objs)) { } - /// To be added. - /// To be added. - /// To be added. + /// Initializes a new mutable set with the specified strings. + /// The strings to add to the set. public NSMutableSet (params string [] strings) : this (NSArray.FromStrings (strings)) { @@ -57,10 +55,18 @@ internal NSMutableSet (params INativeObject [] objs) { } - public static NSMutableSet operator + (NSMutableSet first, NSMutableSet second) + /// Creates a new mutable set containing all objects from both sets. + /// The first set. + /// The second set. + /// A new containing the union of both sets, or if both sets are . + [return: NotNullIfNotNull (nameof (first))] + [return: NotNullIfNotNull (nameof (second))] + public static NSMutableSet? operator + (NSMutableSet? first, NSMutableSet? second) { + if (first is null && second is null) + return null; if (first is null || first.Count == 0) - return new NSMutableSet (second); + return second is null ? new NSMutableSet () : new NSMutableSet (second); if (second is null || second.Count == 0) return new NSMutableSet (first); @@ -69,10 +75,17 @@ internal NSMutableSet (params INativeObject [] objs) return copy; } - public static NSMutableSet operator - (NSMutableSet first, NSMutableSet second) + /// Creates a new mutable set with objects from the first set that are not in the second set. + /// The first set. + /// The second set. + /// A new containing the difference, or if the first set is . + [return: NotNullIfNotNull (nameof (first))] + public static NSMutableSet? operator - (NSMutableSet? first, NSMutableSet? second) { - if (first is null || first.Count == 0) + if (first is null) return null; + if (first.Count == 0) + return new NSMutableSet (); if (second is null || second.Count == 0) return new NSMutableSet (first); diff --git a/tests/cecil-tests/Documentation.KnownFailures.txt b/tests/cecil-tests/Documentation.KnownFailures.txt index c1f04160140c..a782df376c5f 100644 --- a/tests/cecil-tests/Documentation.KnownFailures.txt +++ b/tests/cecil-tests/Documentation.KnownFailures.txt @@ -11877,8 +11877,6 @@ M:Foundation.NSKeyValueSharedObservers.#ctor(System.Type) M:Foundation.NSMachPort.Dispose(System.Boolean) M:Foundation.NSMetadataQuery.Dispose(System.Boolean) M:Foundation.NSMutableDictionary`2.FromObjectsAndKeys(`1[],`0[]) -M:Foundation.NSMutableSet.op_Addition(Foundation.NSMutableSet,Foundation.NSMutableSet) -M:Foundation.NSMutableSet.op_Subtraction(Foundation.NSMutableSet,Foundation.NSMutableSet) M:Foundation.NSNetService.add_AddressResolved(System.EventHandler) M:Foundation.NSNetService.add_DidAcceptConnection(System.EventHandler{Foundation.NSNetServiceConnectionEventArgs}) M:Foundation.NSNetService.add_Published(System.EventHandler) diff --git a/tests/monotouch-test/Foundation/NSMutableSetTest.cs b/tests/monotouch-test/Foundation/NSMutableSetTest.cs index 40d06675b086..e3050be3138c 100644 --- a/tests/monotouch-test/Foundation/NSMutableSetTest.cs +++ b/tests/monotouch-test/Foundation/NSMutableSetTest.cs @@ -64,5 +64,227 @@ public void OperatorPlusReferenceTest () Assert.AreNotEqual (IntPtr.Zero, one.Handle, "Handle must be != IntPtr.Zero"); Assert.AreNotEqual (IntPtr.Zero, two.Handle, "Handle must be != IntPtr.Zero"); } + + [Test] + public void OperatorAdd_BothNull () + { + NSMutableSet first = null; + NSMutableSet second = null; + var result = first + second; + Assert.IsNull (result, "BothNull should return null"); + } + + [Test] + public void OperatorAdd_FirstNull_SecondNonEmpty () + { + NSMutableSet first = null; + using (var second = new NSMutableSet ("1", "2")) + using (var result = first + second) { + Assert.IsNotNull (result, "FirstNull should return new set"); + Assert.AreEqual ((nuint) 2, result.Count, "FirstNull Count"); + Assert.IsTrue (result.Contains ("1"), "FirstNull Contains 1"); + Assert.IsTrue (result.Contains ("2"), "FirstNull Contains 2"); + } + } + + [Test] + public void OperatorAdd_FirstNull_SecondEmpty () + { + NSMutableSet first = null; + using (var second = new NSMutableSet ()) + using (var result = first + second) { + Assert.IsNotNull (result, "FirstNull SecondEmpty should return new set"); + Assert.AreEqual ((nuint) 0, result.Count, "FirstNull SecondEmpty Count"); + } + } + + [Test] + public void OperatorAdd_FirstNonEmpty_SecondNull () + { + using (var first = new NSMutableSet ("1", "2")) + using (var result = first + null) { + Assert.IsNotNull (result, "SecondNull should return new set"); + Assert.AreEqual ((nuint) 2, result.Count, "SecondNull Count"); + Assert.IsTrue (result.Contains ("1"), "SecondNull Contains 1"); + Assert.IsTrue (result.Contains ("2"), "SecondNull Contains 2"); + } + } + + [Test] + public void OperatorAdd_FirstEmpty_SecondNull () + { + using (var first = new NSMutableSet ()) + using (var result = first + null) { + Assert.IsNotNull (result, "FirstEmpty SecondNull should return new set"); + Assert.AreEqual ((nuint) 0, result.Count, "FirstEmpty SecondNull Count"); + } + } + + [Test] + public void OperatorAdd_FirstEmpty_SecondNonEmpty () + { + using (var first = new NSMutableSet ()) + using (var second = new NSMutableSet ("1", "2")) + using (var result = first + second) { + Assert.IsNotNull (result, "FirstEmpty should return copy of second"); + Assert.AreEqual ((nuint) 2, result.Count, "FirstEmpty Count"); + Assert.IsTrue (result.Contains ("1"), "FirstEmpty Contains 1"); + Assert.IsTrue (result.Contains ("2"), "FirstEmpty Contains 2"); + } + } + + [Test] + public void OperatorAdd_FirstNonEmpty_SecondEmpty () + { + using (var first = new NSMutableSet ("1", "2")) + using (var second = new NSMutableSet ()) + using (var result = first + second) { + Assert.IsNotNull (result, "SecondEmpty should return copy of first"); + Assert.AreEqual ((nuint) 2, result.Count, "SecondEmpty Count"); + Assert.IsTrue (result.Contains ("1"), "SecondEmpty Contains 1"); + Assert.IsTrue (result.Contains ("2"), "SecondEmpty Contains 2"); + } + } + + [Test] + public void OperatorAdd_BothEmpty () + { + using (var first = new NSMutableSet ()) + using (var second = new NSMutableSet ()) + using (var result = first + second) { + Assert.IsNotNull (result, "BothEmpty should return new empty set"); + Assert.AreEqual ((nuint) 0, result.Count, "BothEmpty Count"); + } + } + + [Test] + public void OperatorAdd_WithOverlappingElements () + { + using (var first = new NSMutableSet ("1", "2", "3")) + using (var second = new NSMutableSet ("2", "3", "4")) + using (var result = first + second) { + Assert.IsNotNull (result, "Overlapping should return new set"); + Assert.AreEqual ((nuint) 4, result.Count, "Overlapping Count"); + Assert.IsTrue (result.Contains ("1"), "Overlapping Contains 1"); + Assert.IsTrue (result.Contains ("2"), "Overlapping Contains 2"); + Assert.IsTrue (result.Contains ("3"), "Overlapping Contains 3"); + Assert.IsTrue (result.Contains ("4"), "Overlapping Contains 4"); + } + } + + [Test] + public void OperatorSubtract_FirstNull () + { + NSMutableSet first = null; + using (var second = new NSMutableSet ("1", "2")) { + var result = first - second; + Assert.IsNull (result, "FirstNull should return null"); + } + } + + [Test] + public void OperatorSubtract_SecondNull () + { + using (var first = new NSMutableSet ("1", "2")) + using (var result = first - null) { + Assert.IsNotNull (result, "SecondNull should return copy of first"); + Assert.AreEqual ((nuint) 2, result.Count, "SecondNull Count"); + Assert.IsTrue (result.Contains ("1"), "SecondNull Contains 1"); + Assert.IsTrue (result.Contains ("2"), "SecondNull Contains 2"); + } + } + + [Test] + public void OperatorSubtract_BothNull () + { + NSMutableSet first = null; + NSMutableSet second = null; + var result = first - second; + Assert.IsNull (result, "BothNull should return null"); + } + + [Test] + public void OperatorSubtract_FirstEmpty () + { + using (var first = new NSMutableSet ()) + using (var second = new NSMutableSet ("1", "2")) + using (var result = first - second) { + Assert.IsNotNull (result, "FirstEmpty should return empty set"); + Assert.AreEqual ((nuint) 0, result.Count, "FirstEmpty Count"); + } + } + + [Test] + public void OperatorSubtract_SecondEmpty () + { + using (var first = new NSMutableSet ("1", "2")) + using (var second = new NSMutableSet ()) + using (var result = first - second) { + Assert.IsNotNull (result, "SecondEmpty should return copy of first"); + Assert.AreEqual ((nuint) 2, result.Count, "SecondEmpty Count"); + Assert.IsTrue (result.Contains ("1"), "SecondEmpty Contains 1"); + Assert.IsTrue (result.Contains ("2"), "SecondEmpty Contains 2"); + } + } + + [Test] + public void OperatorSubtract_BothEmpty () + { + using (var first = new NSMutableSet ()) + using (var second = new NSMutableSet ()) + using (var result = first - second) { + Assert.IsNotNull (result, "BothEmpty should return empty set"); + Assert.AreEqual ((nuint) 0, result.Count, "BothEmpty Count"); + } + } + + [Test] + public void OperatorSubtract_NoOverlap () + { + using (var first = new NSMutableSet ("1", "2")) + using (var second = new NSMutableSet ("3", "4")) + using (var result = first - second) { + Assert.IsNotNull (result, "NoOverlap should return copy of first"); + Assert.AreEqual ((nuint) 2, result.Count, "NoOverlap Count"); + Assert.IsTrue (result.Contains ("1"), "NoOverlap Contains 1"); + Assert.IsTrue (result.Contains ("2"), "NoOverlap Contains 2"); + } + } + + [Test] + public void OperatorSubtract_PartialOverlap () + { + using (var first = new NSMutableSet ("1", "2", "3")) + using (var second = new NSMutableSet ("2", "3", "4")) + using (var result = first - second) { + Assert.IsNotNull (result, "PartialOverlap should return difference"); + Assert.AreEqual ((nuint) 1, result.Count, "PartialOverlap Count"); + Assert.IsTrue (result.Contains ("1"), "PartialOverlap Contains 1"); + Assert.IsFalse (result.Contains ("2"), "PartialOverlap Not Contains 2"); + Assert.IsFalse (result.Contains ("3"), "PartialOverlap Not Contains 3"); + } + } + + [Test] + public void OperatorSubtract_CompleteOverlap () + { + using (var first = new NSMutableSet ("1", "2", "3")) + using (var second = new NSMutableSet ("1", "2", "3")) + using (var result = first - second) { + Assert.IsNotNull (result, "CompleteOverlap should return empty set"); + Assert.AreEqual ((nuint) 0, result.Count, "CompleteOverlap Count"); + } + } + + [Test] + public void OperatorSubtract_SecondIsSupersetOfFirst () + { + using (var first = new NSMutableSet ("1", "2")) + using (var second = new NSMutableSet ("1", "2", "3", "4")) + using (var result = first - second) { + Assert.IsNotNull (result, "Superset should return empty set"); + Assert.AreEqual ((nuint) 0, result.Count, "Superset Count"); + } + } } }