//
// MultiList library - Copyright 2008 by Michael Moorman / AsAbove.net
// This work is released to the public domain, and may be used for any purpose, without any conditions.
//
using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using AsAbove.Collections;
using AsAbove.Collections.Exception;
namespace Test
{
[TestFixture]
public class UnitTest
{
private NameComparer nameComparer;
private AgeComparer ageComparer;
private CareerComparer careerComparer;
private MultiList<Person> _ml;
private enum bogusEnumerator
{
should,
cause,
exception
}
[TestFixtureSetUp]
public void Init ()
{
nameComparer = new NameComparer ();
ageComparer = new AgeComparer ();
careerComparer = new CareerComparer ();
_ml = new MultiList<Person> (typeof (PersonSortCriteria), nameComparer, ageComparer, careerComparer);
}
[Test]
public void A01_AddAndFind ()
{
Person TomPerson = new Person ("Tom", 56, Person.Profession.Welder);
_ml.Add (new Person ("Jim", 42, Person.Profession.Teacher));
_ml.Add (new Person ("Susan", 29, Person.Profession.Lawyer));
_ml.Add (new Person ("Arthur", 22, Person.Profession.Barber));
_ml.Add (TomPerson);
_ml.Add (new Person ("Betty", 50, Person.Profession.Teacher));
_ml.Add (new Person ("Joe", 18, Person.Profession.Lawyer));
_ml.Add (new Person ("Sandra", 25, Person.Profession.Carpenter));
_ml.Add (new Person ("Andy", 56, Person.Profession.Barber));
_ml.Add (new Person ("Ty", 19, Person.Profession.Carpenter));
_ml.Add (new Person ("Bea", 33, Person.Profession.Nurse));
_ml.Add (new Person ("Andy", 20, Person.Profession.Carpenter));
_ml.Add (new Person ("Andy", 21, Person.Profession.Teacher));
int position;
bool found;
// search and find position
position = _ml.FindIndex<string> (PersonSortCriteria.Name, nameComparer, "Tom");
Assert.AreNotEqual (position, MultiList<Person>.NotFound);
Console.WriteLine ("Found 'Tom' in Name sort at position " + position);
position = _ml.FindIndex<string> (PersonSortCriteria.Name, nameComparer, "Andy");
Assert.AreNotEqual (position, MultiList<Person>.NotFound);
Console.WriteLine ("Found 'Andy' in Name sort at position " + position);
// there are two Andy persons, so this index should differ.
int lastPosition = _ml.FindLastIndex<string> (PersonSortCriteria.Name, nameComparer, "Andy");
Assert.AreNotEqual (position, lastPosition);
// search and match by Tom's name using both find variants
Person match;
found = _ml.TryFind<string> (PersonSortCriteria.Name, nameComparer, "Tom", out match);
Assert.IsTrue (found);
Assert.AreEqual (TomPerson, match);
match = _ml.Find<string> (PersonSortCriteria.Name, nameComparer, "Tom");
Assert.AreEqual (TomPerson, match);
// search and match by Tom's age using both find variants
found = _ml.TryFind<int> (PersonSortCriteria.Name, ageComparer, 56, out match);
Assert.IsTrue (found);
Assert.AreEqual (TomPerson, match);
match = _ml.Find<string> (PersonSortCriteria.Name, nameComparer, "Tom");
Assert.AreEqual (TomPerson, match);
// search and match by Tom's career using both find variants
found = _ml.TryFind<Person.Profession> (PersonSortCriteria.Career, careerComparer, Person.Profession.Welder, out match);
Assert.IsTrue (found);
Assert.AreEqual (TomPerson, match);
match = _ml.Find<Person.Profession> (PersonSortCriteria.Career, careerComparer, Person.Profession.Welder);
Assert.AreEqual (TomPerson, match);
// search and find age position, that we know does *NOT* exist
position = _ml.FindIndex<int> (PersonSortCriteria.Age, ageComparer, 44);
Assert.AreEqual (position, MultiList<Person>.NotFound);
// search and find age position, that we know exists
position = _ml.FindIndex<int> (PersonSortCriteria.Age, ageComparer, 25);
Assert.AreNotEqual (position, MultiList<Person>.NotFound);
// search career position
position = _ml.FindIndex<Person.Profession> (PersonSortCriteria.Career, careerComparer, Person.Profession.Barber);
Assert.AreNotEqual (position, MultiList<Person>.NotFound);
Console.WriteLine ("Found 'Barber' in Profession sort at position " + position);
// search career position
position = _ml.FindIndex<Person.Profession> (PersonSortCriteria.Career, careerComparer, Person.Profession.Carpenter);
Assert.AreNotEqual (position, MultiList<Person>.NotFound);
Console.WriteLine ("Found 'Carpenter' in Profession sort at position " + position);
Dump ("\r\nAfter A01_AddAndFind...");
}
[Test]
public void A02_FindIndexes ()
{
Person match = _ml.Find<string> (PersonSortCriteria.Name, nameComparer, "Andy");
// search for "Andy" which should have three entries
_ml.ActiveList = PersonSortCriteria.Name;
IndexRange range = _ml.FindIndexes (match);
Assert.AreEqual (3, range.Count);
Console.WriteLine ("Found Andy at offsets {0} through {1}", range.Start, range.End);
// try the other search methods - and verify the correct number of returned objects
Person[] persons = _ml.FindMultiple (match);
Assert.AreEqual (3, persons.Length);
persons = _ml.FindMultiple (PersonSortCriteria.Name, match);
Assert.AreEqual (3, persons.Length);
persons = _ml.FindMultiple<string> (PersonSortCriteria.Name, nameComparer, "Andy");
Assert.AreEqual (3, persons.Length);
persons = _ml.FindMultiple<string> (nameComparer, "Andy");
Assert.AreEqual (3, persons.Length);
// should be three carpenters
_ml.ActiveList = PersonSortCriteria.Career;
range = _ml.FindIndexes<Person.Profession> (careerComparer, Person.Profession.Carpenter);
Assert.AreEqual (3, range.Count);
Console.WriteLine ("Found Carpenters at offsets {0} through {1}", range.Start, range.End);
// should be two 56 year olds
_ml.ActiveList = PersonSortCriteria.Age;
range = _ml.FindIndexes<int> (ageComparer, 56);
Assert.AreEqual (2, range.Count);
Console.WriteLine ("Found 56 y.o. at offsets {0} through {1}", range.Start, range.End);
}
[Test]
public void A03_Remove ()
{
Person match;
bool found = _ml.TryFind<string> (PersonSortCriteria.Name, nameComparer, "Tom", out match);
Assert.IsTrue (found);
_ml.Remove (match);
found = _ml.TryFind<int> (PersonSortCriteria.Age, ageComparer, 50, out match);
Assert.IsTrue (found);
_ml.Remove (match);
Dump ("\r\nAfter A02_Remove removing name 'Tom' and age 50...");
}
[Test]
public void A04_Remove ()
{
Person match;
int count = 0;
// in this test, we will iteratively remove all carpenters. We know that there are three
// of them, so the list should go three times.
while (true == _ml.TryFind<Person.Profession> (PersonSortCriteria.Career, careerComparer, Person.Profession.Carpenter, out match))
{
++count;
_ml.Remove (match);
}
Assert.AreEqual (3, count);
Dump ("\r\nAfter A03_Remove removing 'Carpenter'...");
}
[Test]
public void B01_EnumeratorTypeExpectedException ()
{
try
{ // this should throw an exception because we're passing the wrong type
// as the first argument of the constructor.
MultiList<Person> p = new MultiList<Person> (typeof (Person), nameComparer, ageComparer, careerComparer);
Assert.Fail ("Expected EnumeratorTypeExpectedException");
}
catch (EnumeratorTypeExpectedException)
{}
catch (Exception)
{
Assert.Fail ("Expected EnumeratorTypeExpectedException");
}
}
[Test]
public void B02_InsufficientIComparerCount ()
{
try
{ // this should fail because we don't pass 3 comparers to the constructor.
MultiList<Person> p = new MultiList<Person> (typeof (PersonSortCriteria), nameComparer, ageComparer);
Assert.Fail ("Expected InsufficientIComparerCount");
}
catch (InsufficientIComparerCountException)
{ }
catch (Exception)
{
Assert.Fail ("Expected InsufficientIComparerCount");
}
}
[Test]
public void B03_InvalidEnumeratorException ()
{
try
{ // this should fail because we pass the wrong enumerator type
_ml.FindIndex<string> (bogusEnumerator.exception, nameComparer, "Tom");
Assert.Fail ("Expected InvalidEnumeratorException");
}
catch (InvalidEnumeratorException)
{ }
catch (Exception)
{
Assert.Fail ("Expected InvalidEnumeratorException");
}
}
[Test]
public void B04_MultiListObjectNotFoundException ()
{
try
{ // this should fail because no such Person object exists in the list
_ml.Find<string> (PersonSortCriteria.Name, nameComparer, "Oprah");
Assert.Fail ("Expected MultiListObjectNotFoundException");
}
catch (MultiListObjectNotFoundException)
{ }
catch (Exception)
{
Assert.Fail ("Expected MultiListObjectNotFoundException");
}
}
private void Dump (string comment)
{
Console.WriteLine (comment);
DumpList (PersonSortCriteria.Name);
DumpList (PersonSortCriteria.Age);
DumpList (PersonSortCriteria.Career);
}
private void DumpList (PersonSortCriteria attribute)
{
int count = _ml.Count;
int index = 0;
Console.WriteLine ("list sorted by " + attribute);
_ml.ActiveList = attribute;
foreach (Person p in _ml)
{
Console.WriteLine ("{0}.\t{1}, {2}, {3}", index++, p.Name, p.Age, p.Career);
}
// assert that the list count equals the number of iterations
Assert.AreEqual (count, index);
Console.WriteLine ("");
}
#region Sort criteria and Comparer class declarations
// this enumerator is declared to define the sort orders that we want on the Person class.
private enum PersonSortCriteria
{
Name,
Age,
Career
};
public class NameComparer : MultiList<Person>.ITypeComparer<string>, IComparer<Person>
{
public int Compare (Person p1, Person p2)
{
return p1.Name.CompareTo (p2.Name);
}
public int Compare (Person p, string name)
{
return p.Name.CompareTo (name);
}
}
public class AgeComparer : MultiList<Person>.ITypeComparer<int>, IComparer<Person>
{
public int Compare (Person p1, Person p2)
{
return p1.Age - p2.Age;
}
public int Compare (Person p, int age)
{
return p.Age - age;
}
}
public class CareerComparer : MultiList<Person>.ITypeComparer<Person.Profession>, IComparer<Person>
{
public int Compare (Person p1, Person p2)
{
return p1.Career.CompareTo (p2.Career);
}
public int Compare (Person p, Person.Profession career)
{
return p.Career.CompareTo (career);
}
}
#endregion
}
}