#region CPL License /* Nuclex Framework Copyright (C) 2002-2013 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 using System; using System.Collections; using System.Collections.Generic; #if UNITTEST using NUnit.Framework; namespace Nuclex.Support.Collections { /// Unit Test for the weak collection wrapper [TestFixture] internal class WeakCollectionTest { #region class Dummy /// Dummy class used to test the weakly referencing collection private class Dummy { /// Initializes a new dummy /// Value that will be stored by the dummy public Dummy(int value) { this.Value = value; } /// /// Determines whether the specified System.Object is equal to /// the current Dummy object. /// /// /// The System.Object to compare with the current Dummy object /// /// /// True if the specified System.Object is equal to the current Dummy object; /// otherwise, false. /// public override bool Equals(object otherAsObject) { Dummy other = otherAsObject as Dummy; if(other == null) { return false; } return this.Value.Equals(other.Value); } /// Serves as a hash function for a particular type. /// A hash code for the current System.Object. public override int GetHashCode() { return this.Value.GetHashCode(); } /// Some value that can be used for testing public int Value; } #endregion // class Dummy #region class ListWithoutICollection private class ListWithoutICollection : IList> { public int IndexOf(WeakReference item) { throw new NotImplementedException(); } public void Insert(int index, WeakReference item) { throw new NotImplementedException(); } public void RemoveAt(int index) { throw new NotImplementedException(); } public WeakReference this[int index] { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } public void Add(WeakReference item) { throw new NotImplementedException(); } public void Clear() { throw new NotImplementedException(); } public bool Contains(WeakReference item) { throw new NotImplementedException(); } public void CopyTo(WeakReference[] array, int arrayIndex) { throw new NotImplementedException(); } public int Count { get { return 12345; } } public bool IsReadOnly { get { throw new NotImplementedException(); } } public bool Remove(WeakReference item) { throw new NotImplementedException(); } public IEnumerator> GetEnumerator() { throw new NotImplementedException(); } IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); } } #endregion // class ListWithoutICollection /// Verifies that the constructor of the weak collection is working [Test] public void TestConstructor() { WeakCollection dummies = new WeakCollection( new List>() ); Assert.IsNotNull(dummies); } /// /// Test whether the non-typesafe Add() method of the weak collection works /// [Test] public void TestAddAsObject() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(12345); (dummies as IList).Add((object)oneTwoThreeDummy); CollectionAssert.Contains(dummies, oneTwoThreeDummy); } /// /// Test whether the non-typesafe Add() method throws an exception if an object is /// added that is not compatible to the collection's item type /// [Test] public void TestThrowOnAddIncompatibleObject() { WeakCollection dummies = new WeakCollection( new List>() ); Assert.Throws( delegate() { (dummies as IList).Add(new object()); } ); } /// /// Test whether the generic Add() method of the weak collection works /// [Test] public void TestAdd() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(12345); dummies.Add(oneTwoThreeDummy); CollectionAssert.Contains(dummies, oneTwoThreeDummy); } /// Tests whether the Clear() method works [Test] public void TestClear() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(12345); dummies.Add(oneTwoThreeDummy); Dummy threeTwoOneDummy = new Dummy(54321); dummies.Add(threeTwoOneDummy); Assert.AreEqual(2, dummies.Count); dummies.Clear(); Assert.AreEqual(0, dummies.Count); } /// Tests whether the Contains() method works [Test] public void TestContains() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(12345); dummies.Add(oneTwoThreeDummy); Dummy threeTwoOneDummy = new Dummy(54321); Assert.IsTrue(dummies.Contains(oneTwoThreeDummy)); Assert.IsFalse(dummies.Contains(threeTwoOneDummy)); } /// Tests whether the non-typesafe Contains() method works [Test] public void TestContainsWithObject() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(12345); dummies.Add(oneTwoThreeDummy); Dummy threeTwoOneDummy = new Dummy(54321); Assert.IsTrue((dummies as IList).Contains((object)oneTwoThreeDummy)); Assert.IsFalse((dummies as IList).Contains((object)threeTwoOneDummy)); } /// /// Verifies that the Enumerator of the dummy collection correctly /// implements the Reset() method /// [Test] public void TestEnumeratorReset() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(123); dummies.Add(oneTwoThreeDummy); Dummy fourFiveSixDummy = new Dummy(456); dummies.Add(fourFiveSixDummy); IEnumerator dummyEnumerator = dummies.GetEnumerator(); Assert.IsTrue(dummyEnumerator.MoveNext()); Assert.IsTrue(dummyEnumerator.MoveNext()); Assert.IsFalse(dummyEnumerator.MoveNext()); dummyEnumerator.Reset(); Assert.IsTrue(dummyEnumerator.MoveNext()); Assert.IsTrue(dummyEnumerator.MoveNext()); Assert.IsFalse(dummyEnumerator.MoveNext()); } /// Verifies that the IndexOf() method is working as intended [Test] public void TestIndexOf() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(123); dummies.Add(oneTwoThreeDummy); Dummy fourFiveSixDummy = new Dummy(456); dummies.Add(fourFiveSixDummy); Dummy sevenEightNineDummy = new Dummy(789); Assert.AreEqual(0, dummies.IndexOf(oneTwoThreeDummy)); Assert.AreEqual(1, dummies.IndexOf(fourFiveSixDummy)); Assert.AreEqual(-1, dummies.IndexOf(sevenEightNineDummy)); } /// /// Verifies that the non-typesafe IndexOf() method is working as intended /// [Test] public void TestIndexOfWithObject() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(123); dummies.Add(oneTwoThreeDummy); Dummy fourFiveSixDummy = new Dummy(456); dummies.Add(fourFiveSixDummy); Dummy sevenEightNineDummy = new Dummy(789); Assert.AreEqual(0, (dummies as IList).IndexOf((object)oneTwoThreeDummy)); Assert.AreEqual(1, (dummies as IList).IndexOf((object)fourFiveSixDummy)); Assert.AreEqual(-1, (dummies as IList).IndexOf((object)sevenEightNineDummy)); } /// /// Verifies that an exception is thrown if an incompatible object is passed to /// the non-typesafe variant of the IndexOf() method /// [Test] public void TestThrowOnIndexOfWithIncompatibleObject() { WeakCollection dummies = new WeakCollection( new List>() ); Assert.Throws( delegate() { Assert.IsNull((dummies as IList).IndexOf(new object())); } ); } /// Test whether the IndexOf() method can cope with null references [Test] public void TestIndexOfNull() { WeakCollection dummies = new WeakCollection( new List>() ); Assert.AreEqual(-1, dummies.IndexOf(null)); dummies.Add(null); Assert.AreEqual(0, dummies.IndexOf(null)); } /// /// Verifies that the CopyTo() method of the weak collection works /// [Test] public void TestCopyToArray() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(123); dummies.Add(oneTwoThreeDummy); Dummy fourFiveSixDummy = new Dummy(456); dummies.Add(fourFiveSixDummy); Dummy[] inputDummies = new Dummy[] { oneTwoThreeDummy, fourFiveSixDummy }; Dummy[] outputDummies = new Dummy[dummies.Count]; dummies.CopyTo(outputDummies, 0); CollectionAssert.AreEqual(inputDummies, outputDummies); } /// /// Verifies that the CopyTo() method of the weak collection throws an exception /// if the target array is too small to hold the collection's contents /// [Test] public void TestThrowOnCopyToTooSmallArray() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(123); dummies.Add(oneTwoThreeDummy); Dummy fourFiveSixDummy = new Dummy(456); dummies.Add(fourFiveSixDummy); Dummy[] outputStrings = new Dummy[dummies.Count - 1]; Assert.Throws( delegate() { dummies.CopyTo(outputStrings, 0); } ); } /// /// Verifies that the CopyTo() method of the transforming read only collection /// works if invoked via the ICollection interface /// [Test] public void TestCopyToArrayViaICollection() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(123); dummies.Add(oneTwoThreeDummy); Dummy fourFiveSixDummy = new Dummy(456); dummies.Add(fourFiveSixDummy); Dummy[] inputDummies = new Dummy[] { oneTwoThreeDummy, fourFiveSixDummy }; Dummy[] outputDummies = new Dummy[dummies.Count]; (dummies as ICollection).CopyTo(outputDummies, 0); CollectionAssert.AreEqual(inputDummies, outputDummies); } /// /// Verifies that the Insert() method correctly shifts items in the collection /// [Test] public void TestInsert() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(123); dummies.Add(oneTwoThreeDummy); Dummy fourFiveSixDummy = new Dummy(456); dummies.Insert(0, fourFiveSixDummy); Assert.AreEqual(2, dummies.Count); Assert.AreSame(fourFiveSixDummy, dummies[0]); Assert.AreSame(oneTwoThreeDummy, dummies[1]); } /// /// Verifies that the non-typesafe Insert() method correctly shifts items in /// the collection /// [Test] public void TestInsertObject() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(123); dummies.Add(oneTwoThreeDummy); Dummy fourFiveSixDummy = new Dummy(456); (dummies as IList).Insert(0, (object)fourFiveSixDummy); Assert.AreEqual(2, dummies.Count); Assert.AreSame(fourFiveSixDummy, dummies[0]); Assert.AreSame(oneTwoThreeDummy, dummies[1]); } /// /// Verifies that the non-typesafe Insert() method correctly shifts items in /// the collection /// [Test] public void TestThrowOnInsertIncompatibleObject() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(123); dummies.Add(oneTwoThreeDummy); Assert.Throws( delegate() { (dummies as IList).Insert(0, new object()); } ); } /// /// Checks whether the IsFixedSize property of the weak collection returns /// the expected result for a weak collection based on a fixed array /// [Test] public void TestIsFixedSizeViaIList() { Dummy oneTwoThreeDummy = new Dummy(123); Dummy fourFiveSixDummy = new Dummy(456); WeakReference[] dummyReferences = new WeakReference[] { new WeakReference(oneTwoThreeDummy), new WeakReference(fourFiveSixDummy) }; WeakCollection dummies = new WeakCollection(dummyReferences); Assert.IsTrue((dummies as IList).IsFixedSize); } /// /// Tests whether the IsReadOnly property of the weak collection works /// [Test] public void TestIsReadOnly() { Dummy oneTwoThreeDummy = new Dummy(123); Dummy fourFiveSixDummy = new Dummy(456); List> dummyReferences = new List>(); dummyReferences.Add(new WeakReference(oneTwoThreeDummy)); dummyReferences.Add(new WeakReference(fourFiveSixDummy)); ReadOnlyList> readOnlyDummyReferences = new ReadOnlyList>(dummyReferences); WeakCollection dummies = new WeakCollection(dummyReferences); WeakCollection readOnlydummies = new WeakCollection( readOnlyDummyReferences ); Assert.IsFalse(dummies.IsReadOnly); Assert.IsTrue(readOnlydummies.IsReadOnly); } /// /// Tests whether the IsSynchronized property of the weak collection works /// [Test] public void TestIsSynchronized() { WeakCollection dummies = new WeakCollection( new List>() ); Assert.IsFalse((dummies as IList).IsSynchronized); } /// Tests the indexer of the weak collection [Test] public void TestIndexer() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(123); dummies.Add(oneTwoThreeDummy); Dummy fourFiveSixDummy = new Dummy(456); dummies.Add(fourFiveSixDummy); Assert.AreSame(oneTwoThreeDummy, dummies[0]); Assert.AreSame(fourFiveSixDummy, dummies[1]); dummies[0] = fourFiveSixDummy; Assert.AreSame(fourFiveSixDummy, dummies[0]); } /// Tests the non-typesafe indexer of the weak collection [Test] public void TestIndexerWithObject() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(123); dummies.Add(oneTwoThreeDummy); Dummy fourFiveSixDummy = new Dummy(456); dummies.Add(fourFiveSixDummy); Assert.AreSame((object)oneTwoThreeDummy, (dummies as IList)[0]); Assert.AreSame((object)fourFiveSixDummy, (dummies as IList)[1]); (dummies as IList)[0] = (object)fourFiveSixDummy; Assert.AreSame((object)fourFiveSixDummy, (dummies as IList)[0]); } /// /// Tests whether the non-typesafe indexer of the weak collection throws /// the correct exception if an incompatible object is assigned /// [Test] public void TestThrowOnIndexerWithIncompatibleObject() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(123); dummies.Add(oneTwoThreeDummy); Assert.Throws( delegate() { (dummies as IList)[0] = new object(); } ); } /// Tests the Remove() method of the weak collection [Test] public void TestRemove() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(123); dummies.Add(oneTwoThreeDummy); Dummy fourFiveSixDummy = new Dummy(456); dummies.Add(fourFiveSixDummy); Assert.AreEqual(2, dummies.Count); Assert.IsTrue(dummies.Remove(oneTwoThreeDummy)); Assert.AreEqual(1, dummies.Count); Assert.IsFalse(dummies.Remove(oneTwoThreeDummy)); } /// Tests the non-typesafe Remove() method of the weak collection [Test] public void TestRemoveObject() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(123); dummies.Add(oneTwoThreeDummy); Dummy fourFiveSixDummy = new Dummy(456); dummies.Add(fourFiveSixDummy); Assert.AreEqual(2, dummies.Count); (dummies as IList).Remove((object)oneTwoThreeDummy); Assert.AreEqual(1, dummies.Count); } /// /// Tests whether a null object can be managed by and removed from the weak collection /// [Test] public void TestRemoveNull() { WeakCollection dummies = new WeakCollection( new List>() ); dummies.Add(null); Assert.AreEqual(1, dummies.Count); Assert.IsTrue(dummies.Remove(null)); Assert.AreEqual(0, dummies.Count); } /// /// Tests whether the non-typesafe Remove() method of the weak collection throws /// an exception if an object is tried to be removed that is incompatible with /// the collection's item type /// [Test] public void TestThrowOnRemoveIncompatibleObject() { WeakCollection dummies = new WeakCollection( new List>() ); Assert.Throws( delegate() { (dummies as IList).Remove(new object()); } ); } /// Tests the RemoveAt() method of the weak collection [Test] public void TestRemoveAt() { WeakCollection dummies = new WeakCollection( new List>() ); Dummy oneTwoThreeDummy = new Dummy(123); dummies.Add(oneTwoThreeDummy); Dummy fourFiveSixDummy = new Dummy(456); dummies.Add(fourFiveSixDummy); Assert.AreSame(oneTwoThreeDummy, dummies[0]); dummies.RemoveAt(0); Assert.AreSame(fourFiveSixDummy, dummies[0]); } /// /// Verifies that the IsSynchronized property and the SyncRoot property are working /// [Test] public void TestSynchronization() { WeakCollection dummies = new WeakCollection( new List>() ); if(!(dummies as ICollection).IsSynchronized) { lock((dummies as ICollection).SyncRoot) { Assert.AreEqual(0, dummies.Count); } } } /// /// Verifies that the IsSynchronized property and the SyncRoot property are working /// on transforming read only collections based on IList<>s that do not /// implement the ICollection interface /// [Test] public void TestSynchronizationOfIListWithoutICollection() { WeakCollection dummies = new WeakCollection( new ListWithoutICollection() ); if(!(dummies as ICollection).IsSynchronized) { lock((dummies as ICollection).SyncRoot) { int count = dummies.Count; Assert.AreEqual(12345, count); // ;-) } } } /// Tests the RemoveDeadItems() method [Test] public void TestRemoveDeadItems() { List> dummyReferences = new List>(); Dummy oneTwoThreeDummy = new Dummy(123); dummyReferences.Add(new WeakReference(oneTwoThreeDummy)); dummyReferences.Add(new WeakReference(null)); Dummy fourFiveSixDummy = new Dummy(456); dummyReferences.Add(new WeakReference(fourFiveSixDummy)); WeakCollection dummies = new WeakCollection(dummyReferences); Assert.AreEqual(3, dummies.Count); dummies.RemoveDeadItems(); Assert.AreEqual(2, dummies.Count); Assert.AreSame(oneTwoThreeDummy, dummies[0]); Assert.AreSame(fourFiveSixDummy, dummies[1]); } } } // namespace Nuclex.Support.Collections #endif // UNITTEST