예제 #1
0
        /// <summary>
        ///     Tests that the current Tolerance is linear with a
        ///     numeric value, throwing an exception if it is not.
        /// </summary>
        private void CheckLinearAndNumeric()
        {
            if (mode != ToleranceMode.Linear)
            {
                throw new InvalidOperationException(mode == ToleranceMode.None
                                                        ? ModeMustFollowTolerance
                                                        : MultipleToleranceModes);
            }

            if (!Numerics.IsNumericType(amount))
            {
                throw new InvalidOperationException(NumericToleranceRequired);
            }
        }
예제 #2
0
        /// <summary>
        ///     Compares two objects
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public int Compare(object x, object y)
        {
            if (x == null)
            {
                return(y == null ? 0 : -1);
            }
            else if (y == null)
            {
                return(+1);
            }

            if (Numerics.IsNumericType(x) && Numerics.IsNumericType(y))
            {
                return(Numerics.Compare(x, y));
            }

            if (x is IComparable)
            {
                return(((IComparable)x).CompareTo(y));
            }

            if (y is IComparable)
            {
                return(-((IComparable)y).CompareTo(x));
            }

            Type xType = x.GetType();
            Type yType = y.GetType();

            MethodInfo method = xType.GetMethod("CompareTo", new[] { yType });

            if (method != null)
            {
                return((int)method.Invoke(x, new[] { y }));
            }

            method = yType.GetMethod("CompareTo", new[] { xType });
            if (method != null)
            {
                return(-(int)method.Invoke(y, new[] { x }));
            }

            throw new ArgumentException("Neither value implements IComparable or IComparable<T>");
        }
        private bool ObjectsEqual(object expected, object actual, ref Tolerance tolerance)
        {
            if (expected == null && actual == null)
            {
                return(true);
            }

            if (expected == null || actual == null)
            {
                return(false);
            }

            if (object.ReferenceEquals(expected, actual))
            {
                return(true);
            }

            Type xType = expected.GetType();
            Type yType = actual.GetType();

            EqualityAdapter externalComparer = GetExternalComparer(expected, actual);

            if (externalComparer != null)
            {
                return(externalComparer.AreEqual(expected, actual));
            }

            if (xType.IsArray && yType.IsArray && !compareAsCollection)
            {
                return(ArraysEqual((Array)expected, (Array)actual, ref tolerance));
            }

            if (expected is IDictionary && actual is IDictionary)
            {
                return(DictionariesEqual((IDictionary)expected, (IDictionary)actual, ref tolerance));
            }

            if (expected is IEnumerable && actual is IEnumerable && !(expected is string && actual is string))
            {
                return(EnumerablesEqual((IEnumerable)expected, (IEnumerable)actual, ref tolerance));
            }

            if (expected is string && actual is string)
            {
                return(StringsEqual((string)expected, (string)actual));
            }

            if (expected is Stream && actual is Stream)
            {
                return(StreamsEqual((Stream)expected, (Stream)actual));
            }

            if (expected is DirectoryInfo && actual is DirectoryInfo)
            {
                return(DirectoriesEqual((DirectoryInfo)expected, (DirectoryInfo)actual));
            }

            if (Numerics.IsNumericType(expected) && Numerics.IsNumericType(actual))
            {
                return(Numerics.AreEqual(expected, actual, ref tolerance));
            }

            if (tolerance != null && tolerance.Value is TimeSpan)
            {
                var amount = (TimeSpan)tolerance.Value;

                if (expected is DateTime && actual is DateTime)
                {
                    return(((DateTime)expected - (DateTime)actual).Duration() <= amount);
                }

                if (expected is TimeSpan && actual is TimeSpan)
                {
                    return(((TimeSpan)expected - (TimeSpan)actual).Duration() <= amount);
                }
            }

#if CLR_2_0 || CLR_4_0
            if (FirstImplementsIEquatableOfSecond(xType, yType))
            {
                return(InvokeFirstIEquatableEqualsSecond(expected, actual));
            }
            else if (FirstImplementsIEquatableOfSecond(yType, xType))
            {
                return(InvokeFirstIEquatableEqualsSecond(actual, expected));
            }
#endif

            return(expected.Equals(actual));
        }