a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
176 lines
7.5 KiB
C#
176 lines
7.5 KiB
C#
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
|
|
|
using System;
|
|
using System.Linq.Expressions;
|
|
using System.Reflection;
|
|
using Assert = Microsoft.TestCommon.AssertEx;
|
|
|
|
namespace Microsoft.TestCommon
|
|
{
|
|
public class ReflectionAssert
|
|
{
|
|
private static PropertyInfo GetPropertyInfo<T, TProp>(Expression<Func<T, TProp>> property)
|
|
{
|
|
if (property.Body is MemberExpression)
|
|
{
|
|
return (PropertyInfo)((MemberExpression)property.Body).Member;
|
|
}
|
|
else if (property.Body is UnaryExpression && property.Body.NodeType == ExpressionType.Convert)
|
|
{
|
|
return (PropertyInfo)((MemberExpression)((UnaryExpression)property.Body).Operand).Member;
|
|
}
|
|
else
|
|
{
|
|
throw new InvalidOperationException("Could not determine property from lambda expression.");
|
|
}
|
|
}
|
|
|
|
private static void TestPropertyValue<TInstance, TValue>(TInstance instance, Func<TInstance, TValue> getFunc, Action<TInstance, TValue> setFunc, TValue valueToSet, TValue valueToCheck)
|
|
{
|
|
setFunc(instance, valueToSet);
|
|
TValue newValue = getFunc(instance);
|
|
Assert.Equal(valueToCheck, newValue);
|
|
}
|
|
|
|
private static void TestPropertyValue<TInstance, TValue>(TInstance instance, Func<TInstance, TValue> getFunc, Action<TInstance, TValue> setFunc, TValue value)
|
|
{
|
|
TestPropertyValue(instance, getFunc, setFunc, value, value);
|
|
}
|
|
|
|
public void Property<T, TResult>(T instance, Expression<Func<T, TResult>> propertyGetter, TResult expectedDefaultValue, bool allowNull = false, TResult roundTripTestValue = null) where TResult : class
|
|
{
|
|
PropertyInfo property = GetPropertyInfo(propertyGetter);
|
|
Func<T, TResult> getFunc = (obj) => (TResult)property.GetValue(obj, index: null);
|
|
Action<T, TResult> setFunc = (obj, value) => property.SetValue(obj, value, index: null);
|
|
|
|
Assert.Equal(expectedDefaultValue, getFunc(instance));
|
|
|
|
if (allowNull)
|
|
{
|
|
TestPropertyValue(instance, getFunc, setFunc, null);
|
|
}
|
|
else
|
|
{
|
|
Assert.ThrowsArgumentNull(() =>
|
|
{
|
|
setFunc(instance, null);
|
|
}, "value");
|
|
}
|
|
|
|
if (roundTripTestValue != null)
|
|
{
|
|
TestPropertyValue(instance, getFunc, setFunc, roundTripTestValue);
|
|
}
|
|
}
|
|
|
|
public void IntegerProperty<T, TResult>(T instance, Expression<Func<T, TResult>> propertyGetter, TResult expectedDefaultValue,
|
|
TResult? minLegalValue, TResult? illegalLowerValue,
|
|
TResult? maxLegalValue, TResult? illegalUpperValue,
|
|
TResult roundTripTestValue) where TResult : struct
|
|
{
|
|
PropertyInfo property = GetPropertyInfo(propertyGetter);
|
|
Func<T, TResult> getFunc = (obj) => (TResult)property.GetValue(obj, index: null);
|
|
Action<T, TResult> setFunc = (obj, value) => property.SetValue(obj, value, index: null);
|
|
|
|
Assert.Equal(expectedDefaultValue, getFunc(instance));
|
|
|
|
if (minLegalValue.HasValue)
|
|
{
|
|
TestPropertyValue(instance, getFunc, setFunc, minLegalValue.Value);
|
|
}
|
|
|
|
if (maxLegalValue.HasValue)
|
|
{
|
|
TestPropertyValue(instance, getFunc, setFunc, maxLegalValue.Value);
|
|
}
|
|
|
|
if (illegalLowerValue.HasValue)
|
|
{
|
|
Assert.ThrowsArgumentGreaterThanOrEqualTo(() => { setFunc(instance, illegalLowerValue.Value); }, "value", minLegalValue.Value.ToString(), illegalLowerValue.Value);
|
|
}
|
|
|
|
if (illegalUpperValue.HasValue)
|
|
{
|
|
Assert.ThrowsArgumentLessThanOrEqualTo(() => { setFunc(instance, illegalLowerValue.Value); }, "value", maxLegalValue.Value.ToString(), illegalUpperValue.Value);
|
|
}
|
|
|
|
TestPropertyValue(instance, getFunc, setFunc, roundTripTestValue);
|
|
}
|
|
|
|
public void BooleanProperty<T>(T instance, Expression<Func<T, bool>> propertyGetter, bool expectedDefaultValue)
|
|
{
|
|
PropertyInfo property = GetPropertyInfo(propertyGetter);
|
|
Func<T, bool> getFunc = (obj) => (bool)property.GetValue(obj, index: null);
|
|
Action<T, bool> setFunc = (obj, value) => property.SetValue(obj, value, index: null);
|
|
|
|
Assert.Equal(expectedDefaultValue, getFunc(instance));
|
|
|
|
TestPropertyValue(instance, getFunc, setFunc, !expectedDefaultValue);
|
|
}
|
|
|
|
public void EnumProperty<T, TResult>(T instance, Expression<Func<T, TResult>> propertyGetter, TResult expectedDefaultValue, TResult illegalValue, TResult roundTripTestValue) where TResult : struct
|
|
{
|
|
PropertyInfo property = GetPropertyInfo(propertyGetter);
|
|
Func<T, TResult> getFunc = (obj) => (TResult)property.GetValue(obj, index: null);
|
|
Action<T, TResult> setFunc = (obj, value) => property.SetValue(obj, value, index: null);
|
|
|
|
Assert.Equal(expectedDefaultValue, getFunc(instance));
|
|
|
|
Assert.ThrowsInvalidEnumArgument(() => { setFunc(instance, illegalValue); }, "value", Convert.ToInt32(illegalValue), typeof(TResult));
|
|
|
|
TestPropertyValue(instance, getFunc, setFunc, roundTripTestValue);
|
|
}
|
|
|
|
public void StringProperty<T>(T instance, Expression<Func<T, string>> propertyGetter, string expectedDefaultValue,
|
|
bool allowNullAndEmpty = true, string nullAndEmptyReturnValue = "")
|
|
{
|
|
PropertyInfo property = GetPropertyInfo(propertyGetter);
|
|
Func<T, string> getFunc = (obj) => (string)property.GetValue(obj, index: null);
|
|
Action<T, string> setFunc = (obj, value) => property.SetValue(obj, value, index: null);
|
|
|
|
Assert.Equal(expectedDefaultValue, getFunc(instance));
|
|
|
|
if (allowNullAndEmpty)
|
|
{
|
|
// Assert get/set works for null
|
|
TestPropertyValue(instance, getFunc, setFunc, null, nullAndEmptyReturnValue);
|
|
|
|
// Assert get/set works for String.Empty
|
|
TestPropertyValue(instance, getFunc, setFunc, String.Empty, nullAndEmptyReturnValue);
|
|
}
|
|
else
|
|
{
|
|
Assert.ThrowsArgumentNullOrEmpty(
|
|
delegate()
|
|
{
|
|
try
|
|
{
|
|
TestPropertyValue(instance, getFunc, setFunc, null);
|
|
}
|
|
catch (TargetInvocationException e)
|
|
{
|
|
throw e.InnerException;
|
|
}
|
|
},
|
|
"value");
|
|
Assert.ThrowsArgumentNullOrEmpty(
|
|
delegate()
|
|
{
|
|
try
|
|
{
|
|
TestPropertyValue(instance, getFunc, setFunc, String.Empty);
|
|
}
|
|
catch (TargetInvocationException e)
|
|
{
|
|
throw e.InnerException;
|
|
}
|
|
},
|
|
"value");
|
|
}
|
|
|
|
// Assert get/set works for arbitrary value
|
|
TestPropertyValue(instance, getFunc, setFunc, "TestValue");
|
|
}
|
|
}
|
|
}
|