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); }
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); }
/// <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)); }
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); }
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)); }