Skip to content

Commit c73f781

Browse files
committed
Merge branch 'feature/issue-48' into dev
2 parents fb6352f + 7b4f64d commit c73f781

27 files changed

+635
-283
lines changed

src/Patterns.Testing/Patterns.Testing.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343
<Reference Include="Autofac.Extras.CommonServiceLocator">
4444
<HintPath>..\packages\Autofac.Extras.CommonServiceLocator.3.0.0\lib\net40\Autofac.Extras.CommonServiceLocator.dll</HintPath>
4545
</Reference>
46+
<Reference Include="AutoMapper">
47+
<HintPath>..\packages\AutoMapper.2.2.1\lib\net40\AutoMapper.dll</HintPath>
48+
</Reference>
4649
<Reference Include="Microsoft.Practices.ServiceLocation">
4750
<HintPath>..\packages\CommonServiceLocator.1.0\lib\NET35\Microsoft.Practices.ServiceLocation.dll</HintPath>
4851
</Reference>

src/Patterns.Testing/SpecFlow/Mixins.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121

2222
using System;
2323
using System.Diagnostics;
24+
using System.Linq;
25+
using System.Reflection;
26+
27+
using AutoMapper;
2428

2529
using Patterns.ExceptionHandling;
2630
using Patterns.Testing.Moq;
@@ -42,6 +46,36 @@ public static string NewKey(this ScenarioContext context)
4246
}
4347
}
4448

49+
public static TObject CreateAndMapValues<TObject>(this Table table) where TObject : new()
50+
{
51+
var target = new TObject();
52+
table.MapValues(target);
53+
return target;
54+
}
55+
56+
public static TObject MapValues<TObject>(this Table table, TObject target)
57+
{
58+
PropertyInfo[] properties = target.GetType().GetProperties();
59+
60+
foreach (TableRow row in table.Rows)
61+
{
62+
string propertyName = row["name"];
63+
string propertyValue = row["value"];
64+
65+
PropertyInfo property = properties.FirstOrDefault(item => item.Name == propertyName);
66+
67+
if (property == null) continue;
68+
69+
object actualValue = property.PropertyType != typeof (string)
70+
? Mapper.Map(propertyValue, typeof (string), property.PropertyType)
71+
: propertyValue;
72+
73+
property.SetValue(target, actualValue, null);
74+
}
75+
76+
return target;
77+
}
78+
4579
public static TValue GetValue<TValue>(this ScenarioContext context, string key = null, Func<TValue> factory = null)
4680
{
4781
key = ResolveKey<TValue>(key);
@@ -58,6 +92,20 @@ public static TValue GetValue<TValue>(this ScenarioContext context, string key =
5892
return valueExists ? Try.Get(() => context.Get<TValue>(key), exception => new ExceptionState(exception, true), factory) : factory();
5993
}
6094

95+
public static object GetValue(this ScenarioContext context, string key, Func<object> factory = null)
96+
{
97+
bool valueExists = context.ContainsKey(key);
98+
99+
if (!valueExists && factory != null)
100+
{
101+
object value = factory();
102+
context[key] = value;
103+
return value;
104+
}
105+
106+
return valueExists ? Try.Get(() => context[key], exception => new ExceptionState(exception, true)) : null;
107+
}
108+
61109
public static void SetValue<TValue>(this ScenarioContext context, TValue instance, string key = null)
62110
{
63111
key = ResolveKey<TValue>(key);

src/Patterns.Testing/packages.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<packages>
33
<package id="Autofac" version="3.0.1" targetFramework="net40" />
44
<package id="Autofac.Extras.CommonServiceLocator" version="3.0.0" targetFramework="net40" />
5+
<package id="AutoMapper" version="2.2.1" targetFramework="net40" />
56
<package id="CommonServiceLocator" version="1.0" targetFramework="net40" />
67
<package id="Moq" version="4.0.10827" targetFramework="net40" />
78
<package id="SpecFlow" version="1.9.0" targetFramework="net40" />

src/Patterns/Patterns.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@
7070
</Compile>
7171
<Compile Include="Logging\Mixins.cs" />
7272
<Compile Include="Properties\AssemblyInfo.cs" />
73+
<Compile Include="Reflection\Mixins.cs" />
74+
<Compile Include="Reflection\PropertyValue.cs" />
7375
<Compile Include="Runtime\DefaultDateTimeInfo.cs" />
7476
<Compile Include="Runtime\IDateTimeInfo.cs" />
7577
<Compile Include="Runtime\TimeExtensions.cs" />
@@ -105,6 +107,7 @@
105107
<EmbeddedResource Include="Logging\LoggingResources.resx">
106108
<Generator>ResXFileCodeGenerator</Generator>
107109
<LastGenOutput>LoggingResources.Designer.cs</LastGenOutput>
110+
<SubType>Designer</SubType>
108111
</EmbeddedResource>
109112
</ItemGroup>
110113
<ItemGroup>

src/Patterns/Reflection/Mixins.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#region FreeBSD
2+
3+
// Copyright (c) 2013, John Batte
4+
// All rights reserved.
5+
//
6+
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
7+
// the following conditions are met:
8+
//
9+
// * Redistributions of source code must retain the above copyright notice, this list of conditions and the
10+
// following disclaimer.
11+
//
12+
// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
13+
// following disclaimer in the documentation and/or other materials provided with the distribution.
14+
//
15+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
16+
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
17+
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
18+
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
19+
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20+
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21+
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
22+
// POSSIBILITY OF SUCH DAMAGE.
23+
24+
#endregion
25+
26+
using System.Collections.Generic;
27+
using System.Linq;
28+
29+
namespace Patterns.Reflection
30+
{
31+
/// <summary>
32+
/// Provides extensions for ease-of-use during Reflection-based operations.
33+
/// </summary>
34+
public static class Mixins
35+
{
36+
/// <summary>
37+
/// Gets the property values.
38+
/// </summary>
39+
/// <param name="source">The source.</param>
40+
/// <returns></returns>
41+
public static IEnumerable<PropertyValue> GetPropertyValues(this object source)
42+
{
43+
return source.GetType().GetProperties().Select(property => new PropertyValue
44+
{
45+
Name = property.Name,
46+
Value = property.GetValue(source, null)
47+
});
48+
}
49+
}
50+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#region FreeBSD
2+
3+
// Copyright (c) 2013, John Batte
4+
// All rights reserved.
5+
//
6+
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
7+
// the following conditions are met:
8+
//
9+
// * Redistributions of source code must retain the above copyright notice, this list of conditions and the
10+
// following disclaimer.
11+
//
12+
// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
13+
// following disclaimer in the documentation and/or other materials provided with the distribution.
14+
//
15+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
16+
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
17+
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
18+
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
19+
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20+
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21+
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
22+
// POSSIBILITY OF SUCH DAMAGE.
23+
24+
#endregion
25+
26+
namespace Patterns.Reflection
27+
{
28+
/// <summary>
29+
/// Encapsulates the name and value of a property.
30+
/// </summary>
31+
public class PropertyValue
32+
{
33+
/// <summary>
34+
/// Gets or sets the name.
35+
/// </summary>
36+
/// <value>
37+
/// The name.
38+
/// </value>
39+
public string Name { get; set; }
40+
41+
/// <summary>
42+
/// Gets or sets the value.
43+
/// </summary>
44+
/// <value>
45+
/// The value.
46+
/// </value>
47+
public object Value { get; set; }
48+
}
49+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Feature: GetPropertyValues for objects
2+
As a developer, I want to quickly access the properties of an object
3+
and their values without needing to access the clunky Reflection API.
4+
5+
Scenario: Value Type
6+
Given my object is an integer with the value 47
7+
When I get the property values of my object
8+
Then the property values should be empty
9+
10+
Scenario: Reference Type
11+
Given my object is a test object with the following values:
12+
| name | value |
13+
| Id | 47 |
14+
| Data | ABC |
15+
When I get the property values of my object
16+
Then the property values should be equivalent to:
17+
| name | value |
18+
| Id | 47 |
19+
| Data | ABC |

src/_specs.Testing/Features/Reflection/GetPropertyValues.feature.cs

Lines changed: 124 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/_specs.Testing/Steps/Assertions/ConfigAssertions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public void AssertActualConfigSectionWrongType()
4141
Debug.Assert(ConfigObservations.ActualConfig != null);
4242
Debug.Assert(ConfigObservations.ExpectedConfig != null);
4343
var expectedType = ConfigObservations.ExpectedConfig.GetType();
44-
expectedType.IsAssignableFrom(ConfigObservations.ActualConfig.GetType()).Should().BeFalse();
44+
expectedType.IsInstanceOfType(ConfigObservations.ActualConfig).Should().BeFalse();
4545
}
4646
}
4747
}

0 commit comments

Comments
 (0)