예제 #1
0
        private static AggregatedDifference ValueDifferenceEnumerable(IEnumerable firstItem, string firstName,
                                                                      IEnumerable otherItem,
                                                                      ICollection <object> firstSeen)
        {
            if (firstItem.GetType().IsArray&& otherItem.GetType().IsArray)
            {
                return(ValueDifferenceArray(firstItem as Array, firstName, otherItem as Array,
                                            firstSeen));
            }
            if (firstItem is IDictionary firstDico && otherItem is IDictionary secondDico)
            {
                return(ValueDifferenceDictionary(firstDico, firstName, secondDico, firstSeen));
            }
            var valueDifferences = new AggregatedDifference();

            var scanner = otherItem.GetEnumerator();
            var index   = 0;

            foreach (var item in firstItem)
            {
                var firstItemName = $"{firstName}[{index}]";
                if (!scanner.MoveNext())
                {
                    valueDifferences.Add(DifferenceDetails.WasNotExpected(firstItemName, item, index));
                    break;
                }

                valueDifferences.Merge(ValueDifference(item, firstItemName, scanner.Current,
                                                       index, firstSeen));
                index++;
            }

            if (scanner.MoveNext())
            {
                valueDifferences.Add(DifferenceDetails.WasNotFound($"{firstName}[{index}]", scanner.Current, index));
            }

            return(valueDifferences);
        }
예제 #2
0
        private static AggregatedDifference ValueDifferenceDictionary(IReadOnlyDictionary <object, object> sutDictionary,
                                                                      string sutName,
                                                                      IReadOnlyDictionary <object, object> expectedDictionary,
                                                                      ICollection <object> firstItemsSeen)
        {
            var valueDifferences = new AggregatedDifference {
                IsEquivalent = true
            };

            using var actualKeyIterator   = sutDictionary.Keys.GetEnumerator();
            using var expectedKeyIterator = expectedDictionary.Keys.GetEnumerator();
            var stillExpectedKeys = true;
            var stillActualKeys   = true;
            var index             = 0;

            for (;;)
            {
                stillExpectedKeys = stillExpectedKeys && expectedKeyIterator.MoveNext();
                stillActualKeys   = stillActualKeys && actualKeyIterator.MoveNext();
                if (!stillExpectedKeys)
                {
                    // no more expected keys
                    if (!stillActualKeys)
                    {
                        // we're done
                        break;
                    }

                    // the sut has extra key(s)
                    valueDifferences.Add(DifferenceDetails.WasNotExpected(
                                             $"{sutName}[{actualKeyIterator.Current.ToStringProperlyFormatted()}]",
                                             sutDictionary[actualKeyIterator.Current], index));
                    valueDifferences.IsEquivalent = false;
                }
                else if (!stillActualKeys)
                {
                    // key not found
                    valueDifferences.IsEquivalent = false;
                    valueDifferences.Add(DifferenceDetails.WasNotFound(
                                             $"{sutName}[{expectedKeyIterator.Current.ToStringProperlyFormatted()}]",
                                             // ReSharper disable once AssignNullToNotNullAttribute
                                             new DictionaryEntry(expectedKeyIterator.Current,
                                                                 expectedDictionary[expectedKeyIterator.Current]),
                                             0));
                }
                else
                {
                    var actualKey     = actualKeyIterator.Current;
                    var actualKeyName = $"{sutName} key[{index}]";
                    var itemDiffs     = ValueDifference(actualKey,
                                                        actualKeyName,
                                                        expectedKeyIterator.Current,
                                                        index,
                                                        firstItemsSeen);
                    if (!expectedDictionary.TryGetValue(actualKey !, out _))
                    {
                        valueDifferences.Add(DifferenceDetails.WasNotExpected(
                                                 $"{sutName}'s key {actualKey.ToStringProperlyFormatted()}", sutDictionary[actualKey],
                                                 index));
                        valueDifferences.IsEquivalent = false;
                    }
예제 #3
0
        private static AggregatedDifference ScanEnumeration(IEnumerable firstItem, IEnumerable otherItem, Func <int, string> namingCallback, ICollection <object> firstSeen)
        {
            var index                 = 0;
            var mayBeEquivalent       = true;
            var expected              = new List <KeyValuePair <object, int> >();
            var unexpected            = new List <KeyValuePair <object, int> >();
            var aggregatedDifferences = new Dictionary <int, AggregatedDifference>();
            var valueDifferences      = new AggregatedDifference();
            var scanner               = otherItem.GetEnumerator();

            foreach (var item in firstItem)
            {
                var firstItemName = namingCallback(index);
                if (!scanner.MoveNext())
                {
                    valueDifferences.Add(DifferenceDetails.WasNotExpected(firstItemName, item, index));
                    unexpected.Add(new KeyValuePair <object, int>(item, index));
                    break;
                }

                var aggregatedDifference = ValueDifference(item, firstItemName, scanner.Current, index, firstSeen);

                if (aggregatedDifference.IsDifferent)
                {
                    aggregatedDifferences.Add(index, aggregatedDifference);
                    if (!aggregatedDifference.IsEquivalent)
                    {
                        // try to see it was at a different position
                        var indexOrigin = expected.FindIndex(pair => FluentEquivalent(pair.Key, item));
                        if (indexOrigin >= 0)
                        {
                            // we found the value at another index
                            valueDifferences.Add(DifferenceDetails.WasFoundElseWhere(firstItemName, item, index, expected[indexOrigin].Value));
                            expected.RemoveAt(indexOrigin);
                            aggregatedDifferences.Remove(indexOrigin);
                            aggregatedDifferences.Remove(index);
                        }
                        else
                        {
                            unexpected.Add(new KeyValuePair <object, int>(item, index));
                        }

                        // what about the expected value
                        var indexOther = unexpected.FindIndex(pair => FluentEquivalent(pair.Key, scanner.Current));
                        if (indexOther >= 0)
                        {
                            valueDifferences.Add(DifferenceDetails.WasFoundElseWhere(firstItemName, unexpected[indexOther].Key, unexpected[indexOther].Value, index));
                            aggregatedDifferences.Remove(unexpected[indexOther].Value);
                            unexpected.RemoveAt(indexOther);
                        }
                        else
                        {
                            expected.Add(new KeyValuePair <object, int>(scanner.Current, index));
                        }
                    }
                }

                index++;
            }

            if (scanner.MoveNext())
            {
                valueDifferences.Add(DifferenceDetails.WasNotFound(namingCallback(index), scanner.Current, index));
                mayBeEquivalent = false;
            }

            foreach (var differencesValue in aggregatedDifferences.Values)
            {
                valueDifferences.Merge(differencesValue);
            }

            for (var i = 0; i < Math.Min(unexpected.Count, expected.Count); i++)
            {
                //aggregatedDifferences.Remove(unexpected[i].Value);
                valueDifferences.Add(DifferenceDetails.WasFoundInsteadOf(namingCallback(unexpected[i].Value), unexpected[i].Key,
                                                                         expected[i].Key));
            }

            if (mayBeEquivalent && valueDifferences.IsDifferent)
            {
                valueDifferences.IsEquivalent = expected.Count == 0 && unexpected.Count == 0;
            }

            return(valueDifferences);
        }
예제 #4
0
        private static AggregatedDifference ValueDifferenceDictionary(IDictionary sutDico, string sutName,
                                                                      IDictionary expectedDico,
                                                                      ICollection <object> firstItemsSeen)
        {
            var valueDifferences = new AggregatedDifference {
                IsEquivalent = true
            };

            var actualKeyIterator   = sutDico.Keys.GetEnumerator();
            var expectedKeyIterator = expectedDico.Keys.GetEnumerator();
            var stillExpectedKeys   = true;
            var stillActualKeys     = true;
            var index = 0;

            for (;;)
            {
                stillExpectedKeys = stillExpectedKeys && expectedKeyIterator.MoveNext();
                stillActualKeys   = stillActualKeys && actualKeyIterator.MoveNext();
                if (!stillExpectedKeys)
                {
                    // no more expected keys
                    if (!stillActualKeys)
                    {
                        // we're done
                        break;
                    }
                    // the sut has extra key(s)
                    valueDifferences.Add(DifferenceDetails.WasNotExpected($"{sutName}[{actualKeyIterator.Current.ToStringProperlyFormatted()}]", sutDico[actualKeyIterator.Current], index));
                    valueDifferences.IsEquivalent = false;
                }
                else if (!stillActualKeys)
                {
                    // key not found
                    valueDifferences.IsEquivalent = false;
                    valueDifferences.Add(DifferenceDetails.WasNotFound($"{sutName}[{expectedKeyIterator.Current.ToStringProperlyFormatted()}]",
                                                                       expectedDico[expectedKeyIterator.Current],
                                                                       0));
                }
                else
                {
                    var actualKey = actualKeyIterator.Current;
                    var itemDiffs = ValueDifference(actualKey,
                                                    $"{sutName} key[{index}]",
                                                    expectedKeyIterator.Current,
                                                    index,
                                                    firstItemsSeen);
                    if (!itemDiffs.IsDifferent)
                    {
                        // same key, check the values
                        var keyAsString = actualKey.ToStringProperlyFormatted();
                        itemDiffs = ValueDifference(sutDico[actualKey],
                                                    $"{sutName}[{keyAsString}]",
                                                    expectedDico[actualKey],
                                                    index,
                                                    firstItemsSeen);
                        valueDifferences.IsEquivalent &= !itemDiffs.IsDifferent;
                    }
                    else if (valueDifferences.IsEquivalent)
                    {
                        // check if the dictionaries are equivalent anyway
                        valueDifferences.IsEquivalent = expectedDico.Contains(actualKey) &&
                                                        FluentEquals(sutDico[actualKey], expectedDico[actualKey]);
                    }
                    valueDifferences.Merge(itemDiffs);
                }

                index++;
            }
            return(valueDifferences);
        }
예제 #5
0
        private static AggregatedDifference ValueDifferenceDictionary(IReadOnlyDictionary <object, object> sutDico,
                                                                      string sutName,
                                                                      IReadOnlyDictionary <object, object> expectedDico,
                                                                      ICollection <object> firstItemsSeen)
        {
            // TODO: improve error messages
            var valueDifferences = new AggregatedDifference {
                IsEquivalent = true
            };

            var actualKeyIterator   = sutDico.Keys.GetEnumerator();
            var expectedKeyIterator = expectedDico.Keys.GetEnumerator();
            var stillExpectedKeys   = true;
            var stillActualKeys     = true;
            var index = 0;

            for (; ;)
            {
                stillExpectedKeys = stillExpectedKeys && expectedKeyIterator.MoveNext();
                stillActualKeys   = stillActualKeys && actualKeyIterator.MoveNext();
                if (!stillExpectedKeys)
                {
                    // no more expected keys
                    if (!stillActualKeys)
                    {
                        // we're done
                        break;
                    }
                    // the sut has extra key(s)
                    valueDifferences.Add(DifferenceDetails.WasNotExpected($"{sutName}[{actualKeyIterator.Current.ToStringProperlyFormatted()}]", sutDico[actualKeyIterator.Current], index));
                    valueDifferences.IsEquivalent = false;
                }
                else if (!stillActualKeys)
                {
                    // key not found
                    valueDifferences.IsEquivalent = false;
                    valueDifferences.Add(DifferenceDetails.WasNotFound($"{sutName}[{expectedKeyIterator.Current.ToStringProperlyFormatted()}]",
                                                                       expectedDico[expectedKeyIterator.Current],
                                                                       0));
                }
                else
                {
                    var actualKey     = actualKeyIterator.Current;
                    var actualKeyName = $"{sutName} key[{index}]";
                    var itemDiffs     = ValueDifference(actualKey,
                                                        actualKeyName,
                                                        expectedKeyIterator.Current,
                                                        index,
                                                        firstItemsSeen);
                    if (!itemDiffs.IsDifferent)
                    {
                        // same key, check the values
                        itemDiffs = ValueDifference(sutDico[actualKey],
                                                    $"{sutName}[{actualKey.ToStringProperlyFormatted()}]",
                                                    expectedDico[actualKey],
                                                    index,
                                                    firstItemsSeen);
                        valueDifferences.IsEquivalent &= (!itemDiffs.IsDifferent || itemDiffs.IsEquivalent);
                    }
                    else //if (valueDifferences.IsEquivalent)
                    {
                        // check if the dictionaries are equivalent anyway
                        var expectedIndex = expectedDico.ContainsKey(actualKey) ? expectedDico.Keys.ToList().FindIndex(x => x == actualKey) : -1;
                        if (expectedIndex >= 0)
                        {
                            itemDiffs = ValueDifference(sutDico[actualKey],
                                                        $"{sutName}[{actualKey.ToStringProperlyFormatted()}]",
                                                        expectedDico[actualKey],
                                                        index,
                                                        firstItemsSeen);
                            valueDifferences.IsEquivalent &= itemDiffs.IsEquivalent || !itemDiffs.IsDifferent;
                            valueDifferences.Add(
                                DifferenceDetails.WasFoundElseWhere($"{sutName} entry {actualKey.ToStringProperlyFormatted()}", expectedDico[actualKey], index, expectedIndex));
                        }
                        else
                        {
                            valueDifferences.Add(DifferenceDetails.WasNotExpected($"{sutName}'s key {actualKey.ToStringProperlyFormatted()}", sutDico[actualKey], index));
                            valueDifferences.IsEquivalent = false;
                        }
                    }
                    valueDifferences.Merge(itemDiffs);
                }

                index++;
            }
            return(valueDifferences);
        }