#region CPL License /* Nuclex Framework Copyright (C) 2002-2017 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #endregion #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