/// <summary> /// Test the value matched by a prior key match for deep equality /// with another object /// </summary> /// <param name="continuation">Continuation to operate on</param> /// <param name="otherValue">Value to test deep equality against</param> /// <param name="customMessageGenerator">Custom failure message generator</param> /// <typeparam name="T">Type of the dictionary-sourced value</typeparam> /// <returns></returns> public static IMore <T> To <T>( this IDictionaryValueEqual <T> continuation, object otherValue, Func <string> customMessageGenerator) { continuation.AddMatcher(actual => { var isDeep = continuation.GetMetadata( DictionaryValueEqual <T> .DICTIONARY_VALUE_DEEP_EQUALITY_TESTING, true ); var tester = new DeepEqualityTester( actual, otherValue); if (!isDeep) { tester.OnlyTestIntersectingProperties = true; } var passed = tester.AreDeepEqual(); return(new MatcherResult( passed, FinalMessageFor( () => $@"Expected\n{actual.Stringify()}\n{passed.AsNot()}to deep equal\n{otherValue.Stringify()}", customMessageGenerator ) )); }); return(continuation.More()); }
private static void AddCustomComparerersTo( DeepEqualityTester tester, params object[] customEqualityComparers) { ValidateAreComparers(customEqualityComparers); customEqualityComparers.ForEach(tester.AddCustomComparer); }
private static DeepEqualityTester Create(object obj1, object obj2) { var sut = new DeepEqualityTester(obj1, obj2) { RecordErrors = true }; return(sut); }
/// <summary> /// Assert that all the properties for two objects match, deep-tested. Essentially tests /// that all primitive properties are equal and complex ones match shape /// </summary> /// <param name="obj1">Primary object</param> /// <param name="obj2">Object to compare with</param> /// <param name="ignorePropertiesByName">Properties to ignore, by name</param> public static void AreDeepEqual(object obj1, object obj2, params string[] ignorePropertiesByName) { var tester = new DeepEqualityTester(obj1, obj2, ignorePropertiesByName) { IncludeFields = false, RecordErrors = true }; // this is PropertyAssert! if (!tester.AreDeepEqual()) { Assertions.Throw(string.Join("\n", tester.Errors)); } }
/// <summary> /// Runs a deep equality test between two objects, /// ignoring reference differences wherever possible /// and logging failures with the provided action. Properties /// can be explided by name with the ignorePropertiesByName params /// </summary> /// <param name="objSource"></param> /// <param name="objCompare"></param> /// <param name="failureLogAction"></param> /// <param name="ignorePropertiesByName"></param> /// <returns></returns> public static bool DeepEquals(this object objSource, object objCompare, Action <string> failureLogAction, params string[] ignorePropertiesByName) { var tester = new DeepEqualityTester( objSource, objCompare, ignorePropertiesByName) { RecordErrors = true }; var result = tester.AreDeepEqual(); tester.Errors.ForEach(failureLogAction); return(result); }
/// <summary> /// Runs a deep equality test between two objects, using the properties common to both sides /// of the comparison to match on. /// </summary> /// <param name="objSource">Source object to perform comparison against</param> /// <param name="objCompare">Comparison object to compare</param> /// <param name="ignorePropertiesByName">Optional params array of properties to ignore by name</param> /// <returns>True if relevant properties are found and match; false otherwise. If no common properties are found, returns false; caveat: performing this comparison on two vanilla Object() instances will return true.</returns> public static bool DeepIntersectionEquals( this object objSource, object objCompare, params string[] ignorePropertiesByName) { var tester = new DeepEqualityTester( objSource, objCompare, ignorePropertiesByName ) { OnlyTestIntersectingProperties = true }; return(tester.AreDeepEqual()); }
/// <summary> /// Runs a deep equality test between two objects, using the properties on objSource (and children) as /// the set of properties to match on /// </summary> /// <param name="objSource">Source object to perform comparison against</param> /// <param name="objCompare">Comparison object to compare</param> /// <param name="ignorePropertiesByName">Optional params array of properties to ignore by name</param> /// <returns>True if relevant properties are found and match; false otherwise</returns> public static bool DeepSubEquals( this object objSource, object objCompare, params string[] ignorePropertiesByName) { var tester = new DeepEqualityTester( objSource, objCompare, ignorePropertiesByName ) { FailOnMissingProperties = false }; return(tester.AreDeepEqual()); }
private static bool PerformShapeEqualityTesting( object left, object right, bool allowMissingProperties, params string[] ignorePropsByName ) { var tester = new DeepEqualityTester(left, right, ignorePropsByName) { OnlyCompareShape = true, IncludeFields = true, FailOnMissingProperties = !allowMissingProperties }; return(tester.AreDeepEqual()); }
/// <summary> /// Runs a deep equality test between two objects, glossing over reference /// differences between class-types and comparing only primitive types. Use /// this when you'd like to essentially test whether the data in one object /// hierachy matches that of another /// </summary> /// <param name="objSource">Object which is the source of truth</param> /// <param name="objCompare">Object to compare with</param> /// <param name="comparison">Method for comparison</param> /// <param name="ignorePropertiesByName">Params array of properties to ignore by name</param> /// <returns></returns> public static bool DeepEquals( this object objSource, object objCompare, ObjectComparisons comparison, params string[] ignorePropertiesByName ) { var tester = new DeepEqualityTester( objSource, objCompare, ignorePropertiesByName ) { IncludeFields = comparison == ObjectComparisons.PropertiesAndFields }; return(tester.AreDeepEqual()); }
public void GivenObjectsWithDifferentSubShapes_WhenAllowMissingProperties_ButNoMatchedProperties_ShouldThrow() { // Arrange var ours = GetRandom <OurObject>(); var theirs = GetRandom <TheirFrenchObject>(); var tester = new DeepEqualityTester(ours, theirs) { FailOnMissingProperties = false, RecordErrors = true, OnlyCompareShape = true }; // Pre-Assert // Act var result = tester.AreDeepEqual(); // Assert Expect(result).To.Be.False(); Console.WriteLine(tester.Errors.AsText()); }
internal static DeepTestResult AreDeepEqual( object item1, object item2, object[] customEqualityComparers) { var tester = new DeepEqualityTester(item1, item2) { RecordErrors = true, VerbosePropertyMismatchErrors = false, FailOnMissingProperties = true, IncludeFields = true, OnlyTestIntersectingProperties = false }; AddCustomComparerersTo(tester, customEqualityComparers); return(new DeepTestResult( tester.AreDeepEqual(), tester.Errors)); }
public void GivenObjectsWithDifferentTypedButSameShapedProps() { // Arrange var mine = GetRandom <OurObject>(); var theirs = GetRandom <TheirObject>(); var tester = new DeepEqualityTester(mine, theirs) { OnlyCompareShape = true, RecordErrors = true }; // Pre-Assert // Act var result = tester.AreDeepEqual(); // Assert Expect(result) .To.Be.True( tester.Errors.JoinWith("\n") ); }
public void GivenObjectsWithDifferentTypedButSameSubShapedProps() { // Arrange var mine = GetRandom <OurObjectWithSemVer>(); var theirs = GetRandom <TheirObject>(); var tester = new DeepEqualityTester(mine, theirs) { OnlyCompareShape = true, FailOnMissingProperties = false, RecordErrors = true }; // Pre-Assert // Act var result = tester.AreDeepEqual(); // Assert Expect(result) .To.Be.True( tester.Errors.AsText() ); }
/// <summary> /// Assert that common (intersecting) the properties for two objects match, deep-tested. Essentially tests /// that all primitive properties are equal and complex ones match shape /// </summary> /// <param name="obj1"></param> /// <param name="obj2"></param> /// <param name="ignorePropertiesByName"></param> public static void AreIntersectionEqual(object obj1, object obj2, params string[] ignorePropertiesByName) { var propInfos1 = obj1.GetType().GetProperties(); var propInfos2 = obj2.GetType().GetProperties(); var matchingProperties = propInfos1 .Where(pi1 => propInfos2.FirstOrDefault(pi2 => pi1.Name == pi2.Name) != null) .Select(pi => pi.Name); var ignoreProps = propInfos1.Select(pi => pi.Name) .Union(propInfos2.Select(pi => pi.Name)) .Distinct() .Except(matchingProperties) .Union(ignorePropertiesByName) .ToArray(); var tester = new DeepEqualityTester(obj1, obj2, ignoreProps) { RecordErrors = true }; if (tester.AreDeepEqual()) { return; } Assertions.Throw(string.Join("\n", tester.Errors)); }
public static string PrintErrors(this DeepEqualityTester tester) { return(tester.Errors.Any() ? "* " + tester.Errors.JoinWith("\n *") : ""); }