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>
</Compile>
<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.Test.cs">
<DependentUpon>ReadOnlyList.cs</DependentUpon>
</Compile>
<Compile Include="Source\Collections\ReverseComparer.cs" />
<Compile Include="Source\Collections\ReverseComparer.Test.cs">
<DependentUpon>ReverseComparer.cs</DependentUpon>
@ -93,6 +99,9 @@
<Compile Include="Source\Collections\TransformingReadOnlyCollection.Interfaces.cs">
<DependentUpon>TransformingReadOnlyCollection.cs</DependentUpon>
</Compile>
<Compile Include="Source\Collections\TransformingReadOnlyCollection.Test.cs">
<DependentUpon>TransformingReadOnlyCollection.cs</DependentUpon>
</Compile>
<Compile Include="Source\FloatHelper.cs" />
<Compile Include="Source\FloatHelper.Test.cs">
<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>
bool IList.IsFixedSize {
get { throw new NotImplementedException(); }
get { return this.objectList.IsFixedSize; }
}
/// <summary>Removes the specified item from the List</summary>

View File

@ -35,19 +35,6 @@ namespace Nuclex.Support.Collections {
#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>
/// Inserts an item to the TransformingReadOnlyCollection at the specified index.
/// </summary>
@ -120,48 +107,6 @@ namespace Nuclex.Support.Collections {
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>
/// Removes the first occurrence of a specific object from the
/// TransformingReadOnlyCollection.
@ -181,33 +126,6 @@ namespace Nuclex.Support.Collections {
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
#region IEnumerable Members
@ -304,13 +222,6 @@ namespace Nuclex.Support.Collections {
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>
/// Removes the first occurrence of a specific object from the
/// 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.
/// </exception>
public void CopyTo(ExposedItemType[] array, int index) {
if(this.items.Count > (array.Length - index))
if(this.items.Count > (array.Length - index)) {
throw new ArgumentException(
"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]);
}
}
/// <summary>
@ -266,6 +266,11 @@ namespace Nuclex.Support.Collections {
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>
/// <param name="item">Item to be transformed</param>
/// <returns>The transformed item</returns>