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;
using System.Runtime.CompilerServices;
namespace NUnit.Framework.Constraints
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public class DictionaryContainsKeyConstraint : Constraint
{
private const string ContainsMethodName = "Contains";
private const string ContainsKeyMethodName = "ContainsKey";
public override string DisplayName => "ContainsKey";
public override string Description => "dictionary containing key " + MsgUtils.FormatValue(Expected);
protected object Expected { get; }
public DictionaryContainsKeyConstraint(object expected)
: base(expected)
{
Expected = expected;
}
public DictionaryContainsKeyValuePairConstraint WithValue([System.Runtime.CompilerServices.Nullable(2)] object expectedValue)
{
return base.Instead.Append(new DictionaryContainsKeyValuePairConstraint(Expected, expectedValue));
}
[System.Runtime.CompilerServices.NullableContext(2)]
private bool Matches(object actual)
{
if (actual == null)
throw new ArgumentException("Expected: IDictionary But was: null", "actual");
MethodInfo containsKeyMethod = GetContainsKeyMethod(actual);
if ((object)containsKeyMethod != null)
return (bool)containsKeyMethod.Invoke(actual, new object[1] {
Expected
});
IDictionary dictionary = actual as IDictionary;
if (dictionary != null)
return dictionary.Contains(Expected);
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(41, 3);
defaultInterpolatedStringHandler.AppendLiteral("The ");
defaultInterpolatedStringHandler.AppendFormatted(TypeHelper.GetDisplayName(actual.GetType()));
defaultInterpolatedStringHandler.AppendLiteral(" value must have a ");
defaultInterpolatedStringHandler.AppendFormatted("ContainsKey");
defaultInterpolatedStringHandler.AppendLiteral(" or ");
defaultInterpolatedStringHandler.AppendFormatted("Contains");
defaultInterpolatedStringHandler.AppendLiteral("(TKey) method.");
throw new ArgumentException(defaultInterpolatedStringHandler.ToStringAndClear());
}
public override ConstraintResult ApplyTo<[System.Runtime.CompilerServices.Nullable(2)] TActual>(TActual actual)
{
return new ConstraintResult(this, actual, Matches(actual));
}
[return: System.Runtime.CompilerServices.Nullable(2)]
private static MethodInfo GetContainsKeyMethod(object keyedItemContainer)
{
Type type = keyedItemContainer.GetType();
return FindContainsKeyMethod(type) ?? type.GetInterfaces().Concat(GetBaseTypes(type)).Select(FindContainsKeyMethod)
.FirstOrDefault((MethodInfo m) => (object)m != null);
}
[return: System.Runtime.CompilerServices.Nullable(2)]
private static MethodInfo FindContainsKeyMethod(Type type)
{
MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public);
MethodInfo method = methods.FirstOrDefault(delegate(MethodInfo m) {
if (m.ReturnType == typeof(bool) && m.Name == "ContainsKey" && !m.IsGenericMethod)
return m.GetParameters().Length == 1;
return false;
});
if ((object)method == null && type.IsGenericType) {
Type genericTypeDefinition = type.GetGenericTypeDefinition();
Type tKeyGenericArg = genericTypeDefinition.GetGenericArguments().FirstOrDefault((Type typeArg) => typeArg.Name == "TKey");
if ((object)tKeyGenericArg != null) {
method = genericTypeDefinition.GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault(delegate(MethodInfo m) {
if (m.ReturnType == typeof(bool) && m.Name == "Contains" && !m.IsGenericMethod) {
ParameterInfo[] parameters = m.GetParameters();
if (parameters != null && parameters.Length == 1)
return parameters[0].ParameterType == tKeyGenericArg;
}
return false;
});
if ((object)method != null)
method = methods.Single((MethodInfo m) => m.MetadataToken == method.MetadataToken);
}
}
return method;
}
[IteratorStateMachine(typeof(<GetBaseTypes>d__15))]
private static IEnumerable<Type> GetBaseTypes(Type type)
{
<GetBaseTypes>d__15 <GetBaseTypes>d__ = new <GetBaseTypes>d__15(-2);
<GetBaseTypes>d__.<>3__type = type;
return <GetBaseTypes>d__;
}
}
}