Permalink
Browse files

First cut of enabling FillInstance() to populate fields

  • Loading branch information...
1 parent 1f53c0a commit 9070ec025abdf848ac8adf331267f4f2ff49428c @joebuschmann joebuschmann committed Oct 11, 2013
@@ -62,7 +62,7 @@ private static bool ThereAreAnyDifferences(IEnumerable<Difference> differences)
private static bool ThePropertyDoesNotExist<T>(T instance, TableRow row)
{
return instance.GetType().GetProperties()
- .Any(property => TEHelpers.IsPropertyMatchingToColumnName(property, row.Id())) == false;
+ .Any(property => TEHelpers.IsMemberMatchingToColumnName(property, row.Id())) == false;
}
private static bool TheValuesDoNotMatch<T>(T instance, TableRow row)
@@ -21,7 +21,7 @@ private static PropertyInfo GetThePropertyOnThisObject(object @object, string pr
{
var type = @object.GetType();
return type.GetProperties()
- .FirstOrDefault(x => TEHelpers.IsPropertyMatchingToColumnName(x, propertyName));
+ .FirstOrDefault(x => TEHelpers.IsMemberMatchingToColumnName(x, propertyName));
}
}
}
@@ -142,7 +142,7 @@ private static List<T> GetTheActualItems(IEnumerable<T> set)
private void AssertThatAllColumnsInTheTableMatchToPropertiesOnTheType()
{
var propertiesThatDoNotExist = from columnHeader in table.Header
- where (typeof (T).GetProperties().Any(property => TEHelpers.IsPropertyMatchingToColumnName(property, columnHeader)) == false)
+ where (typeof (T).GetProperties().Any(property => TEHelpers.IsMemberMatchingToColumnName(property, columnHeader)) == false)
select columnHeader;
if (propertiesThatDoNotExist.Any())
@@ -21,15 +21,15 @@ internal static T CreateTheInstanceWithTheValuesFromTheTable<T>(Table table)
if (constructor == null)
throw new MissingMethodException(string.Format("Unable to find a suitable constructor to create instance of {0}", typeof(T).Name));
- var propertiesThatNeedToBeSet = GetPropertiesThatNeedToBeSet(table, typeof(T));
+ var membersThatNeedToBeSet = GetMembersThatNeedToBeSet(table, typeof(T));
var constructorParameters = constructor.GetParameters();
var parameterValues = new object[constructorParameters.Length];
for (var parameterIndex = 0; parameterIndex < constructorParameters.Length; parameterIndex++)
{
var parameterName = constructorParameters[parameterIndex].Name;
- var property = (from p in propertiesThatNeedToBeSet
- where p.PropertyName == parameterName
+ var property = (from p in membersThatNeedToBeSet
+ where p.MemberName == parameterName
select p).FirstOrDefault();
if (property != null)
parameterValues[parameterIndex] = property.Handler(property.Row);
@@ -48,7 +48,7 @@ internal static ConstructorInfo GetConstructorMatchingToColumnNames<T>(Table tab
{
var projectedPropertyNames = from property in typeof(T).GetProperties()
from row in table.Rows
- where IsPropertyMatchingToColumnName(property, row.Id())
+ where IsMemberMatchingToColumnName(property, row.Id())
select property.Name;
return (from constructor in typeof(T).GetConstructors()
@@ -58,9 +58,9 @@ where IsPropertyMatchingToColumnName(property, row.Id())
select constructor).FirstOrDefault();
}
- internal static bool IsPropertyMatchingToColumnName(PropertyInfo property, string columnName)
+ internal static bool IsMemberMatchingToColumnName(MemberInfo member, string columnName)
{
- return property.Name.MatchesThisColumnName(columnName);
+ return member.Name.MatchesThisColumnName(columnName);
}
internal static bool MatchesThisColumnName(this string propertyName, string columnName)
@@ -71,30 +71,44 @@ internal static bool MatchesThisColumnName(this string propertyName, string colu
internal static void LoadInstanceWithKeyValuePairs(Table table, object instance)
{
- var propertiesThatNeedToBeSet = GetPropertiesThatNeedToBeSet(table, instance.GetType());
+ var membersThatNeedToBeSet = GetMembersThatNeedToBeSet(table, instance.GetType());
- propertiesThatNeedToBeSet.ToList()
- .ForEach(x => instance.SetPropertyValue(x.PropertyName, x.Handler(x.Row)));
+ membersThatNeedToBeSet.ToList()
+ .ForEach(x => x.Setter(instance, x.Handler(x.Row)));
}
- internal static IEnumerable<PropertyHandler> GetPropertiesThatNeedToBeSet(Table table, Type type)
+ internal static IEnumerable<MemberHandler> GetMembersThatNeedToBeSet(Table table, Type type)
{
var handlers = GetTypeHandlersForFieldValuePairs(type);
- return from property in type.GetProperties()
- from key in handlers.Keys
- from row in table.Rows
- where ThisPropertyMatchesTheType(property, key)
- && IsPropertyMatchingToColumnName(property, row.Id())
- select new PropertyHandler {Row = row, PropertyName = property.Name, Handler = handlers[key]};
+ var properties = from property in type.GetProperties()
+ from key in handlers.Keys
+ from row in table.Rows
+ where TheseTypesMatch(property.PropertyType, key)
+ && IsMemberMatchingToColumnName(property, row.Id())
+ select new MemberHandler { Row = row, MemberName = property.Name, Handler = handlers[key], Setter = (i, v) => property.SetValue(i, v, null) };
+
+ var fields = from field in type.GetFields()
+ from key in handlers.Keys
+ from row in table.Rows
+ where TheseTypesMatch(field.FieldType, key)
+ && IsMemberMatchingToColumnName(field, row.Id())
+ select new MemberHandler { Row = row, MemberName = field.Name, Handler = handlers[key], Setter = (i, v) => field.SetValue(i, v) };
+
+ var memberHandlers = new List<MemberHandler>();
+
+ memberHandlers.AddRange(properties);
+ memberHandlers.AddRange(fields);
+
+ return memberHandlers;
}
- private static bool ThisPropertyMatchesTheType(PropertyInfo property, Type key)
+ private static bool TheseTypesMatch(Type memberType, Type handlerType)
{
- if (key.IsAssignableFrom(property.PropertyType))
+ if (handlerType.IsAssignableFrom(memberType))
return true;
- if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
- return key.IsAssignableFrom(property.PropertyType.GetGenericArguments()[0]);
+ if (memberType.IsGenericType && memberType.GetGenericTypeDefinition() == typeof(Nullable<>))
+ return handlerType.IsAssignableFrom(memberType.GetGenericArguments()[0]);
return false;
}
@@ -137,11 +151,12 @@ private static bool ThisPropertyMatchesTheType(PropertyInfo property, Type key)
};
}
- internal class PropertyHandler
+ internal class MemberHandler
{
public TableRow Row { get; set; }
- public string PropertyName { get; set; }
+ public string MemberName { get; set; }
public Func<TableRow, object> Handler { get; set; }
+ public Action<object, object> Setter { get; set; }
}
internal static Table GetTheProperInstanceTable(Table table, Type type)
@@ -172,7 +187,7 @@ private static bool TheFirstRowValueIsTheNameOfAProperty(Table table, Type type)
{
var firstRowValue = table.Rows[0][table.Header.First()];
return type.GetProperties()
- .Any(property => IsPropertyMatchingToColumnName(property, firstRowValue));
+ .Any(property => IsMemberMatchingToColumnName(property, firstRowValue));
}
}
}
@@ -0,0 +1,11 @@
+namespace TechTalk.SpecFlow.RuntimeTests.AssistTests.ExampleEntities
+{
+ public class EntityWithPropertiesAndFields
+ {
+ public string Property1 { get; set; }
+ public int Property2 { get; set; }
+
+ public string Field1;
+ public int Field2;
+ }
+}
@@ -31,7 +31,7 @@ public virtual void Can_use_horizontal_tables_with_FillInstance()
}
[Test]
- public virtual void Can_populate_subtype_fields_with_FillInstance()
+ public virtual void Can_populate_subtype_properties_with_FillInstance()
{
Person person = new PersonWithStyle();
@@ -45,5 +45,25 @@ public virtual void Can_populate_subtype_fields_with_FillInstance()
Assert.That(personWithStyle.Style, Is.EqualTo(Style.VeryCool));
}
+
+ [Test]
+ public virtual void Can_populate_properties_and_fields()
+ {
+ var entity = new EntityWithPropertiesAndFields();
+
+ var table = new Table("Member", "Value");
+ table.AddRow("Property1", "Property1");
+ table.AddRow("Property2", "100");
+ table.AddRow("Field1", "Field1");
+ table.AddRow("Field2", "100");
+
+ table.FillInstance(entity);
+
+ entity.Property1.ShouldEqual("Property1");
+ entity.Property2.ShouldEqual(100);
+
+ entity.Field1.ShouldEqual("Field1");
+ entity.Field2.ShouldEqual(100);
+ }
}
}
@@ -67,6 +67,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AssistTests\CreateInstanceHelperMethodTests.cs" />
+ <Compile Include="AssistTests\ExampleEntities\EntityWithPropertiesAndFields.cs" />
<Compile Include="AssistTests\FormattingTableDiffExceptionBuilderTests.cs" />
<Compile Include="AssistTests\PivotTableTests.cs" />
<Compile Include="AssistTests\RowExtensionMethodTests_GetEnum.cs" />

0 comments on commit 9070ec0

Please sign in to comment.