/// <summary> /// Determines whether properties are initialized or not. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="propertiesContainer">The properties container.</param> /// <param name="trace">The trace.</param> /// <param name="options">The options.</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException"> /// propertiesContainer - Cannot check if properties are initialized on null /// instance /// </exception> // ReSharper disable once ExcessiveIndentation public static bool PropertiesAreInitialized <T>(T propertiesContainer, CheckingTrace trace, PropertiesComparisonOptions options) { if (propertiesContainer == null) { throw new ArgumentNullException(nameof(propertiesContainer), "Cannot check if properties are initialized on null instance"); } var type = propertiesContainer.GetType(); var properties = ObjectComparer.SelectProperties(type.GetProperties(), options.ExcludedProperties); foreach (var propertyName in properties) { var property = type.GetProperty(propertyName); if (options.IgnoreReadOnlyProperties && !property.CanWrite) { continue; } if (property.CanRead) { // Indexed Properties are managed if (property.GetIndexParameters().Length == 0) { var value = property.GetValue(propertiesContainer, null); trace.PushProperty(type, property.PropertyType, propertyName); if (!IsFilled(value, trace, options)) { return(false); } trace.Pop(); } } } return(true); }
private static bool ListsAreEqual(IList tested, IList expected, PropertiesComparisonOptions options, CheckingTrace trace) { if (expected != null) { if (tested == null) { trace.SetFailure($"Tested list is null but expected list {expected.ShortDisplay()} is not null"); return(false); } if (tested.Count != expected.Count) { trace.SetFailure( $"Tested list {tested.ShortDisplay()} has not same number of element that expected list {expected.ShortDisplay()}"); return(false); } for (var i = 0; i < expected.Count; ++i) { trace.PushIndex(expected.GetType(), i); if (!ObjectsAreEqual(expected[i], tested[i], options, trace)) { return(false); } trace.Pop(); } return(true); } if (tested != null) { trace.SetFailure($"Tested list {tested.ShortDisplay()} is not null but expecting null list"); return(false); } return(true); }
/// <summary> /// Determines whether the specified to check is filled. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="tested">To check.</param> /// <param name="trace">The trace.</param> /// <param name="options">The options.</param> /// <returns> /// <c>true</c> if the specified to check is filled; otherwise, <c>false</c>. /// </returns> // ReSharper disable once ExcessiveIndentation private static bool IsFilled <T>(T tested, CheckingTrace trace, PropertiesComparisonOptions options) { if (tested != null) { var testedType = tested.GetType(); if (testedType.GetTypeInfo().IsValueType) { if (testedType == typeof(bool)) { if ((bool)(object)tested == false) { trace.SetFailure("Tested is false but expected is true."); return(false); } return(true); } if (testedType == typeof(TimeSpan)) { decimal val = Convert <TimeSpan>(tested).Ticks; if (val == 0) { trace.SetFailure("Tested TimeSpan is uninitialized."); return(false); } return(true); } if (!IsInitialized(tested)) { trace.SetFailure($"Tested {testedType} is uninitialized."); return(false); } return(true); } if (testedType == typeof(string)) { var value = Convert <string>(tested); if (value.Length == 0) { trace.SetFailure($"Tested string is empty."); return(false); } } else { PropertiesAreInitialized(tested, trace, options); } } else { trace.SetFailure($"Checked {typeof(T)} is null"); return(false); } return(true); }
/// <summary> /// Determines whether objects are equal. /// </summary> /// <param name="tested">The tested.</param> /// <param name="expected">The expected.</param> /// <param name="options">The options.</param> /// <param name="trace">The trace.</param> /// <returns></returns> public static bool ObjectsAreEqual(object tested, object expected, PropertiesComparisonOptions options, CheckingTrace trace) { if (expected != null) { var expectedType = expected.GetType(); if (tested == null) { trace.SetFailure($"Tested value is null but expected {expectedType}:{expected} is not null."); return(false); } var testedType = tested.GetType(); if (testedType != expectedType) { trace.SetFailure($"Tested type {testedType} is not the expected {expectedType}."); return(false); } if (expectedType.GetTypeInfo().IsValueType || expectedType == typeof(string) || expectedType == typeof(Type)) { if (!expected.Equals(tested)) { trace.SetFailure($"Tested value {tested} is not the expected {expected}."); return(false); } } else { if (typeof(IList).IsAssignableFrom(expectedType)) { return(ListsAreEqual((IList)tested, (IList)expected, options, trace)); } // Manage other types return(PropertiesAreEqual(tested, expected, trace, options)); } } else { if (tested != null) { var type = tested.GetType(); trace.SetFailure($"Tested {type}:{tested} is not null but expecting null."); return(false); } } return(true); }
private static bool PropertiesAreEqual(object expected, object tested, IEnumerable <string> properties, PropertiesComparisonOptions comparisonOptions, CheckingTrace trace) { foreach (var propertyName in properties) { if (propertyName == "SyncRoot") { continue; } var expectedType = expected.GetType(); // get property infos var expectedProperty = expectedType.GetProperty(propertyName); var getter = expectedProperty.GetGetMethod(); if (getter == null || getter.IsStatic) { // no getter, or static continue; } var testedType = tested.GetType(); var testedProperty = testedType.GetProperty(expectedProperty.Name); if (testedProperty == null) { trace.SetFailure( $"{testedType}:{tested} has not the expected property {expectedProperty.Name} of {expectedType}"); return(false); } // compare values if (expectedProperty.CanRead && testedProperty.CanRead) { if (expectedProperty.GetIndexParameters().Length != 0) { continue; } var expectedValue = expectedProperty.GetValue(expected, null); var testedValue = testedProperty.GetValue(tested, null); trace.PushProperty(expectedType, expectedProperty.PropertyType, expectedProperty.Name); if (!ObjectsAreEqual(expectedValue, testedValue, comparisonOptions, trace)) { return(false); } trace.Pop(); } } return(true); }
/// <summary> /// Determines whether properties are equal. /// </summary> /// <param name="tested">The tested.</param> /// <param name="expected">The expected.</param> /// <param name="trace">The trace.</param> /// <param name="comparisonOptions">The comparison options.</param> /// <returns></returns> public static bool PropertiesAreEqual(object tested, object expected, CheckingTrace trace, PropertiesComparisonOptions comparisonOptions) { var expectedType = expected.GetType(); var testedType = tested.GetType(); var expectedLength = expectedType.GetProperties().Length; var testedLength = testedType.GetProperties().Length; if (expectedLength != testedLength && comparisonOptions.CheckForNumberOfProperties) { trace.SetFailure( $"Tested {testedType}[{testedLength}] has not the same number of properties as expected {expectedType}[{expectedLength}]"); return(false); } trace.Push(expectedType); var collection = SelectProperties(expectedType.GetProperties(), comparisonOptions.ExcludedProperties); return(PropertiesAreEqual(expected, tested, collection, comparisonOptions, trace)); }