Example #1
0
        private static AggregatedDifference ValueDifference <TA, TE>(TA actual, string firstName, TE expected, int refIndex, ICollection <object> firstSeen)
        {
            var result = new AggregatedDifference();

            if (expected == null)
            {
                if (actual != null)
                {
                    result.Add(DifferenceDetails.DoesNotHaveExpectedValue(firstName, actual, expected, refIndex));
                }

                return(result);
            }

            if (expected.Equals(actual))
            {
                return(result);
            }

            if (actual != null)
            {
                var commonType = actual.GetType().FindCommonNumericalType(expected.GetType());
                // we silently convert numerical value
                if (commonType != null)
                {
                    var convertedActual   = Convert.ChangeType(actual, commonType);
                    var convertedExpected = Convert.ChangeType(expected, commonType);
                    if (convertedExpected.Equals(convertedActual))
                    {
                        return(result);
                    }
                }

                if (firstSeen.Contains(actual))
                {
                    result.Add(DifferenceDetails.DoesNotHaveExpectedValue(firstName, actual, expected, 0));
                    return(result);
                }

                firstSeen = new List <object>(firstSeen)
                {
                    actual
                };

                if (actual.IsAnEnumeration(false) && expected.IsAnEnumeration(false))
                {
                    return(ValueDifferenceEnumerable(actual as IEnumerable, firstName, expected as IEnumerable, firstSeen));
                }
            }

            result.Add(DifferenceDetails.DoesNotHaveExpectedValue(firstName, actual, expected, refIndex));
            return(result);
        }
Example #2
0
        private static AggregatedDifference NumericalValueDifference <TA, TE>(TA actual, string firstName, TE expected,
                                                                              int refIndex, Type commonType, AggregatedDifference result)
        {
            var convertedActual   = Convert.ChangeType(actual, commonType);
            var convertedExpected = Convert.ChangeType(expected, commonType);

            if (convertedExpected.Equals(convertedActual))
            {
                return(result);
            }

            result.Add(DifferenceDetails.DoesNotHaveExpectedValue(firstName, actual, expected, refIndex));
            return(result);
        }
Example #3
0
        private static AggregatedDifference ValueDifferenceArray(Array firstArray, string firstName, Array secondArray, ICollection <object> firstSeen)
        {
            var valueDifferences = new AggregatedDifference();

            if (firstArray.Rank != secondArray.Rank)
            {
                valueDifferences.Add(DifferenceDetails.DoesNotHaveExpectedValue(firstName + ".Rank", firstArray.Rank, secondArray.Rank, 0));
                return(valueDifferences);
            }
            for (var i = 0; i < firstArray.Rank; i++)
            {
                if (firstArray.SizeOfDimension(i) == secondArray.SizeOfDimension(i))
                {
                    continue;
                }

                valueDifferences.Add(DifferenceDetails.DoesNotHaveExpectedValue($"{firstName}.Dimension({i})",
                                                                                firstArray.SizeOfDimension(i),
                                                                                secondArray.SizeOfDimension(i),
                                                                                i));
                return(valueDifferences);
            }

            var indices       = new int[firstArray.Rank];
            var secondIndices = new int[secondArray.Rank];

            for (var i = 0; i < firstArray.Length; i++)
            {
                var temp  = i;
                var label = new StringBuilder("[");
                for (var j = 0; j < firstArray.Rank; j++)
                {
                    var currentIndex = temp % firstArray.SizeOfDimension(j);
                    label.Append(currentIndex.ToString());
                    label.Append(j < firstArray.Rank - 1 ? "," : "]");
                    indices[j]       = currentIndex + firstArray.GetLowerBound(j);
                    secondIndices[j] = currentIndex + secondArray.GetLowerBound(j);
                    temp            /= firstArray.SizeOfDimension(j);
                }

                var firstEntry  = firstArray.GetValue(indices);
                var secondEntry = secondArray.GetValue(secondIndices);
                valueDifferences.Merge(ValueDifference(firstEntry, firstName + label, secondEntry, i, firstSeen));
            }

            return(valueDifferences);
        }
Example #4
0
        /// <summary>
        ///     Check Equality between actual and expected and provides details regarding differences, if any.
        /// </summary>
        /// <remarks>
        ///     Is recursive.
        ///     Algorithm focuses on value comparison, to better match expectations. Here is a summary of the logic:
        ///     1. deals with expected = null case
        ///     2. tries Equals, if success, values are considered equals
        ///     3. if there is recursion (self referencing object), values are assumed as different
        ///     4. if both values are numerical, compare them after conversion if needed.
        ///     5. if expected is an anonymous type, use a property based comparison
        ///     6. if both are enumerations, perform enumeration comparison
        ///     7. report values as different.
        /// </remarks>
        /// <typeparam name="TA">type of the actual value</typeparam>
        /// <typeparam name="TE">type of the expected value</typeparam>
        /// <param name="actual">actual value</param>
        /// <param name="firstName">name/label to use for messages</param>
        /// <param name="expected">expected value</param>
        /// <param name="refIndex">reference index (for collections)</param>
        /// <param name="firstSeen">track recursion</param>
        /// <returns></returns>
        private static AggregatedDifference ValueDifference <TA, TE>(TA actual, string firstName, TE expected,
                                                                     int refIndex, ICollection <object> firstSeen)
        {
            var result = new AggregatedDifference();

            // handle null case first
            if (expected == null)
            {
                if (actual != null)
                {
                    result.Add(DifferenceDetails.DoesNotHaveExpectedValue(firstName, actual, null, refIndex));
                }

                return(result);
            }

            // if both equals from a BCL perspective, we are done.
            if (EqualityHelper.CustomEquals(expected, actual))
            {
                return(result);
            }

            // handle actual is null
            if (actual == null)
            {
                result.Add(DifferenceDetails.DoesNotHaveExpectedValue(firstName, null, expected, refIndex));
                return(result);
            }

            // do not recurse
            if (firstSeen.Contains(actual))
            {
                result.Add(DifferenceDetails.DoesNotHaveExpectedValue(firstName, actual, expected, 0));
                return(result);
            }

            firstSeen = new List <object>(firstSeen)
            {
                actual
            };

            // deals with numerical
            var type       = expected.GetType();
            var commonType = actual.GetType().FindCommonNumericalType(type);

            // we silently convert numerical values
            if (commonType != null)
            {
                return(NumericalValueDifference(actual, firstName, expected, refIndex, commonType, result));
            }

            if (type.TypeIsAnonymous())
            {
                return(AnonymousTypeDifference(actual, expected, type, result));
            }

            // handle enumeration
            if (actual.IsAnEnumeration(false) && expected.IsAnEnumeration(false))
            {
                return(ValueDifferenceEnumerable(actual as IEnumerable, firstName, expected as IEnumerable, firstSeen));
            }

            result.Add(DifferenceDetails.DoesNotHaveExpectedValue(firstName, actual, expected, refIndex));
            return(result);
        }