using System.Linq;
using Chernobyl;
using Chernobyl.Collections.Generic;
using NUnit.Framework;
namespace System.Collections.Generic
{
///
/// An NUnit base test fixture class that is made to test
/// and types.
/// This tests includes:
///
/// - Iteration of a single item.
/// - Iteration of many items.
///
///
/// The type held by the
public abstract class EnumerationTests
{
///
/// Initializes a new instance of the
/// class.
///
/// True if the order of iteration by
/// the should be tested, false if otherwise.
/// If you specify true, be sure to implement the
/// property.
protected EnumerationTests(bool testIterationOrder)
: this(testIterationOrder, null)
{ }
///
/// Initializes a new instance of the
/// class.
///
/// True if the order of iteration by
/// the should be tested, false if otherwise.
/// If you specify true, be sure to implement the
/// property.
/// The that
/// is used to compare values in the for
/// uniqueness or null if the default
/// specified by is to be used.
protected EnumerationTests(bool testIterationOrder, IEqualityComparer comparer)
{
TestIterationOrder = testIterationOrder;
Comparer = comparer ?? EqualityComparer.Default;
}
[Test, Description("Tests the iteration of a single item.")]
public virtual void SingleItemIteration()
{
int count = 0;
foreach (T foobar in CreateSingleItemEnumerable())
count++;
Assert.AreEqual(1, count, "Failed to iterate over single item in the " +
"IEnumerable. Instead this method iterated over \"" + count +
"\" items.");
}
[Test, Description("Tests the order of the items iterated in the IEnumerable " +
"if testing of ordered iteration is required (see the constructor for " +
"more information).")]
public virtual void ManyItemIteration()
{
IEnumerable enumerable = CreateManyItemEnumerable();
int enumerableCount = enumerable.Count();
if(TestIterationOrder == true)
{
int orderedItemsCount = OrderedItems.Count();
Assert.AreEqual(orderedItemsCount, enumerableCount,
"The IEnumerable does not have the expected number " +
"of items.");
for (int i = 0; i < orderedItemsCount; i++)
{
T expected = OrderedItems.ElementAt(i);
T actual = enumerable.ElementAt(i);
Assert.That(Comparer.Equals(expected, actual),
"The item " + actual + " does not equal " + expected +
" when it was expected to.");
}
}
Assert.That(enumerableCount >= 5, "The IEnumerable did not contain 5 or " +
"more items. It contained " + enumerableCount + " items.");
}
[Test, Description("Ensures the items in the IEnumerable are unique.")]
public virtual void ManyItemUniqueness()
{
IEnumerable enumerable = CreateManyItemEnumerable();
int enumerableCount = enumerable.Count();
Assert.That(enumerableCount >= 5, "The IEnumerable did not contain 5 or " +
"more items. It contained " + enumerableCount + " items.");
Assert.That(enumerable.IsUnique(Comparer), "The items in " +
"the list must be unique.");
}
///
/// This method should return a new that can
/// be iterated over exactly once. This method should create a new
/// every time it is invoked and not reuse
/// instances.
///
/// The containing a single item.
protected abstract IEnumerable CreateSingleItemEnumerable();
///
/// This method should return a new that can
/// be iterated over five or more times. The items will be compared to
/// the items in but only
/// if the property
/// is set to true. This method should create a new
/// every time it is invoked and not reuse
/// instances. All instances returned through iteration of the
/// should be unique.
///
/// The containing many items.
protected abstract IEnumerable CreateManyItemEnumerable();
///
/// Returns the items created by
/// are expected to be in.
///
protected virtual IEnumerable OrderedItems
{
get
{
throw new NotImplementedException("The deriving class has not " +
"implemented this property.");
}
}
///
/// The that is used to compare
/// values in the for uniqueness.
///
protected IEqualityComparer Comparer { get; set; }
///
/// True if the order of iteration by the
/// should be tested, false if otherwise.
///
bool TestIterationOrder { get; set; }
}
}