3

Closed

Add overload of Assert.Equal(IEnumerable) with key comparer

description

At present, I use the following helper which leverages the collection level diff report to be able to do an order-insensitive sequence comparison:
static class AssertExtensions
{
    public static void SequenceEqual<T, T2>( IEnumerable<T> left, IEnumerable<T> right, Func<T, T2> keySelector, Func<T, T, bool> comparer )
    {
        Assert.Equal( left.OrderBy( keySelector ), right.OrderBy( keySelector ), new FuncEqualityComparer<T>( comparer ) );
    }

    public static void SequenceEqual<T>( IEnumerable<T> left, IEnumerable<T> right )
    {
        Assert.Equal( left.OrderBy( x => x ), right.OrderBy( x => x ) );
    }

    // http://stackoverflow.com/a/3719617
    class FuncEqualityComparer<T> : IEqualityComparer<T>
    {
        readonly Func<T, T, bool> _comparer;
        readonly Func<T, int> _hash;

        public FuncEqualityComparer( Func<T, T, bool> comparer )
            : this( comparer, t => 0 ) // NB Cannot assume anything about how e.g., t.GetHashCode() interacts with the comparer's behavior
        {
        }

        public FuncEqualityComparer( Func<T, T, bool> comparer, Func<T, int> hash )
        {
            _comparer = comparer;
            _hash = hash;
        }

        public bool Equals( T x, T y )
        {
            return _comparer( x, y );
        }

        public int GetHashCode( T obj )
        {
            return _hash( obj );
        }
    }
}
Closed Mar 22 at 11:01 PM by BradWilson

comments

bartelink wrote May 6, 2013 at 8:15 PM

Consider making it as simple as possible by leaning on Tuple.Create as a way to implement a key extractor and skipping impl of equality comparers or Equals lambdas, see http://stackoverflow.com/a/1239337/11635