mirror of
https://github.com/inthehand/32feet.git
synced 2026-10-20 07:38:22 +08:00
153 lines
5.2 KiB
C#
153 lines
5.2 KiB
C#
using System;
|
|
|
|
namespace NUnit.Framework
|
|
{
|
|
/// <summary>
|
|
/// Abstract base class for EqualsAsserter and NotEqualsAsserter
|
|
/// </summary>
|
|
public abstract class EqualityAsserter : ComparisonAsserter
|
|
{
|
|
private double delta;
|
|
|
|
/// <summary>
|
|
/// Constructor taking expected and actual values and a user message with arguments.
|
|
/// </summary>
|
|
/// <param name="expected"></param>
|
|
/// <param name="actual"></param>
|
|
/// <param name="message"></param>
|
|
/// <param name="args"></param>
|
|
public EqualityAsserter( object expected, object actual, string message, params object[] args )
|
|
: base( expected, actual, message, args ) { }
|
|
|
|
/// <summary>
|
|
/// Constructor taking expected and actual values, a tolerance
|
|
/// and a user message and arguments.
|
|
/// </summary>
|
|
/// <param name="expected"></param>
|
|
/// <param name="actual"></param>
|
|
/// <param name="delta"></param>
|
|
/// <param name="message"></param>
|
|
/// <param name="args"></param>
|
|
public EqualityAsserter( double expected, double actual, double delta, string message, params object[] args )
|
|
: base( expected, actual, message, args )
|
|
{
|
|
this.delta = delta;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Used to compare two objects. Two nulls are equal and null
|
|
/// is not equal to non-null. Comparisons between the same
|
|
/// numeric types are fine (Int32 to Int32, or Int64 to Int64),
|
|
/// but the Equals method fails across different types so we
|
|
/// use <c>ToString</c> and compare the results.
|
|
/// </summary>
|
|
/// <param name="expected"></param>
|
|
/// <param name="actual"></param>
|
|
/// <returns></returns>
|
|
protected virtual bool ObjectsEqual( Object expected, Object actual )
|
|
{
|
|
if ( expected == null && actual == null ) return true;
|
|
if ( expected == null || actual == null ) return false;
|
|
|
|
//if ( expected.GetType().IsArray && actual.GetType().IsArray )
|
|
// return ArraysEqual( (System.Array)expected, (System.Array)actual );
|
|
|
|
if ( expected is double && actual is double )
|
|
{
|
|
if ( double.IsNaN((double)expected) && double.IsNaN((double)actual) )
|
|
return true;
|
|
// handle infinity specially since subtracting two infinite values gives
|
|
// NaN and the following test fails. mono also needs NaN to be handled
|
|
// specially although ms.net could use either method.
|
|
if (double.IsInfinity((double)expected) || double.IsNaN((double)expected) || double.IsNaN((double)actual))
|
|
return expected.Equals( actual );
|
|
else
|
|
return Math.Abs((double)expected-(double)actual) <= this.delta;
|
|
}
|
|
|
|
// if ( expected is float && actual is float )
|
|
// {
|
|
// // handle infinity specially since subtracting two infinite values gives
|
|
// // NaN and the following test fails. mono also needs NaN to be handled
|
|
// // specially although ms.net could use either method.
|
|
// if (float.IsInfinity((float)expected) || float.IsNaN((float)expected) || float.IsNaN((float)actual))
|
|
// return (float)expected == (float)actual;
|
|
// else
|
|
// return Math.Abs((float)expected-(float)actual) <= (float)this.delta;
|
|
// }
|
|
|
|
if ( expected.GetType() != actual.GetType() &&
|
|
IsNumericType( expected ) && IsNumericType( actual ) )
|
|
{
|
|
//
|
|
// Convert to strings and compare result to avoid
|
|
// issues with different types that have the same
|
|
// value
|
|
//
|
|
string sExpected = expected.ToString();
|
|
string sActual = actual.ToString();
|
|
return sExpected.Equals( sActual );
|
|
}
|
|
return expected.Equals(actual);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks the type of the object, returning true if
|
|
/// the object is a numeric type.
|
|
/// </summary>
|
|
/// <param name="obj">The object to check</param>
|
|
/// <returns>true if the object is a numeric type</returns>
|
|
private bool IsNumericType( Object obj )
|
|
{
|
|
if( null != obj )
|
|
{
|
|
if( obj is byte ) return true;
|
|
if( obj is sbyte ) return true;
|
|
if( obj is decimal ) return true;
|
|
if( obj is double ) return true;
|
|
if( obj is float ) return true;
|
|
if( obj is int ) return true;
|
|
if( obj is uint ) return true;
|
|
if( obj is long ) return true;
|
|
if( obj is short ) return true;
|
|
if( obj is ushort ) return true;
|
|
|
|
if( obj is System.Byte ) return true;
|
|
if( obj is System.SByte ) return true;
|
|
if( obj is System.Decimal ) return true;
|
|
if( obj is System.Double ) return true;
|
|
if( obj is System.Single ) return true;
|
|
if( obj is System.Int32 ) return true;
|
|
if( obj is System.UInt32 ) return true;
|
|
if( obj is System.Int64 ) return true;
|
|
if( obj is System.UInt64 ) return true;
|
|
if( obj is System.Int16 ) return true;
|
|
if( obj is System.UInt16 ) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Helper method to compare two arrays
|
|
/// </summary>
|
|
protected virtual bool ArraysEqual( Array expected, Array actual )
|
|
{
|
|
if ( expected.Rank != actual.Rank )
|
|
return false;
|
|
|
|
if ( expected.Rank != 1 )
|
|
throw new ArgumentException( "Multi-dimension array comparison is not supported" );
|
|
|
|
int iLength = Math.Min( expected.Length, actual.Length );
|
|
for( int i = 0; i < iLength; i++ )
|
|
if ( !ObjectsEqual( expected.GetValue( i ), actual.GetValue( i ) ) )
|
|
return false;
|
|
|
|
if ( expected.Length != actual.Length )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|