public bool AreDeepEqual(object a, object b, DeepComparisonOptions comparisonOptions)
        {
            if (a == null && b == null)
            {
                return(true);
            }
            if (a == null || b == null)
            {
                return(false);
            }
            if (a.GetType() != b.GetType())
            {
                return(false);
            }
            if (ReferenceEquals(a, b))
            {
                return(true);
            }
            if (comparisonOptions == null)
            {
                throw new ArgumentNullException(nameof(comparisonOptions));
            }
            if (comparisonOptions.DeepEqualityComparers == null || !comparisonOptions.DeepEqualityComparers.Any())
            {
                throw new InvalidOperationException($"There were no comparers provided to use for comparing the objects.");
            }
            if (TryGetComparer(comparisonOptions.DeepEqualityComparers, a.GetType(), out var comparer))
            {
                return(comparer.AreDeepEqual(a, b, comparisonOptions));
            }

            throw new InvalidOperationException($"There were no comparers able to compare objects of type {a.GetType().FullName}.");
        }
        public void AreDeepEqual_SameObjectTypes_DifferentObjects_DeepEqualityComparerAvailable_ReturnsTrue()
        {
            // Arrange
            var service = CreateService();
            var objA    = new MockStruct();
            var objB    = new MockStruct();

            var mockComparer = new Mock <IDeepEqualityComparer>();

            mockComparer.Setup(m => m.CanCompare(It.IsAny <Type>()))
            .Returns(true);
            mockComparer.Setup(m =>
                               m.AreDeepEqual(It.IsAny <object>(), It.IsAny <object>(), It.IsAny <DeepComparisonOptions>()))
            .Returns(true);

            var options = new DeepComparisonOptions()
            {
                DeepEqualityComparers = new List <IDeepEqualityComparer>()
                {
                    mockComparer.Object
                }
            };

            // Act
            var result = service.AreDeepEqual(objA, objB, options);

            // Assert
            Assert.True(result);
        }
        /// <summary>
        /// Performs a deep comparison between <see cref="objA"/> and <see cref="objB"/>.
        /// </summary>
        /// <param name="objA">The first object to compare</param>
        /// <param name="objB">The second object to compare against <see cref="objA"/></param>
        /// <param name="comparisonOptions">The specific comparison rules to use when comparing certain types of objects</param>
        /// <returns>True/False for whether the objects are deeply equal to each other</returns>
        public static bool DeepEquals(this object objA, object objB, DeepComparisonOptions comparisonOptions)
        {
            if (comparisonOptions == null)
            {
                throw new ArgumentNullException(nameof(comparisonOptions));
            }

            var scopeProvider    = ComparisonScopeProvider ?? new ComparisonScopeProvider();
            var scopedComparison = scopeProvider.CreateScope(objA, objB, comparisonOptions);

            return(scopedComparison.Compare());
        }
        public void AreDeepEqual_SameObjectTypes_DifferentObjects_ComparisonOptionsEmptyComparers_ThrowsInvalidOperationException()
        {
            // Arrange
            var service = CreateService();
            var objA    = new MockStruct();
            var objB    = new MockStruct();
            var options = new DeepComparisonOptions()
            {
                DeepEqualityComparers = new List <IDeepEqualityComparer>()
            };

            // Act/Assert
            Assert.Throws <InvalidOperationException>(() => service.AreDeepEqual(objA, objB, options));
        }
        public void AreDeepEqual_CaseInsensitive_StringVariations_ReturnsExpectedResult(string a, string b, bool expectedResult)
        {
            // Arrange
            var comparer = CreateComparer();
            var options  = new DeepComparisonOptions()
            {
                IgnoreCaseSensitivity = true
            };

            // Act
            var result = comparer.AreDeepEqual(a, b, options);

            // Assert
            Assert.Equal(expectedResult, result);
        }
Пример #6
0
        public void CreateScope_ValidComparisonService_ReturnsScopeComparisonWithObjects()
        {
            // Arrange
            var provider = CreateProvider();
            var objA     = new object();
            var objB     = 2;
            var options  = new DeepComparisonOptions();

            // Act
            var result = provider.CreateScope(objA, objB, options);

            // Assert
            Assert.NotNull(result);
            Assert.Equal(objA, result.A);
            Assert.Equal(objB, result.B);
            Assert.NotNull(result.DeepComparisonService);
            Assert.Equal(options, result.ComparisonOptions);
        }
        public void DeepEquals_OptionsProvided_RunsSuccessfully()
        {
            // Arrange
            var obj = new object();
            var comparisonOptions = new DeepComparisonOptions()
            {
                DeepEqualityComparers = new List <IDeepEqualityComparer>()
                {
                    new BooleanComparer(),
                    new PropertyComparer()
                },
                IgnoreCaseSensitivity     = true,
                EnforceEnumerableOrdering = false
            };

            var mockComparisonService = new Mock <IDeepComparisonService>();

            mockComparisonService.Setup(m =>
                                        m.AreDeepEqual(It.IsAny <object>(), It.IsAny <object>(), It.IsAny <DeepComparisonOptions>()))
            .Returns((object objA, object objB, DeepComparisonOptions options) =>
                     options.IgnoreCaseSensitivity == comparisonOptions.IgnoreCaseSensitivity &&
                     options.EnforceEnumerableOrdering == comparisonOptions.EnforceEnumerableOrdering &&
                     options.DeepEqualityComparers.SequenceEqual(comparisonOptions.DeepEqualityComparers));

            var mockScopeProvider = new Mock <IComparisonScopeProvider>();

            mockScopeProvider.Setup(m => m.CreateScope(It.IsAny <object>(), It.IsAny <object>(), It.IsAny <DeepComparisonOptions>()))
            .Returns((object o, object o2, DeepComparisonOptions options) => new ScopedComparison()
            {
                ComparisonOptions     = options,
                DeepComparisonService = mockComparisonService.Object
            });

            ObjectExtensions.ComparisonScopeProvider = mockScopeProvider.Object;

            // Act
            var result = obj.DeepEquals(new object(), comparisonOptions);

            // Assert
            Assert.True(result);
        }
Пример #8
0
        /// <inheritdoc />
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="InvalidOperationException"></exception>
        public bool AreDeepEqual(object a, object b, DeepComparisonOptions deepComparisonOptions)
        {
            if (a == null)
            {
                throw new ArgumentNullException(nameof(a));
            }
            if (b == null)
            {
                throw new ArgumentNullException(nameof(b));
            }
            if (a.GetType() != b.GetType())
            {
                throw new InvalidOperationException($"Both objects must be the same type. First object is of type {a.GetType().FullName}. Second object is of type {b.GetType().FullName}.");
            }
            if (!CanCompare(a.GetType()))
            {
                throw new InvalidOperationException($"Comparer, of type {GetType().FullName}, is unable to compare objects of type {a.GetType().FullName}.");
            }

            DeepComparisonOptions = deepComparisonOptions ?? throw new ArgumentNullException(nameof(deepComparisonOptions));
            return(AreDeepEqual(a, b));
        }
Пример #9
0
        public void AreDeepEqual_List_OrderEnforced_Unordered_SameValues_ReturnsFalse()
        {
            // Arrange
            var testSet1 = new List <string>()
            {
                "Test",
                "Hello",
                "Amazing",
                "World"
            };
            var testSet2 = new List <string>()
            {
                "Test",
                "Hello",
                "World",
                "Amazing"
            };
            var comparer = CreateComparer();

            MockComparerTestSetup.SetupComparer(comparer, (objA, objB, _) =>
            {
                var s1 = (string)objA;
                var s2 = (string)objB;

                return(s1.Equals(s2, StringComparison.OrdinalIgnoreCase));
            });

            var options = new DeepComparisonOptions()
            {
                EnforceEnumerableOrdering = true
            };

            // Act
            var result = comparer.AreDeepEqual(testSet1, testSet2, options);

            // Assert
            Assert.False(result);
        }
Пример #10
0
        public void AreDeepEqual_Array_OrderNotEnforced_Ordered_SameValues_ReturnsTrue()
        {
            // Arrange
            var testSet1 = new[]
            {
                1,
                12,
                3,
                7
            };
            var testSet2 = new[]
            {
                1,
                12,
                3,
                7
            };
            var comparer = CreateComparer();

            MockComparerTestSetup.SetupComparer(comparer, (objA, objB, _) =>
            {
                var int1 = (int)objA;
                var int2 = (int)objB;

                return(int1 == int2);
            });

            var options = new DeepComparisonOptions()
            {
                EnforceEnumerableOrdering = false
            };

            // Act
            var result = comparer.AreDeepEqual(testSet1, testSet2, options);

            // Assert
            Assert.True(result);
        }
        public ScopedComparison CreateScope(object objA, object objB, DeepComparisonOptions options)
        {
            var configuration = new ComparerConfiguration()
            {
                DeepComparisonService    = new DeepComparisonService(),
                PropertyCache            = new PropertyCache(),
                ObjectCache              = new ObjectCache(),
                CircularReferenceMonitor = new CircularReferenceMonitor()
            };

            foreach (var comparer in options.DeepEqualityComparers)
            {
                comparer.SetConfiguration(configuration);
            }

            return(new ScopedComparison()
            {
                A = objA,
                B = objB,
                ComparisonOptions = options,
                DeepComparisonService = configuration.DeepComparisonService
            });
        }
        public void AreDeepEqual_SameObjectTypes_DifferentObjects_NoDeepEqualityComparersOfTheGivenObjectType_ThrowsInvalidOperationException()
        {
            // Arrange
            var service = CreateService();
            var objA    = new MockStruct();
            var objB    = new MockStruct();

            var mockComparer = new Mock <IDeepEqualityComparer>();

            mockComparer.Setup(m => m.CanCompare(It.IsAny <Type>()))
            .Returns(false);

            var options = new DeepComparisonOptions()
            {
                DeepEqualityComparers = new List <IDeepEqualityComparer>()
                {
                    mockComparer.Object
                }
            };

            // Act/Assert
            Assert.Throws <InvalidOperationException>(() => service.AreDeepEqual(objA, objB, options));
        }
        /// <summary>
        /// Performs a deep comparison between <see cref="objA"/> and <see cref="objB"/> using the default <see cref="DeepComparisonOptions"/>
        /// </summary>
        /// <param name="objA">The first object to compare</param>
        /// <param name="objB">The second object to compare against <see cref="objA"/></param>
        /// <returns>True/False for whether the objects are deeply equal to each other</returns>
        public static bool DeepEquals(this object objA, object objB)
        {
            var options = new DeepComparisonOptions();

            return(objA.DeepEquals(objB, options));
        }