view Constraints/ArrayContainsConstraint.cs @ 2:405baf327de2

Re #46: Add NUnit helper methods * Improve additional information message * Improve handling of mis-matched length arrays
author IBBoard <dev@ibboard.co.uk>
date Sat, 21 Aug 2010 14:53:48 +0000
parents 4dad6872ca5a
children
line wrap: on
line source

//  This file (Contain.cs) is a part of the IBBoard.NUnit project and is copyright 2010 IBBoard
// 
// The file and the library/program it is in are licensed and distributed, without warranty, under the GNU LGPL, either version 3 of the License or (at your option) any later version. Please see COPYING for more information and the full license.
using System;
using NUnit.Framework.Constraints;
using NUnit.Framework;
namespace IBBoard.NUnit.Constraints
{
	/// <summary>
	/// Requires a list of objects to appear in a given order from the start of an array
	/// </summary>
	public class ArrayContainsConstraint<T> : Constraint
	{
		private static readonly int NOT_FOUND = -1;
		private T[] containedObjs;
		private int idx = NOT_FOUND;
		
		public ArrayContainsConstraint(params T[] containedObjects)
		{
			containedObjs = containedObjects;
		}
		
		public override bool Matches(object actual)
		{
			this.actual = actual;
			
			if (!(actual is Array))
			{
				throw new ArgumentException("The actual value must be an array");
			}
			
			return DoMatch((object[])this.actual);
		}
		
		private bool DoMatch(object[] array)
		{
			bool isMatch = true;
			idx = NOT_FOUND;
			
			int max = Math.Min(array.Length, containedObjs.Length);
			
			for (int i = 0; i < max; i++)
			{
				if (!EqualityChecker.AreEqual(containedObjs[i], array[i]))
				{
					isMatch = false;
					idx = i;
					break;
				}
			}

			if (isMatch && containedObjs.Length != array.Length)
			{
				isMatch = false;
				idx = max;
			}
			
			return isMatch;
		}
		
		public override void WriteDescriptionTo(MessageWriter writer)
		{
			if (containedObjs.Length == 0)
			{
				writer.Write("Empty array");
			}
			else if (idx == NOT_FOUND)
			{
				writer.WriteExpectedValue(containedObjs[0]);
			}
			else if (idx >= containedObjs.Length)
			{
				writer.Write("End of array");
			}
			else
			{
				writer.WriteExpectedValue(containedObjs[idx]);
			}
		}
		
		public override void WriteActualValueTo(MessageWriter writer)
		{
			object[] actualArray = ((object[])actual);
			
			if (actualArray.Length == 0)
			{				
				writer.Write("Empty array");
			}
			else if (idx == NOT_FOUND)
			{
				writer.WriteActualValue(actualArray[0]);
			}
			else if (idx >= actualArray.Length)
			{
				writer.Write("End of array");
			}
			else
			{
				writer.WriteActualValue(actualArray[idx]);
			}
		}
		
		public override void WriteMessageTo(MessageWriter writer)
		{
			base.WriteMessageTo(writer);
			
			if (idx >= containedObjs.Length)
			{
				writer.WriteMessageLine("Unexpected value at index {0}", idx);
			}
			else if (idx >= ((object[])actual).Length)
			{
				writer.WriteMessageLine("Expected value at index {0}", idx);
			}
			else if (idx != NOT_FOUND)
			{
				writer.WriteMessageLine("Incorrect value at index {0}", idx);
			}
		}
	}
}