Skip to content

Instantly share code, notes, and snippets.

@y-gagar1n
Created December 4, 2017 08:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save y-gagar1n/eef16c7598235a4448a4af55ee5ff3aa to your computer and use it in GitHub Desktop.
Save y-gagar1n/eef16c7598235a4448a4af55ee5ff3aa to your computer and use it in GitHub Desktop.
AssertUtils
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