Created
December 4, 2017 08:53
-
-
Save y-gagar1n/eef16c7598235a4448a4af55ee5ff3aa to your computer and use it in GitHub Desktop.
AssertUtils
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using NUnit.Framework; | |
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace TestUtils | |
{ | |
public static class AssertUtils | |
{ | |
/// <summary> | |
/// "Глубокое" сравнение двух объектов по значению их свойств | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
/// <param name="a"></param> | |
/// <param name="b"></param> | |
/// <returns></returns> | |
public static bool AllPropertiesEqualTo<T>(this T a, T b) | |
{ | |
if (a == null) return b == null; | |
if (b == null) return a == null; | |
if (IsCollection(a.GetType())) return EqualsAsCollection(a, b); | |
if (a.GetType().IsPrimitive) return a.Equals(b); | |
var props = a.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); | |
return props.All(x => x.EqualsOn(a, b)); | |
} | |
public static bool EqualsOn<T>(this PropertyInfo prop, T a, T b) | |
{ | |
object valueA = prop.GetValue(a); | |
object valueB = prop.GetValue(b); | |
if (valueA == null && valueB == null) return true; | |
if (valueA == null || valueB == null) | |
{ | |
ThrowOnPropertyInequality(prop, valueA, valueB); | |
} | |
if (IsCollection(prop.PropertyType)) | |
{ | |
return prop.EqualsAsCollectionOn(a, b); | |
} | |
if (!valueA.Equals(valueB) && !valueA.AllPropertiesEqualTo(valueB)) | |
{ | |
ThrowOnPropertyInequality(prop, valueA, valueB); | |
} | |
return true; | |
} | |
private static void ThrowOnPropertyInequality(PropertyInfo prop, object expectedValue, object actualValue) | |
{ | |
var msg = string.Format("\"{0}\" is not equal. Expected: {1} Actual: {2}", prop.Name, expectedValue ?? "<null>", | |
actualValue ?? "<null>"); | |
throw new AssertionException(msg); | |
} | |
public static bool EqualsAsCollectionOn<T>(this PropertyInfo prop, T a, T b) | |
{ | |
return EqualsAsCollection(prop.GetValue(a), prop.GetValue(b)); | |
} | |
public static bool EqualsAsCollection<T>(T a, T b) | |
{ | |
IEnumerable enumerableA = (IEnumerable) a; | |
IEnumerable enumerableB = (IEnumerable) b; | |
var iterA = enumerableA.GetEnumerator(); | |
var iterB = enumerableB.GetEnumerator(); | |
while (iterA.MoveNext()) | |
{ | |
if (!iterB.MoveNext()) return false; | |
if (!iterA.Current.AllPropertiesEqualTo(iterB.Current)) return false; | |
} | |
if (iterB.MoveNext()) | |
{ | |
return false; | |
} | |
return true; | |
} | |
public static bool IsCollection(Type type) | |
{ | |
return typeof(IEnumerable).IsAssignableFrom(type); | |
} | |
public static bool IsTrue<T>(this T input, Predicate<T> predicate) | |
{ | |
return predicate(input); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment