EqualConstraint
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
namespace NUnit.Framework.Constraints
{
[NullableContext(1)]
[Nullable(0)]
public class EqualConstraint : Constraint
{
[Nullable(2)]
private readonly object _expected;
private Tolerance _tolerance = Tolerance.Default;
private readonly NUnitEqualityComparer _comparer = new NUnitEqualityComparer();
public Tolerance Tolerance => _tolerance;
public bool CaseInsensitive => _comparer.IgnoreCase;
public bool IgnoringWhiteSpace => _comparer.IgnoreWhiteSpace;
public bool ComparingProperties => _comparer.CompareProperties;
public bool ClipStrings { get; set; }
public bool HasFailurePoints => _comparer.HasFailurePoints;
public IList<NUnitEqualityComparer.FailurePoint> FailurePoints => _comparer.FailurePoints;
public EqualConstraint IgnoreCase {
get {
_comparer.IgnoreCase = true;
return this;
}
}
public EqualConstraint IgnoreWhiteSpace {
get {
_comparer.IgnoreWhiteSpace = true;
return this;
}
}
public EqualConstraint NoClip {
get {
ClipStrings = false;
return this;
}
}
public EqualConstraint AsCollection {
get {
_comparer.CompareAsCollection = true;
return this;
}
}
public EqualConstraint WithSameOffset {
get {
_comparer.WithSameOffset = true;
return this;
}
}
public EqualConstraint Ulps {
get {
_tolerance = _tolerance.Ulps;
return this;
}
}
public EqualConstraint Percent {
get {
_tolerance = _tolerance.Percent;
return this;
}
}
public EqualConstraint Days {
get {
_tolerance = _tolerance.Days;
return this;
}
}
public EqualConstraint Hours {
get {
_tolerance = _tolerance.Hours;
return this;
}
}
public EqualConstraint Minutes {
get {
_tolerance = _tolerance.Minutes;
return this;
}
}
public EqualConstraint Seconds {
get {
_tolerance = _tolerance.Seconds;
return this;
}
}
public EqualConstraint Milliseconds {
get {
_tolerance = _tolerance.Milliseconds;
return this;
}
}
public EqualConstraint Ticks {
get {
_tolerance = _tolerance.Ticks;
return this;
}
}
public override string Description {
get {
StringBuilder stringBuilder = new StringBuilder(MsgUtils.FormatValue(_expected));
if (_tolerance != null && _tolerance.HasVariance) {
stringBuilder.Append(" +/- ");
stringBuilder.Append(MsgUtils.FormatValue(_tolerance.Amount));
if (_tolerance.Mode != ToleranceMode.Linear) {
stringBuilder.Append(" ");
stringBuilder.Append(_tolerance.Mode.ToString());
}
}
if (_comparer.IgnoreCase)
stringBuilder.Append(", ignoring case");
if (_comparer.IgnoreWhiteSpace)
stringBuilder.Append(", ignoring white-space");
return stringBuilder.ToString();
}
}
[NullableContext(2)]
public EqualConstraint(object expected)
: base(expected)
{
AdjustArgumentIfNeeded(ref expected);
_expected = expected;
ClipStrings = true;
}
public EqualConstraint Within(object amount)
{
if (!_tolerance.IsUnsetOrDefault)
throw new InvalidOperationException("Within modifier may appear only once in a constraint expression");
_tolerance = new Tolerance(amount);
return this;
}
public EqualConstraint Using(IComparer comparer)
{
_comparer.ExternalComparers.Add(EqualityAdapter.For(comparer));
return this;
}
public EqualConstraint Using<[Nullable(2)] T>(IComparer<T> comparer)
{
((ICollection<EqualityAdapter>)_comparer.ExternalComparers).Add(EqualityAdapter.For(comparer));
return this;
}
public EqualConstraint Using<[Nullable(2)] T>(Func<T, T, bool> comparer)
{
((ICollection<EqualityAdapter>)_comparer.ExternalComparers).Add(EqualityAdapter.For(comparer));
return this;
}
public EqualConstraint Using<[Nullable(2)] T>(Comparison<T> comparer)
{
((ICollection<EqualityAdapter>)_comparer.ExternalComparers).Add(EqualityAdapter.For(comparer));
return this;
}
public EqualConstraint Using(IEqualityComparer comparer)
{
_comparer.ExternalComparers.Add(EqualityAdapter.For(comparer));
return this;
}
public EqualConstraint Using<[Nullable(2)] T>(IEqualityComparer<T> comparer)
{
((ICollection<EqualityAdapter>)_comparer.ExternalComparers).Add(EqualityAdapter.For(comparer));
return this;
}
public EqualConstraint Using<[Nullable(2)] TActual, [Nullable(2)] TExpected>(Func<TActual, TExpected, bool> comparison)
{
((ICollection<EqualityAdapter>)_comparer.ExternalComparers).Add(EqualityAdapter.For(comparison));
return this;
}
public EqualConstraint UsingPropertiesComparer()
{
_comparer.CompareProperties = true;
return this;
}
public override ConstraintResult ApplyTo<[Nullable(2)] TActual>(TActual actual)
{
AdjustArgumentIfNeeded(ref actual);
return new EqualConstraintResult(this, actual, _comparer.AreEqual(_expected, actual, ref _tolerance));
}
private void AdjustArgumentIfNeeded<[Nullable(2)] T>(ref T arg)
{
if (arg != null) {
Type type = arg.GetType();
Type left = type.IsGenericType ? type.GetGenericTypeDefinition() : null;
if (left == typeof(ArraySegment<>) && type.GetProperty("Array")?.GetValue(arg, null) == null) {
Type elementType = type.GetGenericArguments()[0];
Array array = Array.CreateInstance(elementType, 0);
ConstructorInfo constructor = type.GetConstructor(new Type[1] {
array.GetType()
});
arg = (T)constructor.Invoke(new object[1] {
array
});
}
}
}
}
}