Skip to content

Commit

Permalink
Removing Should hard reference in favor of embedded code
Browse files Browse the repository at this point in the history
  • Loading branch information
jbogard committed Feb 27, 2013
1 parent e9c862a commit b362e29
Show file tree
Hide file tree
Showing 48 changed files with 4,381 additions and 3 deletions.
Binary file removed lib/Should.dll
Binary file not shown.
940 changes: 940 additions & 0 deletions src/UnitTests/Should/Should.Core/Assertions/Assert.cs

Large diffs are not rendered by default.

860 changes: 860 additions & 0 deletions src/UnitTests/Should/Should.Core/Assertions/Assert.cs.orig

Large diffs are not rendered by default.

102 changes: 102 additions & 0 deletions src/UnitTests/Should/Should.Core/Assertions/AssertComparer.cs
@@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;

namespace Should.Core.Assertions
{
internal class AssertComparer<T> : IComparer<T>
{
public int Compare(T x, T y)
{
Type type = typeof(T);

// Null?
if (!type.IsValueType || (type.IsGenericType && type.GetGenericTypeDefinition().IsAssignableFrom(typeof(Nullable<>))))
{
if (Equals(x, default(T)))
{
return Equals(y, default(T)) ? 0 : 1;
}

if (Equals(y, default(T)))
return -1;
}

var xIsAssignableFromY = x.GetType().IsAssignableFrom(y.GetType());
var yIsAssignableFromX = y.GetType().IsAssignableFrom(x.GetType());

if (!xIsAssignableFromY && !yIsAssignableFromX)
throw new InvalidOperationException(string.Format("Cannot compare objects of type {0} and {1} because neither is assignable from the other.", x.GetType().Name, y.GetType().Name));

// x Implements IComparable<T>?
IComparable<T> comparable1 = x as IComparable<T>;

if (comparable1 != null && xIsAssignableFromY)
return comparable1.CompareTo(y);

// y Implements IComparable<T>?
IComparable<T> comparable2 = y as IComparable<T>;

if (comparable2 != null && yIsAssignableFromX)
return comparable2.CompareTo(x) * -1;

// x Implements IComparable?
IComparable comparable3 = x as IComparable;

if (comparable3 != null && xIsAssignableFromY)
return comparable3.CompareTo(y);

// y Implements IComparable?
IComparable comparable4 = y as IComparable;

if (comparable4 != null && yIsAssignableFromX)
return comparable4.CompareTo(x) *-1;

if (new AssertEqualityComparer<T>().Equals(x, y))
{
return 0;
}

if (xIsAssignableFromY)
{
var result = CompareUsingOperators(x, y, x.GetType());
if (result.HasValue)
{
return result.Value;
}
}

if (yIsAssignableFromX)
{
var result = CompareUsingOperators(x, y, y.GetType());
if (result.HasValue)
{
return result.Value;
}
}

throw new InvalidOperationException(string.Format("Cannot compare objects of type {0} and {1} because neither implements IComparable or IComparable<T> nor overloads comparaison operators.", x.GetType().Name, y.GetType().Name));
}

//Note: Handles edge case of a class where operators are overloaded but niether IComparable or IComparable<T> are implemented
private int? CompareUsingOperators(T x, T y, Type type)
{
var greaterThan = type.GetMethod("op_GreaterThan");
if (greaterThan != null)
{
var lessThan = type.GetMethod("op_LessThan");
return (bool)greaterThan.Invoke(null, new object[] { x, y })
? 1
: (bool)lessThan.Invoke(null, new object[] { x, y }) ? -1 : 0;
}
var greaterThanOrEqual = type.GetMethod("op_GreaterThanOrEqual");
if (greaterThanOrEqual != null)
{
var lessThanOrEqual = type.GetMethod("op_LessThanOrEqual");
return (bool)greaterThanOrEqual.Invoke(null, new object[] { x, y })
? (bool)lessThanOrEqual.Invoke(null, new object[] { x, y }) ? 0 : 1
: -1;
}
return null;
}
}
}
@@ -0,0 +1,51 @@
using System;
using System.Collections;
using System.Collections.Generic;

namespace Should.Core.Assertions
{
internal class AssertEqualityComparer<T> : IEqualityComparer<T>
{
public bool Equals(T x, T y)
{
Type type = typeof(T);

// Null?
if (!type.IsValueType || (type.IsGenericType && type.GetGenericTypeDefinition().IsAssignableFrom(typeof(Nullable<>))))
{
if (Object.Equals(x, default(T)))
return Object.Equals(y, default(T));

if (Object.Equals(y, default(T)))
return false;
}

//x implements IEquitable<T> and is assignable from y?
var xIsAssignableFromY = x.GetType().IsAssignableFrom(y.GetType());
if (xIsAssignableFromY && x is IEquatable<T>)
return ((IEquatable<T>)x).Equals(y);

//y implements IEquitable<T> and is assignable from x?
var yIsAssignableFromX = y.GetType().IsAssignableFrom(x.GetType());
if (yIsAssignableFromX && y is IEquatable<T>)
return ((IEquatable<T>)y).Equals(x);

// Enumerable?
IEnumerable enumerableX = x as IEnumerable;
IEnumerable enumerableY = y as IEnumerable;

if (enumerableX != null && enumerableY != null)
{
return new EnumerableEqualityComparer().Equals(enumerableX, enumerableY);
}

// Last case, rely on Object.Equals
return Object.Equals(x, y);
}

public int GetHashCode(T obj)
{
throw new NotImplementedException();
}
}
}

0 comments on commit b362e29

Please sign in to comment.