DictionaryContainsKeyConstraint
DictionaryContainsKeyConstraint is used to test whether a dictionary
contains an expected object as a key.
using NUnit.Framework.Internal;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace NUnit.Framework.Constraints
{
public class DictionaryContainsKeyConstraint : CollectionItemsEqualConstraint
{
private const string ObsoleteMessage = "DictionaryContainsKeyConstraint now uses the comparer which the dictionary is based on. To test using a comparer which the dictionary is not based on, use a collection constraint on the set of keys.";
private const string ContainsMethodName = "Contains";
private bool _isDeprecatedMode;
public override string DisplayName => "ContainsKey";
public override string Description => "dictionary containing key " + MsgUtils.FormatValue(Expected);
protected object Expected { get; }
[Obsolete("DictionaryContainsKeyConstraint now uses the comparer which the dictionary is based on. To test using a comparer which the dictionary is not based on, use a collection constraint on the set of keys.")]
public new CollectionItemsEqualConstraint IgnoreCase {
get {
_isDeprecatedMode = true;
return base.IgnoreCase;
}
}
public DictionaryContainsKeyConstraint(object expected)
: base(expected)
{
Expected = expected;
}
private bool Matches(object actual)
{
if (_isDeprecatedMode) {
foreach (object key in ConstraintUtils.RequireActual<IDictionary>(actual, "actual", false).Keys) {
if (ItemsEqual(key, Expected))
return true;
}
return false;
}
MethodInfo containsKeyMethod = GetContainsKeyMethod(actual);
if ((object)containsKeyMethod != null)
return (bool)containsKeyMethod.Invoke(actual, new object[1] {
Expected
});
throw new ArgumentException("The " + TypeHelper.GetDisplayName(actual.GetType()) + " value must have a ContainsKey or Contains(TKey) method.");
}
public override ConstraintResult ApplyTo<TActual>(TActual actual)
{
return new ConstraintResult(this, actual, Matches(actual));
}
protected override bool Matches(IEnumerable collection)
{
return Matches(collection);
}
[Obsolete("DictionaryContainsKeyConstraint now uses the comparer which the dictionary is based on. To test using a comparer which the dictionary is not based on, use a collection constraint on the set of keys.")]
public DictionaryContainsKeyConstraint Using<TCollectionType, TMemberType>(Func<TCollectionType, TMemberType, bool> comparison)
{
Func<TMemberType, TCollectionType, bool> comparison2 = (TMemberType actual, TCollectionType expected) => comparison(expected, actual);
_isDeprecatedMode = true;
Using(EqualityAdapter.For(comparison2));
return this;
}
[Obsolete("DictionaryContainsKeyConstraint now uses the comparer which the dictionary is based on. To test using a comparer which the dictionary is not based on, use a collection constraint on the set of keys.")]
public new CollectionItemsEqualConstraint Using<T>(Comparison<T> comparison)
{
_isDeprecatedMode = true;
return base.Using(comparison);
}
[Obsolete("DictionaryContainsKeyConstraint now uses the comparer which the dictionary is based on. To test using a comparer which the dictionary is not based on, use a collection constraint on the set of keys.")]
public new CollectionItemsEqualConstraint Using(IComparer comparer)
{
_isDeprecatedMode = true;
return base.Using(comparer);
}
[Obsolete("DictionaryContainsKeyConstraint now uses the comparer which the dictionary is based on. To test using a comparer which the dictionary is not based on, use a collection constraint on the set of keys.")]
public new CollectionItemsEqualConstraint Using<T>(IComparer<T> comparer)
{
_isDeprecatedMode = true;
return base.Using(comparer);
}
[Obsolete("DictionaryContainsKeyConstraint now uses the comparer which the dictionary is based on. To test using a comparer which the dictionary is not based on, use a collection constraint on the set of keys.")]
public new CollectionItemsEqualConstraint Using(IEqualityComparer comparer)
{
_isDeprecatedMode = true;
return base.Using(comparer);
}
[Obsolete("DictionaryContainsKeyConstraint now uses the comparer which the dictionary is based on. To test using a comparer which the dictionary is not based on, use a collection constraint on the set of keys.")]
public new CollectionItemsEqualConstraint Using<T>(IEqualityComparer<T> comparer)
{
_isDeprecatedMode = true;
return base.Using(comparer);
}
[Obsolete("DictionaryContainsKeyConstraint now uses the comparer which the dictionary is based on. To test using a comparer which the dictionary is not based on, use a collection constraint on the set of keys.")]
public new CollectionItemsEqualConstraint Using<T>(Func<T, T, bool> comparer)
{
_isDeprecatedMode = true;
return base.Using(comparer);
}
private static MethodInfo GetContainsKeyMethod(object keyedItemContainer)
{
if (keyedItemContainer == null)
throw new ArgumentNullException("keyedItemContainer");
Type type = keyedItemContainer.GetType();
return FindContainsKeyMethod(type) ?? TypeExtensions.GetInterfaces(type).Concat(GetBaseTypes(type)).Select(FindContainsKeyMethod)
.FirstOrDefault((MethodInfo m) => (object)m != null);
}
private static MethodInfo FindContainsKeyMethod(Type type)
{
MethodInfo[] methods = TypeExtensions.GetMethods(type, BindingFlags.Instance | BindingFlags.Public);
MethodInfo method = methods.FirstOrDefault(delegate(MethodInfo m) {
if ((object)m.ReturnType == typeof(bool) && m.Name == "ContainsKey" && !m.IsGenericMethod)
return m.GetParameters().Length == 1;
return false;
});
if ((object)method == null && type.GetTypeInfo().get_IsGenericType()) {
Type genericTypeDefinition = type.GetGenericTypeDefinition();
Type tKeyGenericArg = TypeExtensions.GetGenericArguments(genericTypeDefinition).FirstOrDefault((Type typeArg) => typeArg.get_Name() == "TKey");
if ((object)tKeyGenericArg != null) {
method = TypeExtensions.GetMethods(genericTypeDefinition, BindingFlags.Instance | BindingFlags.Public).FirstOrDefault(delegate(MethodInfo m) {
if ((object)m.ReturnType == typeof(bool) && m.Name == "Contains" && !m.IsGenericMethod && m.GetParameters().Length == 1)
return (object)m.GetParameters()[0].ParameterType == tKeyGenericArg;
return false;
});
if ((object)method != null)
method = methods.Single(delegate(MethodInfo m) {
if (m.Name == method.Name && m.GetParameters().Length == 1 && method.GetParameters().Length == 1)
return m.GetParameters()[0].Name == method.GetParameters()[0].Name;
return false;
});
}
}
return method;
}
private static IEnumerable<Type> GetBaseTypes(Type type)
{
while (true) {
type = type.GetTypeInfo().get_BaseType();
if ((object)type == null)
break;
yield return type;
}
}
}
}