using System;
using System.ComponentModel;
using System.Linq.Expressions;
using NUnit.Framework;
namespace Tests
{
///
/// Collection of usefull extension methods to help testing viewmodel properties.
///
public static class TestViewModelHelper
{
///
/// Test that a string property of a viewmodel class has a correct behavior:
/// - write a value and read it back to check its value
/// - ensure that the PropertyChanged event is raised properly
///
/// Type of the ViewModel
/// Type of the property to test. Supported types are bool, string, int and bouel
/// Instance of a ViewModel object
/// Expression which evaluate the property to test
public static void TestProperty(T viewmodel, Expression> expression)
where T : INotifyPropertyChanged
{
if(expression.Body is MemberExpression)
{
MemberExpression memberExpression = (MemberExpression) expression.Body;
if (expression.Body.Type == typeof(bool))
{
TestViewModelProperty(viewmodel, memberExpression.Member.Name, true, false);
}
else if (expression.Body.Type == typeof(string))
{
TestViewModelProperty(viewmodel, memberExpression.Member.Name, "value1", "value2");
}
else if (expression.Body.Type == typeof(int))
{
TestViewModelProperty(viewmodel, memberExpression.Member.Name, 1, 99);
}
else if (expression.Body.Type == typeof(double))
{
TestViewModelProperty(viewmodel, memberExpression.Member.Name, 1.0, 99.0);
}
else
{
throw new NotSupportedException("Type is not supported");
}
}
}
///
/// Test that a property of a viewmodel class has a correct behavior:
/// - write a value and read it back to check its value
/// - ensure that the PropertyChanged event is raised properly
///
/// Type of the viewmodel
/// ViewModel instance
/// Name of the property to test
private static void TestViewModelProperty(T viewModel, string propertyName, U value1, U value2)
where T : INotifyPropertyChanged
{
bool propertyChanged;
viewModel.PropertyChanged += (s, e) => propertyChanged = e.PropertyName == propertyName;
propertyChanged = false;
viewModel.SetValue(propertyName, value1);
Assert.IsTrue(propertyChanged);
Assert.IsTrue(viewModel.GetValue(propertyName).Equals(value1));
propertyChanged = false;
viewModel.SetValue(propertyName, value2);
Assert.IsTrue(propertyChanged);
Assert.IsTrue(viewModel.GetValue(propertyName).Equals(value2));
}
///
/// Gets a property on a object by reflection
///
/// Type of the value to get
/// Instance of the object which has the property
/// Name of the property to get
/// Value of the property on this object
private static T GetValue(this object obj, string propertyName)
{
var propertyInfo = obj.GetType().GetProperty(propertyName);
return (T)propertyInfo.GetValue(obj, null);
}
///
/// Sets a property on a object by reflection
///
/// Type of the value to set
/// Instance of the object which has the property
/// Name of the property to set
/// Value to set
private static void SetValue(this object obj, string propertyName, T value)
{
var propertyInfo = obj.GetType().GetProperty(propertyName);
propertyInfo.SetValue(obj, value, null);
}
}
}