Achieved 100% test coverage for the TransformingReadOnlyCollection and ReadOnlyList classes

git-svn-id: file:///srv/devel/repo-conversion/nusu@97 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
Markus Ewald 2008-11-27 19:40:43 +00:00
parent 195ba1df30
commit 5c90646327
7 changed files with 886 additions and 94 deletions

View File

@ -80,7 +80,13 @@
<DependentUpon>ReadOnlyCollection.cs</DependentUpon> <DependentUpon>ReadOnlyCollection.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Source\Collections\ReadOnlyDictionary.cs" /> <Compile Include="Source\Collections\ReadOnlyDictionary.cs" />
<Compile Include="Source\Collections\ReadOnlyDictionary.Test.cs">
<DependentUpon>ReadOnlyDictionary.cs</DependentUpon>
</Compile>
<Compile Include="Source\Collections\ReadOnlyList.cs" /> <Compile Include="Source\Collections\ReadOnlyList.cs" />
<Compile Include="Source\Collections\ReadOnlyList.Test.cs">
<DependentUpon>ReadOnlyList.cs</DependentUpon>
</Compile>
<Compile Include="Source\Collections\ReverseComparer.cs" /> <Compile Include="Source\Collections\ReverseComparer.cs" />
<Compile Include="Source\Collections\ReverseComparer.Test.cs"> <Compile Include="Source\Collections\ReverseComparer.Test.cs">
<DependentUpon>ReverseComparer.cs</DependentUpon> <DependentUpon>ReverseComparer.cs</DependentUpon>
@ -93,6 +99,9 @@
<Compile Include="Source\Collections\TransformingReadOnlyCollection.Interfaces.cs"> <Compile Include="Source\Collections\TransformingReadOnlyCollection.Interfaces.cs">
<DependentUpon>TransformingReadOnlyCollection.cs</DependentUpon> <DependentUpon>TransformingReadOnlyCollection.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Source\Collections\TransformingReadOnlyCollection.Test.cs">
<DependentUpon>TransformingReadOnlyCollection.cs</DependentUpon>
</Compile>
<Compile Include="Source\FloatHelper.cs" /> <Compile Include="Source\FloatHelper.cs" />
<Compile Include="Source\FloatHelper.Test.cs"> <Compile Include="Source\FloatHelper.Test.cs">
<DependentUpon>FloatHelper.cs</DependentUpon> <DependentUpon>FloatHelper.cs</DependentUpon>

View File

@ -0,0 +1,39 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2008 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 {
/// <summary>Unit Test for the read only dictionary wrapper</summary>
[TestFixture]
public class ReadOnlyDictionaryTest {
}
} // namespace Nuclex.Support.Collections
#endif // UNITTEST

View File

@ -0,0 +1,357 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2008 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 {
/// <summary>Unit Test for the read only list wrapper</summary>
[TestFixture]
public class ReadOnlyListTest {
/// <summary>
/// Verifies that the copy constructor of the read only list works
/// </summary>
[Test]
public void TestCopyConstructor() {
int[] integers = new int[] { 12, 34, 56, 78 };
ReadOnlyList<int> testList = new ReadOnlyList<int>(integers);
CollectionAssert.AreEqual(integers, testList);
}
/// <summary>Verifies that the IsReadOnly property returns true</summary>
[Test]
public void TestIsReadOnly() {
ReadOnlyList<int> testList = new ReadOnlyList<int>(new int[0]);
Assert.IsTrue(testList.IsReadOnly);
}
/// <summary>
/// Verifies that the CopyTo() of the read only list works
/// </summary>
[Test]
public void TestCopyToArray() {
int[] inputIntegers = new int[] { 12, 34, 56, 78 };
ReadOnlyList<int> testList = new ReadOnlyList<int>(inputIntegers);
int[] outputIntegers = new int[testList.Count];
testList.CopyTo(outputIntegers, 0);
CollectionAssert.AreEqual(inputIntegers, outputIntegers);
}
/// <summary>
/// Checks whether the Contains() method of the read only list is able to
/// determine if the list contains an item
/// </summary>
[Test]
public void TestContains() {
int[] integers = new int[] { 1234, 6789 };
ReadOnlyList<int> testList = new ReadOnlyList<int>(integers);
Assert.IsTrue(testList.Contains(1234));
Assert.IsFalse(testList.Contains(4321));
}
/// <summary>
/// Checks whether the IndexOf() method of the read only list is able to
/// determine if the index of an item in the list
/// </summary>
[Test]
public void TestIndexOf() {
int[] integers = new int[] { 12, 34, 67, 89 };
ReadOnlyList<int> testList = new ReadOnlyList<int>(integers);
Assert.AreEqual(0, testList.IndexOf(12));
Assert.AreEqual(1, testList.IndexOf(34));
Assert.AreEqual(2, testList.IndexOf(67));
Assert.AreEqual(3, testList.IndexOf(89));
}
/// <summary>
/// Checks whether the indexer method of the read only list is able to
/// retrieve items from the list
/// </summary>
[Test]
public void TestRetrieveByIndexer() {
int[] integers = new int[] { 12, 34, 67, 89 };
ReadOnlyList<int> testList = new ReadOnlyList<int>(integers);
Assert.AreEqual(12, testList[0]);
Assert.AreEqual(34, testList[1]);
Assert.AreEqual(67, testList[2]);
Assert.AreEqual(89, testList[3]);
}
/// <summary>
/// Checks whether the read only list will throw an exception if its Insert() method
/// is called via the generic IList&lt;&gt; interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnInsertViaGenericIList() {
ReadOnlyList<int> testList = new ReadOnlyList<int>(new int[0]);
(testList as IList<int>).Insert(0, 12345);
}
/// <summary>
/// Checks whether the read only list will throw an exception if its RemoveAt() method
/// is called via the generic IList&lt;&gt; interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnRemoveViaGenericIList() {
ReadOnlyList<int> testList = new ReadOnlyList<int>(new int[1]);
(testList as IList<int>).RemoveAt(0);
}
/// <summary>
/// Checks whether the indexer method of the read only list will throw an exception
/// if it is attempted to be used for replacing an item
/// </summary>
[Test]
public void TestRetrieveByIndexerViaGenericIList() {
int[] integers = new int[] { 12, 34, 67, 89 };
ReadOnlyList<int> testList = new ReadOnlyList<int>(integers);
Assert.AreEqual(12, (testList as IList<int>)[0]);
Assert.AreEqual(34, (testList as IList<int>)[1]);
Assert.AreEqual(67, (testList as IList<int>)[2]);
Assert.AreEqual(89, (testList as IList<int>)[3]);
}
/// <summary>
/// Checks whether the indexer method of the read only list will throw an exception
/// if it is attempted to be used for replacing an item
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnReplaceByIndexerViaGenericIList() {
ReadOnlyList<int> testList = new ReadOnlyList<int>(new int[1]);
(testList as IList<int>)[0] = 12345;
}
/// <summary>
/// Checks whether the read only list will throw an exception if its Add() method
/// is called via the generic ICollection&lt;&gt; interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnAddViaGenericICollection() {
ReadOnlyList<int> testList = new ReadOnlyList<int>(new int[0]);
(testList as ICollection<int>).Add(12345);
}
/// <summary>
/// Checks whether the read only list will throw an exception if its Clear() method
/// is called via the generic ICollection&lt;&gt; interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnClearViaGenericICollection() {
ReadOnlyList<int> testList = new ReadOnlyList<int>(new int[1]);
(testList as ICollection<int>).Clear();
}
/// <summary>
/// Checks whether the read only list will throw an exception if its Remove() method
/// is called via the generic ICollection&lt;&gt; interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnRemoveViaGenericICollection() {
int[] integers = new int[] { 12, 34, 67, 89 };
ReadOnlyList<int> testList = new ReadOnlyList<int>(integers);
(testList as ICollection<int>).Remove(89);
}
/// <summary>
/// Tests whether the typesafe enumerator of the read only collection is working
/// </summary>
[Test]
public void TestTypesafeEnumerator() {
int[] inputIntegers = new int[] { 12, 34, 56, 78 };
ReadOnlyList<int> testList = new ReadOnlyList<int>(inputIntegers);
List<int> outputIntegers = new List<int>();
foreach(int value in testList) {
outputIntegers.Add(value);
}
CollectionAssert.AreEqual(inputIntegers, outputIntegers);
}
/// <summary>
/// Checks whether the read only list will throw an exception if its Clear() method
/// is called via the IList interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnClearViaIList() {
ReadOnlyList<int> testList = new ReadOnlyList<int>(new int[1]);
(testList as IList).Clear();
}
/// <summary>
/// Checks whether the read only list will throw an exception if its Add() method
/// is called via the IList interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnAddViaIList() {
ReadOnlyList<int> testList = new ReadOnlyList<int>(new int[0]);
(testList as IList).Add(12345);
}
/// <summary>
/// Checks whether the Contains() method of the read only list is able to
/// determine if the list contains an item
/// </summary>
[Test]
public void TestContainsViaIList() {
int[] integers = new int[] { 1234, 6789 };
ReadOnlyList<int> testList = new ReadOnlyList<int>(integers);
Assert.IsTrue((testList as IList).Contains(1234));
Assert.IsFalse((testList as IList).Contains(4321));
}
/// <summary>
/// Checks whether the IndexOf() method of the read only list is able to
/// determine if the index of an item in the list
/// </summary>
[Test]
public void TestIndexOfViaIList() {
int[] integers = new int[] { 12, 34, 67, 89 };
ReadOnlyList<int> testList = new ReadOnlyList<int>(integers);
Assert.AreEqual(0, (testList as IList).IndexOf(12));
Assert.AreEqual(1, (testList as IList).IndexOf(34));
Assert.AreEqual(2, (testList as IList).IndexOf(67));
Assert.AreEqual(3, (testList as IList).IndexOf(89));
}
/// <summary>
/// Checks whether the read only list will throw an exception if its Insert() method
/// is called via the IList interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnInsertViaIList() {
ReadOnlyList<int> testList = new ReadOnlyList<int>(new int[0]);
(testList as IList).Insert(0, 12345);
}
/// <summary>
/// Checks whether the IsFixedSize property of the read only list returns the
/// expected result for a read only list based on a fixed array
/// </summary>
[Test]
public void TestIsFixedSizeViaIList() {
int[] integers = new int[] { 12, 34, 67, 89 };
ReadOnlyList<int> testList = new ReadOnlyList<int>(integers);
Assert.IsTrue((testList as IList).IsFixedSize);
}
/// <summary>
/// Checks whether the read only list will throw an exception if its Remove() method
/// is called via the IList interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnRemoveViaIList() {
int[] integers = new int[] { 1234, 6789 };
ReadOnlyList<int> testList = new ReadOnlyList<int>(integers);
(testList as IList).Remove(6789);
}
/// <summary>
/// Checks whether the read only list will throw an exception if its Remove() method
/// is called via the IList interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnRemoveAtViaIList() {
ReadOnlyList<int> testList = new ReadOnlyList<int>(new int[1]);
(testList as IList).RemoveAt(0);
}
/// <summary>
/// Checks whether the indexer method of the read only list will throw an exception
/// if it is attempted to be used for replacing an item
/// </summary>
[Test]
public void TestRetrieveByIndexerViaIList() {
int[] integers = new int[] { 12, 34, 67, 89 };
ReadOnlyList<int> testList = new ReadOnlyList<int>(integers);
Assert.AreEqual(12, (testList as IList)[0]);
Assert.AreEqual(34, (testList as IList)[1]);
Assert.AreEqual(67, (testList as IList)[2]);
Assert.AreEqual(89, (testList as IList)[3]);
}
/// <summary>
/// Checks whether the indexer method of the read only list will throw an exception
/// if it is attempted to be used for replacing an item
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnReplaceByIndexerViaIList() {
ReadOnlyList<int> testList = new ReadOnlyList<int>(new int[1]);
(testList as IList)[0] = 12345;
}
/// <summary>
/// Verifies that the CopyTo() of the read only list works if invoked via
/// the ICollection interface
/// </summary>
[Test]
public void TestCopyToArrayViaICollection() {
int[] inputIntegers = new int[] { 12, 34, 56, 78 };
ReadOnlyList<int> testList = new ReadOnlyList<int>(inputIntegers);
int[] outputIntegers = new int[testList.Count];
(testList as ICollection).CopyTo(outputIntegers, 0);
CollectionAssert.AreEqual(inputIntegers, outputIntegers);
}
/// <summary>
/// Verifies that the IsSynchronized property and the SyncRoot property are working
/// </summary>
[Test]
public void TestSynchronization() {
ReadOnlyList<int> testList = new ReadOnlyList<int>(new int[0]);
if(!(testList as ICollection).IsSynchronized) {
lock((testList as ICollection).SyncRoot) {
int count = testList.Count;
}
}
}
}
} // namespace Nuclex.Support.Collections
#endif // UNITTEST

View File

@ -194,7 +194,7 @@ namespace Nuclex.Support.Collections {
/// <summary>Whether the size of the List is fixed</summary> /// <summary>Whether the size of the List is fixed</summary>
bool IList.IsFixedSize { bool IList.IsFixedSize {
get { throw new NotImplementedException(); } get { return this.objectList.IsFixedSize; }
} }
/// <summary>Removes the specified item from the List</summary> /// <summary>Removes the specified item from the List</summary>

View File

@ -35,19 +35,6 @@ namespace Nuclex.Support.Collections {
#region IList<ExposedItemType> Members #region IList<ExposedItemType> Members
/// <summary>
/// Determines the index of a specific item in the TransformingReadOnlyCollection.
/// </summary>
/// <param name="item">
/// The object to locate in the TransformingReadOnlyCollection.
/// </param>
/// <returns>
/// The index of item if found in the list; otherwise, -1.
/// </returns>
int IList<ExposedItemType>.IndexOf(ExposedItemType item) {
return IndexOf(item);
}
/// <summary> /// <summary>
/// Inserts an item to the TransformingReadOnlyCollection at the specified index. /// Inserts an item to the TransformingReadOnlyCollection at the specified index.
/// </summary> /// </summary>
@ -120,48 +107,6 @@ namespace Nuclex.Support.Collections {
throw new NotSupportedException("The collection is ready-only"); throw new NotSupportedException("The collection is ready-only");
} }
/// <summary>
/// Determines whether the TransformingReadOnlyCollection contains a specific value.
/// </summary>
/// <param name="item">
/// The object to locate in the TransformingReadOnlyCollection.
/// </param>
/// <returns>
/// True if item is found in the TransformingReadOnlyCollection; otherwise, false.
/// </returns>
bool ICollection<ExposedItemType>.Contains(ExposedItemType item) {
return Contains(item);
}
/// <summary>
/// Copies the elements of the TransformingReadOnlyCollection to an System.Array,
/// starting at a particular System.Array index.
/// </summary>
/// <param name="array">
/// The one-dimensional System.Array that is the destination of the elements
/// copied from TransformingReadOnlyCollection. The System.Array must have
/// zero-based indexing.
/// </param>
/// <param name="arrayIndex">
/// The zero-based index in array at which copying begins
/// </param>
/// <exception cref="System.ArgumentOutOfRangeException">
/// ArrayIndex is less than 0.
/// </exception>
/// <exception cref="System.ArgumentNullException">
/// Array is null.
/// </exception>
/// <exception cref="System.ArgumentException">
/// Array is multidimensional or arrayIndex is equal to or greater than the
/// length of array or the number of elements in the source
/// TransformingReadOnlyCollection is greater than the available
/// space from arrayIndex to the end of the destination array or type T cannot
/// be cast automatically to the type of the destination array.
/// </exception>
void ICollection<ExposedItemType>.CopyTo(ExposedItemType[] array, int arrayIndex) {
CopyTo(array, arrayIndex);
}
/// <summary> /// <summary>
/// Removes the first occurrence of a specific object from the /// Removes the first occurrence of a specific object from the
/// TransformingReadOnlyCollection. /// TransformingReadOnlyCollection.
@ -181,33 +126,6 @@ namespace Nuclex.Support.Collections {
throw new NotSupportedException("The collection is ready-only"); throw new NotSupportedException("The collection is ready-only");
} }
/// <summary>
/// The number of elements contained in the TransformingReadOnlyCollection.
/// </summary>
int ICollection<ExposedItemType>.Count {
get { return Count; }
}
/// <summary>
/// A value indicating whether the TransformingReadOnlyCollection is read-only.
/// </summary>
bool ICollection<ExposedItemType>.IsReadOnly {
get { return true; }
}
#endregion
#region IEnumerable<ExposedItemType> Members
/// <summary>Returns an enumerator that iterates through the collection.</summary>
/// <returns>
/// A System.Collections.Generic.IEnumerator&lt;ExposedItemType&gt; that can be used
/// to iterate through the collection.
/// </returns>
IEnumerator<ExposedItemType> IEnumerable<ExposedItemType>.GetEnumerator() {
return GetEnumerator();
}
#endregion #endregion
#region IEnumerable Members #region IEnumerable Members
@ -304,13 +222,6 @@ namespace Nuclex.Support.Collections {
get { return true; } get { return true; }
} }
/// <summary>
/// A value indicating whether the index is not a valid index in the is read-only.
/// </summary>
bool IList.IsReadOnly {
get { return true; }
}
/// <summary> /// <summary>
/// Removes the first occurrence of a specific object from the /// Removes the first occurrence of a specific object from the
/// TransformingReadOnlyCollection. /// TransformingReadOnlyCollection.

View File

@ -0,0 +1,471 @@
#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2008 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;
using NMock2;
namespace Nuclex.Support.Collections {
/// <summary>Unit Test for the transforming read only collection wrapper</summary>
[TestFixture]
public class TransformingReadOnlyCollectionTest {
#region class StringTransformer
/// <summary>Test implementation of a transforming collection</summary>
private class StringTransformer : TransformingReadOnlyCollection<int, string> {
/// <summary>Initializes a new int-to-string transforming collection</summary>
/// <param name="items">Items the transforming collection will contain</param>
public StringTransformer(IList<int> items) : base(items) { }
/// <summary>Transforms an item into the exposed type</summary>
/// <param name="item">Item to be transformed</param>
/// <returns>The transformed item</returns>
/// <remarks>
/// This method is used to transform an item in the wrapped collection into
/// the exposed item type whenever the user accesses an item. Expect it to
/// be called frequently, because the TransformingReadOnlyCollection does
/// not cache or otherwise store the transformed items.
/// </remarks>
protected override string Transform(int item) {
if(item == 42) {
return null;
}
return item.ToString();
}
}
#endregion // class StringTransformer
/// <summary>
/// Verifies that the copy constructor of the transforming read only collection works
/// </summary>
[Test]
public void TestCopyConstructor() {
int[] integers = new int[] { 12, 34, 56, 78 };
StringTransformer testCollection = new StringTransformer(integers);
string[] strings = new string[] { "12", "34", "56", "78" };
CollectionAssert.AreEqual(strings, testCollection);
}
/// <summary>Verifies that the IsReadOnly property returns true</summary>
[Test]
public void TestIsReadOnly() {
StringTransformer testCollection = new StringTransformer(new int[0]);
Assert.IsTrue(testCollection.IsReadOnly);
}
/// <summary>
/// Verifies that the CopyTo() of the transforming read only collection works
/// </summary>
[Test]
public void TestCopyToArray() {
int[] inputIntegers = new int[] { 12, 34, 56, 78 };
StringTransformer testCollection = new StringTransformer(inputIntegers);
string[] inputStrings = new string[] { "12", "34", "56", "78" };
string[] outputStrings = new string[testCollection.Count];
testCollection.CopyTo(outputStrings, 0);
CollectionAssert.AreEqual(inputStrings, outputStrings);
}
/// <summary>
/// Verifies that the CopyTo() of the transforming read only collection throws
/// an exception if the target array is too small to hold the collection's contents
/// </summary>
[Test, ExpectedException(typeof(ArgumentException))]
public void TestThrowOnCopyToTooSmallArray() {
int[] inputIntegers = new int[] { 12, 34, 56, 78 };
StringTransformer testCollection = new StringTransformer(inputIntegers);
string[] outputStrings = new string[testCollection.Count - 1];
testCollection.CopyTo(outputStrings, 0);
}
/// <summary>
/// Checks whether the Contains() method of the transforming read only collection
/// is able to determine if the collection contains an item
/// </summary>
[Test]
public void TestContains() {
int[] integers = new int[] { 1234, 6789 };
StringTransformer testCollection = new StringTransformer(integers);
Assert.IsTrue(testCollection.Contains("1234"));
Assert.IsFalse(testCollection.Contains("4321"));
}
/// <summary>
/// Checks whether the IndexOf() method of the transforming read only collection
/// is able to determine if the index of an item in the collection
/// </summary>
[Test]
public void TestIndexOf() {
int[] integers = new int[] { 12, 34, 67, 89 };
StringTransformer testCollection = new StringTransformer(integers);
Assert.AreEqual(0, testCollection.IndexOf("12"));
Assert.AreEqual(1, testCollection.IndexOf("34"));
Assert.AreEqual(2, testCollection.IndexOf("67"));
Assert.AreEqual(3, testCollection.IndexOf("89"));
}
/// <summary>
/// Checks whether the IndexOf() method of the transforming read only collection
/// can cope with queries for 'null' when no 'null' item is contained on it
/// </summary>
[Test]
public void TestIndexOfWithNullItemNotContained() {
int[] integers = new int[] { 12, 34, 67, 89 };
StringTransformer testCollection = new StringTransformer(integers);
Assert.AreEqual(-1, testCollection.IndexOf(null));
}
/// <summary>
/// Checks whether the IndexOf() method of the transforming read only collection
/// can cope with queries for 'null' when a 'null' item is contained on it
/// </summary>
[Test]
public void TestIndexOfWithNullItemContained() {
int[] integers = new int[] { 12, 34, 67, 89, 42 };
StringTransformer testCollection = new StringTransformer(integers);
Assert.AreEqual(4, testCollection.IndexOf(null));
}
/// <summary>
/// Verifies that the Enumerator of the transforming read only collection correctly
/// implements the Reset() method
/// </summary>
[Test]
public void TestEnumeratorReset() {
int[] integers = new int[] { 1234, 6789 };
StringTransformer testCollection = new StringTransformer(integers);
IEnumerator<string> stringEnumerator = testCollection.GetEnumerator();
Assert.IsTrue(stringEnumerator.MoveNext());
Assert.IsTrue(stringEnumerator.MoveNext());
Assert.IsFalse(stringEnumerator.MoveNext());
stringEnumerator.Reset();
Assert.IsTrue(stringEnumerator.MoveNext());
Assert.IsTrue(stringEnumerator.MoveNext());
Assert.IsFalse(stringEnumerator.MoveNext());
}
/// <summary>
/// Checks whether the indexer method of the transforming read only collection
/// is able to retrieve items from the collection
/// </summary>
[Test]
public void TestRetrieveByIndexer() {
int[] integers = new int[] { 12, 34, 67, 89 };
StringTransformer testCollection = new StringTransformer(integers);
Assert.AreEqual("12", testCollection[0]);
Assert.AreEqual("34", testCollection[1]);
Assert.AreEqual("67", testCollection[2]);
Assert.AreEqual("89", testCollection[3]);
}
/// <summary>
/// Checks whether the transforming read only collection will throw an exception
/// if its Insert() method is called via the generic IList&lt;&gt; interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnInsertViaGenericIList() {
StringTransformer testCollection = new StringTransformer(new int[0]);
(testCollection as IList<string>).Insert(0, "12345");
}
/// <summary>
/// Checks whether the transforming read only collection will throw an exception
/// if its RemoveAt() method is called via the generic IList&lt;&gt; interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnRemoveViaGenericIList() {
StringTransformer testCollection = new StringTransformer(new int[1]);
(testCollection as IList<string>).RemoveAt(0);
}
/// <summary>
/// Checks whether the indexer method of the transforming read only collection will
/// throw an exception if it is attempted to be used for replacing an item
/// </summary>
[Test]
public void TestRetrieveByIndexerViaGenericIList() {
int[] integers = new int[] { 12, 34, 67, 89 };
StringTransformer testCollection = new StringTransformer(integers);
Assert.AreEqual("12", (testCollection as IList<string>)[0]);
Assert.AreEqual("34", (testCollection as IList<string>)[1]);
Assert.AreEqual("67", (testCollection as IList<string>)[2]);
Assert.AreEqual("89", (testCollection as IList<string>)[3]);
}
/// <summary>
/// Checks whether the indexer method of the transforming read only collection
/// will throw an exception if it is attempted to be used for replacing an item
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnReplaceByIndexerViaGenericIList() {
StringTransformer testCollection = new StringTransformer(new int[1]);
(testCollection as IList<string>)[0] = "12345";
}
/// <summary>
/// Checks whether the transforming read only collection will throw an exception
/// if its Add() method is called via the generic ICollection&lt;&gt; interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnAddViaGenericICollection() {
StringTransformer testCollection = new StringTransformer(new int[0]);
(testCollection as ICollection<string>).Add("12345");
}
/// <summary>
/// Checks whether the transforming read only collection will throw an exception
/// if its Clear() method is called via the generic ICollection&lt;&gt; interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnClearViaGenericICollection() {
StringTransformer testCollection = new StringTransformer(new int[1]);
(testCollection as ICollection<string>).Clear();
}
/// <summary>
/// Checks whether the transforming read only collection will throw an exception
/// if its Remove() method is called via the generic ICollection&lt;&gt; interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnRemoveViaGenericICollection() {
int[] integers = new int[] { 12, 34, 67, 89 };
StringTransformer testCollection = new StringTransformer(integers);
(testCollection as ICollection<string>).Remove("89");
}
/// <summary>
/// Tests whether the typesafe enumerator of the read only collection is working
/// </summary>
[Test]
public void TestTypesafeEnumerator() {
int[] inputIntegers = new int[] { 12, 34, 56, 78 };
StringTransformer testCollection = new StringTransformer(inputIntegers);
List<string> outputStrings = new List<string>();
foreach(string value in testCollection) {
outputStrings.Add(value);
}
string[] inputStrings = new string[] { "12", "34", "56", "78" };
CollectionAssert.AreEqual(inputStrings, outputStrings);
}
/// <summary>
/// Checks whether the transforming read only collection will throw an exception
/// if its Clear() method is called via the IList interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnClearViaIList() {
StringTransformer testCollection = new StringTransformer(new int[1]);
(testCollection as IList).Clear();
}
/// <summary>
/// Checks whether the transforming read only collection will throw an exception
/// if its Add() method is called via the IList interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnAddViaIList() {
StringTransformer testCollection = new StringTransformer(new int[0]);
(testCollection as IList).Add("12345");
}
/// <summary>
/// Checks whether the Contains() method of the transforming read only collection
/// is able to determine if the collection contains an item
/// </summary>
[Test]
public void TestContainsViaIList() {
int[] integers = new int[] { 1234, 6789 };
StringTransformer testCollection = new StringTransformer(integers);
Assert.IsTrue((testCollection as IList).Contains("1234"));
Assert.IsFalse((testCollection as IList).Contains("4321"));
}
/// <summary>
/// Checks whether the IndexOf() method of the transforming read only collection
/// is able to determine if the index of an item in the collection
/// </summary>
[Test]
public void TestIndexOfViaIList() {
int[] integers = new int[] { 12, 34, 67, 89 };
StringTransformer testCollection = new StringTransformer(integers);
Assert.AreEqual(0, (testCollection as IList).IndexOf("12"));
Assert.AreEqual(1, (testCollection as IList).IndexOf("34"));
Assert.AreEqual(2, (testCollection as IList).IndexOf("67"));
Assert.AreEqual(3, (testCollection as IList).IndexOf("89"));
}
/// <summary>
/// Checks whether the transforming read only collection will throw an exception
/// if its Insert() method is called via the IList interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnInsertViaIList() {
StringTransformer testCollection = new StringTransformer(new int[0]);
(testCollection as IList).Insert(0, "12345");
}
/// <summary>
/// Checks whether the IsFixedSize property of the transforming read only collection
/// returns the expected result for a transforming read only collection based on
/// a fixed array
/// </summary>
[Test]
public void TestIsFixedSizeViaIList() {
int[] integers = new int[] { 12, 34, 67, 89 };
StringTransformer testCollection = new StringTransformer(integers);
Assert.IsTrue((testCollection as IList).IsFixedSize);
}
/// <summary>
/// Checks whether the transforming read only collection will throw an exception
/// if its Remove() method is called via the IList interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnRemoveViaIList() {
int[] integers = new int[] { 1234, 6789 };
StringTransformer testCollection = new StringTransformer(integers);
(testCollection as IList).Remove("6789");
}
/// <summary>
/// Checks whether the transforming read only collection will throw an exception
/// if its Remove() method is called via the IList interface
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnRemoveAtViaIList() {
StringTransformer testCollection = new StringTransformer(new int[1]);
(testCollection as IList).RemoveAt(0);
}
/// <summary>
/// Checks whether the indexer method of the transforming read only collection
/// will throw an exception if it is attempted to be used for replacing an item
/// </summary>
[Test]
public void TestRetrieveByIndexerViaIList() {
int[] integers = new int[] { 12, 34, 67, 89 };
StringTransformer testCollection = new StringTransformer(integers);
Assert.AreEqual("12", (testCollection as IList)[0]);
Assert.AreEqual("34", (testCollection as IList)[1]);
Assert.AreEqual("67", (testCollection as IList)[2]);
Assert.AreEqual("89", (testCollection as IList)[3]);
}
/// <summary>
/// Checks whether the indexer method of the transforming read only collection
/// will throw an exception if it is attempted to be used for replacing an item
/// </summary>
[Test, ExpectedException(typeof(NotSupportedException))]
public void TestThrowOnReplaceByIndexerViaIList() {
StringTransformer testCollection = new StringTransformer(new int[1]);
(testCollection as IList)[0] = "12345";
}
/// <summary>
/// Verifies that the CopyTo() of the transforming read only collection works
/// if invoked via the ICollection interface
/// </summary>
[Test]
public void TestCopyToArrayViaICollection() {
int[] inputIntegers = new int[] { 12, 34, 56, 78 };
StringTransformer testCollection = new StringTransformer(inputIntegers);
string[] outputStrings = new string[testCollection.Count];
(testCollection as ICollection).CopyTo(outputStrings, 0);
string[] inputStrings = new string[] { "12", "34", "56", "78" };
CollectionAssert.AreEqual(inputStrings, outputStrings);
}
/// <summary>
/// Verifies that the IsSynchronized property and the SyncRoot property are working
/// </summary>
[Test]
public void TestSynchronization() {
StringTransformer testCollection = new StringTransformer(new int[0]);
if(!(testCollection as ICollection).IsSynchronized) {
lock((testCollection as ICollection).SyncRoot) {
int count = testCollection.Count;
}
}
}
/// <summary>
/// Verifies that the IsSynchronized property and the SyncRoot property are working
/// on transforming read only collections based on IList&lt;&gt;s that do not
/// implement the ICollection interface
/// </summary>
[Test]
public void TestSynchronizationOfIListWithoutICollection() {
Mockery mockery = new Mockery();
IList<int> mockedIList = mockery.NewMock<IList<int>>();
StringTransformer testCollection = new StringTransformer(mockedIList);
if(!(testCollection as ICollection).IsSynchronized) {
lock((testCollection as ICollection).SyncRoot) {
Expect.Once.On(mockedIList).GetProperty("Count").Will(Return.Value(12345));
int count = testCollection.Count;
Assert.AreEqual(12345, count); // ;-)
}
}
}
}
} // namespace Nuclex.Support.Collections
#endif // UNITTEST

View File

@ -181,15 +181,15 @@ namespace Nuclex.Support.Collections {
/// Array is null. /// Array is null.
/// </exception> /// </exception>
public void CopyTo(ExposedItemType[] array, int index) { public void CopyTo(ExposedItemType[] array, int index) {
if(this.items.Count > (array.Length - index)) {
if(this.items.Count > (array.Length - index))
throw new ArgumentException( throw new ArgumentException(
"Array too small to fit the collection items starting at the specified index" "Array too small to fit the collection items starting at the specified index"
); );
}
for(int itemIndex = 0; itemIndex < this.items.Count; ++itemIndex) for(int itemIndex = 0; itemIndex < this.items.Count; ++itemIndex) {
array[itemIndex + index] = Transform(this.items[itemIndex]); array[itemIndex + index] = Transform(this.items[itemIndex]);
}
} }
/// <summary> /// <summary>
@ -266,6 +266,11 @@ namespace Nuclex.Support.Collections {
get { return Transform(this.items[index]); } get { return Transform(this.items[index]); }
} }
/// <summary>Whether the List is write-protected</summary>
public bool IsReadOnly {
get { return true; }
}
/// <summary>Transforms an item into the exposed type</summary> /// <summary>Transforms an item into the exposed type</summary>
/// <param name="item">Item to be transformed</param> /// <param name="item">Item to be transformed</param>
/// <returns>The transformed item</returns> /// <returns>The transformed item</returns>