#region Apache License 2.0 /* Nuclex .NET Framework Copyright (C) 2002-2024 Markus Ewald / Nuclex Development Labs Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #endregion // Apache License 2.0 #if !NO_SETS #if UNITTEST using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using NUnit.Framework; using NMock; namespace Nuclex.Support.Collections { /// Unit Test for the observable set wrapper [TestFixture] internal class ObservableSetTest { #region interface IObservableCollectionSubscriber public interface IObservableCollectionSubscriber { /// Called when an item has been added to the collection void ItemAdded(object sender, ItemEventArgs arguments); /// Called when an item is removed from the collection void ItemRemoved(object sender, ItemEventArgs arguments); /// Called when an item is replaced in the collection void ItemReplaced(object sender, ItemReplaceEventArgs arguments); /// Called when the collection is about to be cleared void Clearing(object sender, EventArgs arguments); /// Called when the collection has been cleared void Cleared(object sender, EventArgs arguments); } #endregion // interface IObservableCollectionSubscriber /// Called before each test is run [SetUp] public void Setup() { this.mockFactory = new MockFactory(); this.observableSet = new ObservableSet(); this.subscriber = this.mockFactory.CreateMock>(); this.observableSet.ItemAdded += this.subscriber.MockObject.ItemAdded; this.observableSet.ItemRemoved += this.subscriber.MockObject.ItemRemoved; this.observableSet.ItemReplaced += this.subscriber.MockObject.ItemReplaced; this.observableSet.Clearing += this.subscriber.MockObject.Clearing; this.observableSet.Cleared += this.subscriber.MockObject.Cleared; } /// Called after each test has run [TearDown] public void Teardown() { if(this.mockFactory != null) { this.mockFactory.VerifyAllExpectationsHaveBeenMet(); this.subscriber = null; this.mockFactory.Dispose(); this.mockFactory = null; } } /// /// Verifies that the observable set has a default constructor /// [Test] public void HasDefaultConstructor() { Assert.IsNotNull(new ObservableSet()); } /// /// Verifies that adding items to the set triggers the 'ItemAdded' event /// [Test] public void AddingItemsTriggersEvent() { this.subscriber.Expects.One.Method((s) => s.ItemAdded(null, null)).WithAnyArguments(); this.observableSet.Add(123); } /// /// Verifies that removing items from the set triggers the 'ItemRemoved' event /// [Test] public void RemovingItemsTriggersEvent() { this.subscriber.Expects.One.Method((s) => s.ItemAdded(null, null)).WithAnyArguments(); this.observableSet.Add(123); this.subscriber.Expects.One.Method((s) => s.ItemRemoved(null, null)).WithAnyArguments(); this.observableSet.Remove(123); } /// /// Verifies that adding items to the set triggers the 'ItemAdded' event /// [Test] public void AddingAlreadyContainedItemDoesNotTriggerEvent() { this.subscriber.Expects.One.Method((s) => s.ItemAdded(null, null)).WithAnyArguments(); this.observableSet.Add(123); this.subscriber.Expects.No.Method((s) => s.ItemAdded(null, null)).WithAnyArguments(); this.observableSet.Add(123); } /// /// Verifies that excepting the set with itself empties the set /// [Test] public void ExceptWithSelfEmptiesSet() { this.subscriber.Expects.Exactly(3).Method( (s) => s.ItemAdded(null, null) ).WithAnyArguments(); this.observableSet.Add(1); this.observableSet.Add(2); this.observableSet.Add(3); Assert.AreEqual(3, this.observableSet.Count); this.subscriber.Expects.One.Method((s) => s.Clearing(null, null)).WithAnyArguments(); this.subscriber.Expects.One.Method((s) => s.Cleared(null, null)).WithAnyArguments(); this.observableSet.ExceptWith(this.observableSet); Assert.AreEqual(0, this.observableSet.Count); } /// /// Verifies that a set can be excepted with a collection /// [Test] public void SetCanBeExceptedWithCollection() { this.subscriber.Expects.Exactly(2).Method( (s) => s.ItemAdded(null, null) ).WithAnyArguments(); this.observableSet.Add(1); this.observableSet.Add(2); var collection = new List() { 1 }; this.subscriber.Expects.One.Method((s) => s.ItemRemoved(null, null)).WithAnyArguments(); this.observableSet.ExceptWith(collection); Assert.AreEqual(1, this.observableSet.Count); Assert.IsTrue(this.observableSet.Contains(2)); } /// /// Verifies that a set can be intersected with a collection /// [Test] public void SetCanBeIntersectedWithCollection() { this.subscriber.Expects.Exactly(2).Method( (s) => s.ItemAdded(null, null) ).WithAnyArguments(); this.observableSet.Add(1); this.observableSet.Add(2); var collection = new List() { 1 }; this.subscriber.Expects.One.Method((s) => s.ItemRemoved(null, null)).WithAnyArguments(); this.observableSet.IntersectWith(collection); Assert.AreEqual(1, this.observableSet.Count); Assert.IsTrue(this.observableSet.Contains(1)); } /// /// Verifies that it's possible to determine whether a set is a proper subset /// or superset of another set /// [Test] public void CanDetermineProperSubsetAndSuperset() { var set1 = new ObservableSet() { 1, 2, 3 }; var set2 = new HashSet() { 1, 3 }; Assert.IsTrue(set1.IsProperSupersetOf(set2)); Assert.IsTrue(set2.IsProperSubsetOf(set1)); set2.Add(2); Assert.IsFalse(set1.IsProperSupersetOf(set2)); Assert.IsFalse(set2.IsProperSubsetOf(set1)); } /// /// Verifies that it's possible to determine whether a set is a subset /// or a superset of another set /// [Test] public void CanDetermineSubsetAndSuperset() { var set1 = new ObservableSet() { 1, 2, 3 }; var set2 = new HashSet() { 1, 2, 3 }; Assert.IsTrue(set1.IsSupersetOf(set2)); Assert.IsTrue(set2.IsSubsetOf(set1)); set2.Add(4); Assert.IsFalse(set1.IsSupersetOf(set2)); Assert.IsFalse(set2.IsSubsetOf(set1)); } /// /// Verifies that a set can determine if another set overlaps with it /// [Test] public void CanDetermineOverlap() { var set1 = new ObservableSet() { 1, 3, 5 }; var set2 = new HashSet() { 3 }; Assert.IsTrue(set1.Overlaps(set2)); Assert.IsTrue(set2.Overlaps(set1)); } /// /// Verifies that a set can determine if another set contains the same elements /// [Test] public void CanDetermineSetEquality() { var set1 = new ObservableSet() { 1, 3, 5 }; var set2 = new HashSet() { 3, 1, 5 }; Assert.IsTrue(set1.SetEquals(set2)); Assert.IsTrue(set2.SetEquals(set1)); set1.Add(7); Assert.IsFalse(set1.SetEquals(set2)); Assert.IsFalse(set2.SetEquals(set1)); } /// /// Verifies that a set can be symmetrically excepted with another set /// [Test] public void CanBeSymmetricallyExcepted() { var set1 = new ObservableSet() { 1, 2, 3 }; var set2 = new HashSet() { 3, 4, 5 }; set1.SymmetricExceptWith(set2); Assert.AreEqual(4, set1.Count); } /// /// Verifies that a union of two sets can be built /// [Test] public void CanBeUnioned() { this.subscriber.Expects.Exactly(3).Method( (s) => s.ItemAdded(null, null) ).WithAnyArguments(); this.observableSet.Add(1); this.observableSet.Add(2); this.observableSet.Add(3); var set2 = new ObservableSet() { 3, 4, 5 }; this.subscriber.Expects.Exactly(2).Method( (s) => s.ItemAdded(null, null) ).WithAnyArguments(); this.observableSet.UnionWith(set2); Assert.AreEqual(5, this.observableSet.Count); } /// Creates mock object for the test private MockFactory mockFactory; /// Observable set being tested private ObservableSet observableSet; /// Subscriber for the observable set's events private Mock> subscriber; } } // namespace Nuclex.Support.Collections #endif // UNITTEST #endif // !NO_SETS