/// <summary> /// Test two numeric values for equality, performing the usual numeric /// conversions and using a provided or default tolerance. If the tolerance /// provided is Empty, this method may set it to a default tolerance. /// </summary> /// <param name="expected">The expected value</param> /// <param name="actual">The actual value</param> /// <param name="tolerance">A reference to the tolerance in effect</param> /// <returns>True if the values are equal</returns> public static bool AreEqual( object expected, object actual, ref Tolerance tolerance ) { if ( expected is double || actual is double ) return AreEqual( Convert.ToDouble(expected), Convert.ToDouble(actual), ref tolerance ); if ( expected is float || actual is float ) return AreEqual( Convert.ToSingle(expected), Convert.ToSingle(actual), ref tolerance ); if (tolerance.Mode == ToleranceMode.Ulps) throw new InvalidOperationException("Ulps may only be specified for floating point arguments"); if ( expected is decimal || actual is decimal ) return AreEqual( Convert.ToDecimal(expected), Convert.ToDecimal(actual), tolerance ); if (expected is ulong || actual is ulong) return AreEqual(Convert.ToUInt64(expected), Convert.ToUInt64(actual), tolerance ); if ( expected is long || actual is long ) return AreEqual( Convert.ToInt64(expected), Convert.ToInt64(actual), tolerance ); if ( expected is uint || actual is uint ) return AreEqual( Convert.ToUInt32(expected), Convert.ToUInt32(actual), tolerance ); return AreEqual( Convert.ToInt32(expected), Convert.ToInt32(actual), tolerance ); }
/// <summary> /// Display Expected and Actual lines for given values, including /// a tolerance value on the Expected line. /// </summary> /// <param name="expected">The expected value</param> /// <param name="actual">The actual value causing the failure</param> /// <param name="tolerance">The tolerance within which the test was made</param> public abstract void DisplayDifferences(object expected, object actual, Tolerance tolerance);
/// <summary> /// Write the generic 'Expected' line for a given value /// and tolerance. /// </summary> /// <param name="expected">The expected value</param> /// <param name="tolerance">The tolerance within which the test was made</param> private void WriteExpectedLine(object expected, Tolerance tolerance) { Write(Pfx_Expected); WriteExpectedValue(expected); if (tolerance != null && !tolerance.IsEmpty) { WriteConnector("+/-"); WriteExpectedValue(tolerance.Value); } WriteLine(); }
/// <summary> /// Display Expected and Actual lines for given values, including /// a tolerance value on the expected line. /// </summary> /// <param name="expected">The expected value</param> /// <param name="actual">The actual value causing the failure</param> /// <param name="tolerance">The tolerance within which the test was made</param> public override void DisplayDifferences(object expected, object actual, Tolerance tolerance) { WriteExpectedLine(expected, tolerance); WriteActualLine(actual); }
private static bool AreEqual( int expected, int actual, Tolerance tolerance ) { switch (tolerance.Mode) { case ToleranceMode.None: return expected.Equals(actual); case ToleranceMode.Linear: int intTolerance = Convert.ToInt32(tolerance.Value); if (intTolerance > 0) return Math.Abs(expected - actual) <= intTolerance; return expected.Equals(actual); case ToleranceMode.Percent: if (expected == 0) return expected.Equals(actual); double relativeError = Math.Abs( (double)(expected - actual) / (double)expected); return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0); default: throw new ArgumentException("Unknown tolerance mode specified", "mode"); } }
private static bool AreEqual( uint expected, uint actual, Tolerance tolerance ) { switch (tolerance.Mode) { case ToleranceMode.None: return expected.Equals(actual); case ToleranceMode.Linear: uint uintTolerance = Convert.ToUInt32(tolerance.Value); if(uintTolerance > 0) { uint diff = expected >= actual ? expected - actual : actual - expected; return diff <= uintTolerance; } return expected.Equals( actual ); case ToleranceMode.Percent: if(expected == 0u) return expected.Equals(actual); // Can't do a simple Math.Abs() here since it's unsigned uint difference = Math.Max(expected, actual) - Math.Min(expected, actual); double relativeError = Math.Abs((double)difference / (double)expected ); return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0); default: throw new ArgumentException("Unknown tolerance mode specified", "mode"); } }
private static bool AreEqual( float expected, float actual, ref Tolerance tolerance ) { if ( float.IsNaN(expected) && float.IsNaN(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 (float.IsInfinity(expected) || float.IsNaN(expected) || float.IsNaN(actual)) { return expected.Equals(actual); } if (tolerance.IsEmpty && GlobalSettings.DefaultFloatingPointTolerance > 0.0d) tolerance = new Tolerance(GlobalSettings.DefaultFloatingPointTolerance); switch (tolerance.Mode) { case ToleranceMode.None: return expected.Equals(actual); case ToleranceMode.Linear: return Math.Abs(expected - actual) <= Convert.ToDouble(tolerance.Value); case ToleranceMode.Percent: if (expected == 0.0f) return expected.Equals(actual); float relativeError = Math.Abs((expected - actual) / expected); return (relativeError <= Convert.ToSingle(tolerance.Value) / 100.0f); #if !NETCF_1_0 case ToleranceMode.Ulps: return FloatingPointNumerics.AreAlmostEqualUlps( expected, actual, Convert.ToInt32(tolerance.Value)); #endif default: throw new ArgumentException("Unknown tolerance mode specified", "mode"); } }