/// <summary> /// Flag the constraint to use the supplied predicate function /// </summary> /// <param name="comparison">The comparison function to use.</param> /// <returns>Self.</returns> public DictionaryContainsValueConstraint Using <TCollectionType, TMemberType>(Func <TCollectionType, TMemberType, bool> comparison) { // reverse the order of the arguments to match expectations of PredicateEqualityComparer Func <TMemberType, TCollectionType, bool> invertedComparison = (actual, expected) => comparison.Invoke(expected, actual); base.Using(EqualityAdapter.For(invertedComparison)); return(this); }
/// <summary> /// Flag the constraint to use the supplied predicate function /// </summary> /// <param name="comparison">The comparison function to use.</param> /// <returns>Self.</returns> public CollectionSupersetConstraint Using <TSupersetType, TSubsetType>(Func <TSupersetType, TSubsetType, bool> comparison) { // internal code reverses the expected order of the arguments. Func <TSubsetType, TSupersetType, bool> invertedComparison = (actual, expected) => comparison.Invoke(expected, actual); base.Using(EqualityAdapter.For(invertedComparison)); return(this); }
public static IEnumerable <EqualityAdapter> EqualityAdapters() { return(new[] { EqualityAdapter.For((IEqualityComparer)StringComparer.Ordinal), EqualityAdapter.For((IEqualityComparer <string>)StringComparer.Ordinal), EqualityAdapter.For <string, string>(StringComparer.Ordinal.Equals), EqualityAdapter.For((IComparer)StringComparer.Ordinal), EqualityAdapter.For((IComparer <string>)StringComparer.Ordinal), EqualityAdapter.For <string>(StringComparer.Ordinal.Compare) }); }
internal bool AreEqual(object x, object y, ref Tolerance tolerance, ComparisonState state) { this._failurePoints = new List <FailurePoint>(); if (x == null && y == null) { return(true); } if (x == null || y == null) { return(false); } if (object.ReferenceEquals(x, y)) { return(true); } if (state.DidCompare(x, y)) { return(false); } EqualityAdapter externalComparer = GetExternalComparer(x, y); if (externalComparer != null) { return(externalComparer.AreEqual(x, y)); } foreach (EqualMethod equalMethod in _comparers) { bool?result = equalMethod(x, y, ref tolerance, state, this); if (result.HasValue) { return(result.Value); } } return(x.Equals(y)); }
/// <summary> /// Compares two objects for equality within a tolerance. /// </summary> public bool AreEqual(object x, object y, ref Tolerance tolerance, bool topLevelComparison = true) { this.failurePoints = new List <FailurePoint>(); if (x == null && y == null) { return(true); } if (x == null || y == null) { return(false); } if (object.ReferenceEquals(x, y)) { return(true); } EqualityAdapter externalComparer = GetExternalComparer(x, y); if (externalComparer != null) { return(externalComparer.AreEqual(x, y)); } foreach (IChainComparer comparer in _comparers) { bool?result = comparer.Equal(x, y, ref tolerance, topLevelComparison); if (result.HasValue) { return(result.Value); } } return(x.Equals(y)); }
/// <summary> /// Flag the constraint to use the supplied IEqualityComparer object. /// </summary> /// <param name="comparer">The IComparer object to use.</param> /// <returns>Self.</returns> public EqualConstraint Using <T>(IEqualityComparer <T> comparer) { _comparer.ExternalComparers.Add(EqualityAdapter.For(comparer)); return(this); }
/// <summary> /// Flag the constraint to use the supplied predicate function /// </summary> /// <param name="comparison">The comparison function to use.</param> /// <returns>Self.</returns> public EqualConstraint Using <TCollectionType, TMemberType>(Func <TCollectionType, TMemberType, bool> comparison) { _comparer.ExternalComparers.Add(EqualityAdapter.For(comparison)); return(this); }
/// <summary> /// Compares two objects for equality within a tolerance. /// </summary> public bool AreEqual(object x, object y, ref Tolerance tolerance) { this.failurePoints = new ArrayList(); if (x == null && y == null) { return(true); } if (x == null || y == null) { return(false); } if (object.ReferenceEquals(x, y)) { return(true); } Type xType = x.GetType(); Type yType = y.GetType(); EqualityAdapter externalComparer = GetExternalComparer(x, y); if (externalComparer != null) { return(externalComparer.AreEqual(x, y)); } if (xType.IsArray && yType.IsArray && !compareAsCollection) { return(ArraysEqual((Array)x, (Array)y, ref tolerance)); } if (x is IDictionary && y is IDictionary) { return(DictionariesEqual((IDictionary)x, (IDictionary)y, ref tolerance)); } //if (x is ICollection && y is ICollection) // return CollectionsEqual((ICollection)x, (ICollection)y, ref tolerance); if (x is IEnumerable && y is IEnumerable && !(x is string && y is string)) { return(EnumerablesEqual((IEnumerable)x, (IEnumerable)y, ref tolerance)); } if (x is string && y is string) { return(StringsEqual((string)x, (string)y)); } if (x is Stream && y is Stream) { return(StreamsEqual((Stream)x, (Stream)y)); } if (x is DirectoryInfo && y is DirectoryInfo) { return(DirectoriesEqual((DirectoryInfo)x, (DirectoryInfo)y)); } if (Numerics.IsNumericType(x) && Numerics.IsNumericType(y)) { return(Numerics.AreEqual(x, y, ref tolerance)); } if (tolerance != null && tolerance.Value is TimeSpan) { TimeSpan amount = (TimeSpan)tolerance.Value; if (x is DateTime && y is DateTime) { return(((DateTime)x - (DateTime)y).Duration() <= amount); } if (x is TimeSpan && y is TimeSpan) { return(((TimeSpan)x - (TimeSpan)y).Duration() <= amount); } } #if CLR_2_0 || CLR_4_0 if (FirstImplementsIEquatableOfSecond(xType, yType)) { return(InvokeFirstIEquatableEqualsSecond(x, y)); } else if (FirstImplementsIEquatableOfSecond(yType, xType)) { return(InvokeFirstIEquatableEqualsSecond(y, x)); } #endif return(x.Equals(y)); }
/// <summary> /// Flag the constraint to use the supplied boolean-returning delegate. /// </summary> /// <param name="comparer">The boolean-returning delegate to use.</param> /// <returns>Self.</returns> public EqualConstraint Using <T>(Func <T, T, bool> comparer) { _comparer.ExternalComparers.Add(EqualityAdapter.For(comparer)); return(this); }
/// <summary> /// Flag the constraint to use the supplied Comparison object. /// </summary> /// <param name="comparer">The IComparer object to use.</param> /// <returns>Self.</returns> public EqualConstraint Using <T>(Comparison <T> comparer) { this.comparer.ExternalComparer = EqualityAdapter.For(comparer); return(this); }
public static void CanCompareWithNull(EqualityAdapter adapter) { Assert.That(adapter.AreEqual(null, "a"), Is.False); Assert.That(adapter.AreEqual("a", null), Is.False); Assert.That(adapter.AreEqual(null, null), Is.True); }
/// <summary> /// Flag the constraint to use the supplied IComparer object. /// </summary> /// <param name="comparer">The IComparer object to use.</param> /// <returns>Self.</returns> public EqualConstraint Using(IComparer comparer) { this.comparer.ExternalComparers.Add(EqualityAdapter.For(comparer)); return(this); }
/// <summary> /// Flag the constraint to use the supplied predicate function /// </summary> /// <param name="comparison">The comparison function to use.</param> /// <returns>Self.</returns> public CollectionSubsetConstraint Using <TSubsetType, TSupersetType>(Func <TSubsetType, TSupersetType, bool> comparison) { base.Using(EqualityAdapter.For(comparison)); return(this); }
/// <summary> /// Flag the constraint to use the supplied predicate function /// </summary> /// <param name="comparison">The comparison function to use.</param> /// <returns>Self.</returns> public CollectionEquivalentConstraint Using <TActual, TExpected>(Func <TActual, TExpected, bool> comparison) { base.Using(EqualityAdapter.For(comparison)); return(this); }
private bool ObjectsEqual(object expected, object actual, ref Tolerance tolerance) { if (expected == null && actual == null) { return(true); } if (expected == null || actual == null) { return(false); } if (object.ReferenceEquals(expected, actual)) { return(true); } Type xType = expected.GetType(); Type yType = actual.GetType(); EqualityAdapter externalComparer = GetExternalComparer(expected, actual); if (externalComparer != null) { return(externalComparer.AreEqual(expected, actual)); } if (xType.IsArray && yType.IsArray && !compareAsCollection) { return(ArraysEqual((Array)expected, (Array)actual, ref tolerance)); } if (expected is IDictionary && actual is IDictionary) { return(DictionariesEqual((IDictionary)expected, (IDictionary)actual, ref tolerance)); } // Issue #70 - EquivalentTo isn't compatible with IgnoreCase for dictionaries if (expected is DictionaryEntry && actual is DictionaryEntry) { return(DictionaryEntriesEqual((DictionaryEntry)expected, (DictionaryEntry)actual, ref tolerance)); } #if CLR_2_0 || CLR_4_0 // IDictionary<,> will eventually try to compare it's key value pairs when using CollectionTally if (xType.IsGenericType && xType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>) && yType.IsGenericType && yType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>)) { Tolerance keyTolerance = new Tolerance(0); object xKey = xType.GetProperty("Key").GetValue(expected, null); object yKey = yType.GetProperty("Key").GetValue(actual, null); object xValue = xType.GetProperty("Value").GetValue(expected, null); object yValue = yType.GetProperty("Value").GetValue(actual, null); return(AreEqual(xKey, yKey, ref keyTolerance) && AreEqual(xValue, yValue, ref tolerance)); } #endif if (expected is IEnumerable && actual is IEnumerable && !(expected is string && actual is string)) { return(EnumerablesEqual((IEnumerable)expected, (IEnumerable)actual, ref tolerance)); } if (expected is string && actual is string) { return(StringsEqual((string)expected, (string)actual)); } if (expected is Stream && actual is Stream) { return(StreamsEqual((Stream)expected, (Stream)actual)); } if (expected is char && actual is char) { return(CharsEqual((char)expected, (char)actual)); } if (expected is DirectoryInfo && actual is DirectoryInfo) { return(DirectoriesEqual((DirectoryInfo)expected, (DirectoryInfo)actual)); } if (Numerics.IsNumericType(expected) && Numerics.IsNumericType(actual)) { return(Numerics.AreEqual(expected, actual, ref tolerance)); } if (tolerance != null && tolerance.Value is TimeSpan) { TimeSpan amount = (TimeSpan)tolerance.Value; if (expected is DateTime && actual is DateTime) { return(((DateTime)expected - (DateTime)actual).Duration() <= amount); } #if CLR_2_0 || CLR_4_0 if (expected is DateTimeOffset && actual is DateTimeOffset) { return(((DateTimeOffset)expected - (DateTimeOffset)actual).Duration() <= amount); } #endif if (expected is TimeSpan && actual is TimeSpan) { return(((TimeSpan)expected - (TimeSpan)actual).Duration() <= amount); } } #if CLR_2_0 || CLR_4_0 if (FirstImplementsIEquatableOfSecond(xType, yType)) { return(InvokeFirstIEquatableEqualsSecond(expected, actual)); } else if (FirstImplementsIEquatableOfSecond(yType, xType)) { return(InvokeFirstIEquatableEqualsSecond(actual, expected)); } #endif return(expected.Equals(actual)); }
/// <summary> /// Flag the constraint to use the supplied IComparer object. /// </summary> /// <param name="comparer">The IComparer object to use.</param> /// <returns>Self.</returns> public CollectionItemsEqualConstraint Using <T>(IComparer <T> comparer) { return(Using(EqualityAdapter.For(comparer))); }
/// <summary> /// Flag the constraint to use the supplied EqualityAdapter. /// NOTE: For internal use only. /// </summary> /// <param name="adapter">The EqualityAdapter to use.</param> /// <returns>Self.</returns> internal CollectionItemsEqualConstraint Using(EqualityAdapter adapter) { this.comparer.ExternalComparers.Add(adapter); return(this); }
private bool ObjectsEqual(object expected, object actual, ref Tolerance tolerance) { if (expected == null && actual == null) { return(true); } if (expected == null || actual == null) { return(false); } if (object.ReferenceEquals(expected, actual)) { return(true); } Type xType = expected.GetType(); Type yType = actual.GetType(); EqualityAdapter externalComparer = GetExternalComparer(expected, actual); if (externalComparer != null) { return(externalComparer.AreEqual(expected, actual)); } if (xType.IsArray && yType.IsArray && !compareAsCollection) { return(ArraysEqual((Array)expected, (Array)actual, ref tolerance)); } if (expected is IDictionary && actual is IDictionary) { return(DictionariesEqual((IDictionary)expected, (IDictionary)actual, ref tolerance)); } if (expected is IEnumerable && actual is IEnumerable && !(expected is string && actual is string)) { return(EnumerablesEqual((IEnumerable)expected, (IEnumerable)actual, ref tolerance)); } if (expected is string && actual is string) { return(StringsEqual((string)expected, (string)actual)); } if (expected is Stream && actual is Stream) { return(StreamsEqual((Stream)expected, (Stream)actual)); } #if !PORTABLE if (expected is DirectoryInfo && actual is DirectoryInfo) { return(DirectoriesEqual((DirectoryInfo)expected, (DirectoryInfo)actual)); } #endif if (Numerics.IsNumericType(expected) && Numerics.IsNumericType(actual)) { return(Numerics.AreEqual(expected, actual, ref tolerance)); } if (tolerance != null && tolerance.Value is TimeSpan) { TimeSpan amount = (TimeSpan)tolerance.Value; if (expected is DateTime && actual is DateTime) { return(((DateTime)expected - (DateTime)actual).Duration() <= amount); } if (expected is TimeSpan && actual is TimeSpan) { return(((TimeSpan)expected - (TimeSpan)actual).Duration() <= amount); } } #if (CLR_2_0 || CLR_4_0) && !NETCF if (FirstImplementsIEquatableOfSecond(xType, yType)) { return(InvokeFirstIEquatableEqualsSecond(expected, actual)); } else if (FirstImplementsIEquatableOfSecond(yType, xType)) { return(InvokeFirstIEquatableEqualsSecond(actual, expected)); } #endif return(expected.Equals(actual)); }
/// <summary> /// Flag the constraint to use the supplied Comparison object. /// </summary> /// <param name="comparer">The IComparer object to use.</param> /// <returns>Self.</returns> public CollectionItemsEqualConstraint Using <T>(Comparison <T> comparer) { this.comparer.ExternalComparers.Add(EqualityAdapter.For(comparer)); return(this); }
/// <summary> /// Flag the constraint to use the supplied IComparer object. /// </summary> /// <param name="comparer">The IComparer object to use.</param> /// <returns>Self.</returns> public ContainsConstraint Using(IComparer comparer) { return(AddAdapter(EqualityAdapter.For(comparer))); }
public bool AreEqual(object x, object y, ref Tolerance tolerance) { failurePoints = new ObjectList(); if (x == null && y == null) { return(true); } if (x == null || y == null) { return(false); } if (object.ReferenceEquals(x, y)) { return(true); } Type type = x.GetType(); Type type2 = y.GetType(); EqualityAdapter externalComparer = GetExternalComparer(x, y); if (externalComparer != null) { return(externalComparer.AreEqual(x, y)); } if (type.IsArray && type2.IsArray && !compareAsCollection) { return(ArraysEqual((Array)x, (Array)y, ref tolerance)); } if (x is IDictionary && y is IDictionary) { return(DictionariesEqual((IDictionary)x, (IDictionary)y, ref tolerance)); } if (x is IEnumerable && y is IEnumerable && (!(x is string) || !(y is string))) { return(EnumerablesEqual((IEnumerable)x, (IEnumerable)y, ref tolerance)); } if (x is string && y is string) { return(StringsEqual((string)x, (string)y)); } if (x is Stream && y is Stream) { return(StreamsEqual((Stream)x, (Stream)y)); } if (Numerics.IsNumericType(x) && Numerics.IsNumericType(y)) { return(Numerics.AreEqual(x, y, ref tolerance)); } if (tolerance != null && tolerance.Value is TimeSpan) { TimeSpan timeSpan = (TimeSpan)tolerance.Value; if (x is DateTime && y is DateTime) { return(((DateTime)x - (DateTime)y).Duration() <= timeSpan); } if (x is TimeSpan && y is TimeSpan) { return(((TimeSpan)x - (TimeSpan)y).Duration() <= timeSpan); } } return(x.Equals(y)); }
private ContainsConstraint AddAdapter(EqualityAdapter adapter) { this.equalityAdapters.Add(adapter); return(this); }
/// <summary> /// Compares two objects for equality within a tolerance. /// </summary> public bool AreEqual(object x, object y, ref Tolerance tolerance) { this.failurePoints = new List <FailurePoint>(); if (x == null && y == null) { return(true); } if (x == null || y == null) { return(false); } if (object.ReferenceEquals(x, y)) { return(true); } Type xType = x.GetType(); Type yType = y.GetType(); Type xGenericTypeDefinition = xType.IsGenericType ? xType.GetGenericTypeDefinition() : null; Type yGenericTypeDefinition = yType.IsGenericType ? yType.GetGenericTypeDefinition() : null; EqualityAdapter externalComparer = GetExternalComparer(x, y); if (externalComparer != null) { return(externalComparer.AreEqual(x, y)); } if (xType.IsArray && yType.IsArray && !compareAsCollection) { return(ArraysEqual((Array)x, (Array)y, ref tolerance)); } if (x is IDictionary && y is IDictionary) { return(DictionariesEqual((IDictionary)x, (IDictionary)y, ref tolerance)); } // Issue #70 - EquivalentTo isn't compatible with IgnoreCase for dictionaries if (x is DictionaryEntry && y is DictionaryEntry) { return(DictionaryEntriesEqual((DictionaryEntry)x, (DictionaryEntry)y, ref tolerance)); } // IDictionary<,> will eventually try to compare it's key value pairs when using CollectionTally if (xGenericTypeDefinition == typeof(KeyValuePair <,>) && yGenericTypeDefinition == typeof(KeyValuePair <,>)) { var keyTolerance = Tolerance.Exact; object xKey = xType.GetProperty("Key").GetValue(x, null); object yKey = yType.GetProperty("Key").GetValue(y, null); object xValue = xType.GetProperty("Value").GetValue(x, null); object yValue = yType.GetProperty("Value").GetValue(y, null); return(AreEqual(xKey, yKey, ref keyTolerance) && AreEqual(xValue, yValue, ref tolerance)); } //if (x is ICollection && y is ICollection) // return CollectionsEqual((ICollection)x, (ICollection)y, ref tolerance); if (x is string && y is string) { return(StringsEqual((string)x, (string)y)); } if (x is IEnumerable && y is IEnumerable) { return(EnumerablesEqual((IEnumerable)x, (IEnumerable)y, ref tolerance)); } if (x is Stream && y is Stream) { return(StreamsEqual((Stream)x, (Stream)y)); } if (x is char && y is char) { return(CharsEqual((char)x, (char)y)); } #if !PORTABLE if (x is DirectoryInfo && y is DirectoryInfo) { return(DirectoriesEqual((DirectoryInfo)x, (DirectoryInfo)y)); } #endif if (Numerics.IsNumericType(x) && Numerics.IsNumericType(y)) { return(Numerics.AreEqual(x, y, ref tolerance)); } #if !NETCF if (x is DateTimeOffset && y is DateTimeOffset) { bool result; DateTimeOffset xAsOffset = (DateTimeOffset)x; DateTimeOffset yAsOffset = (DateTimeOffset)y; if (tolerance != null && tolerance.Value is TimeSpan) { TimeSpan amount = (TimeSpan)tolerance.Value; result = (xAsOffset - yAsOffset).Duration() <= amount; } else { result = xAsOffset == yAsOffset; } if (result && WithSameOffset) { result = xAsOffset.Offset == yAsOffset.Offset; } return(result); } #endif if (tolerance != null && tolerance.Value is TimeSpan) { TimeSpan amount = (TimeSpan)tolerance.Value; if (x is DateTime && y is DateTime) { return(((DateTime)x - (DateTime)y).Duration() <= amount); } if (x is TimeSpan && y is TimeSpan) { return(((TimeSpan)x - (TimeSpan)y).Duration() <= amount); } } if (FirstImplementsIEquatableOfSecond(xType, yType)) { return(InvokeFirstIEquatableEqualsSecond(x, y)); } else if (xType != yType && FirstImplementsIEquatableOfSecond(yType, xType)) { return(InvokeFirstIEquatableEqualsSecond(y, x)); } return(x.Equals(y)); }
/// <summary> /// Flag the constraint to use the supplied IComparer object. /// </summary> /// <param name="comparer">The IComparer object to use.</param> /// <returns>Self.</returns> public CollectionItemsEqualConstraint Using(IComparer comparer) { _comparer.ExternalComparers.Add(EqualityAdapter.For(comparer)); return(this); }
/// <summary> /// Flag the constraint to use the supplied IEqualityComparer object. /// </summary> /// <param name="comparer">The IEqualityComparer object to use.</param> public AnyOfConstraint Using(IEqualityComparer comparer) { _comparer.ExternalComparers.Add(EqualityAdapter.For(comparer)); return(this); }
/// <summary> /// Flag the constraint to use the supplied IEqualityComparer object. /// </summary> /// <param name="comparer">The IComparer object to use.</param> /// <returns>Self.</returns> public ContainsConstraint Using <T>(IEqualityComparer <T> comparer) { return(AddAdapter(EqualityAdapter.For(comparer))); }
/// <summary> /// Flag the constraint to use the supplied IEqualityComparer object. /// </summary> /// <param name="comparer">The IComparer object to use.</param> /// <returns>Self.</returns> public CollectionItemsEqualConstraint Using <T>(IEqualityComparer <T> comparer) { this.comparer.ExternalComparer = EqualityAdapter.For(comparer); return(this); }
/// <summary> /// Flag the constraint to use the supplied IEqualityComparer object. /// </summary> /// <param name="comparer">The IComparer object to use.</param> /// <returns>Self.</returns> public ContainsConstraint Using <T>(IEqualityComparer <T> comparer) { this.adapter = EqualityAdapter.For(comparer); return(this); }