Skip to content

Commit 15671b0

Browse files
committed
Merge pull request #53 from HerrLoesch/master
Setups can now be reused in other setups as well as the Randomizer class
2 parents b6148f5 + 706ef91 commit 15671b0

File tree

5 files changed

+164
-27
lines changed

5 files changed

+164
-27
lines changed

ObjectFiller.Test/ObjectFiller.Test.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
<Compile Include="SaveFillerSetupTest.cs" />
8686
<Compile Include="EmailAddressesPluginTest.cs" />
8787
<Compile Include="TestPoco\TestEnum.cs" />
88+
<Compile Include="SetupTests.cs" />
8889
</ItemGroup>
8990
<ItemGroup>
9091
<ProjectReference Include="..\ObjectFiller\ObjectFiller.csproj">

ObjectFiller.Test/SetupTests.cs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
using System;
2+
using Microsoft.VisualStudio.TestTools.UnitTesting;
3+
4+
namespace ObjectFiller.Test
5+
{
6+
using Tynamix.ObjectFiller;
7+
8+
[TestClass]
9+
public class SetupTests
10+
{
11+
public class Parent
12+
{
13+
public Child Child { get; set; }
14+
}
15+
16+
public class Child
17+
{
18+
public int Value { get; set; }
19+
}
20+
21+
[TestMethod]
22+
public void RandomizerCreatesObjectsBasedOnPreviouseSetups()
23+
{
24+
int givenValue = Randomizer<int>.Create();
25+
26+
var childFiller = new Filler<Child>();
27+
var childSetup = childFiller.Setup().OnProperty(x => x.Value).Use(givenValue).Result;
28+
29+
var child = Randomizer<Child>.Create(childSetup);
30+
Assert.AreEqual(givenValue, child.Value);
31+
}
32+
33+
[TestMethod]
34+
public void UseSetupsAgainForPropertyConfigurations()
35+
{
36+
int givenValue = Randomizer<int>.Create();
37+
38+
var childFiller = new Filler<Child>();
39+
var childSetup = childFiller.Setup().OnProperty(x => x.Value).Use(givenValue).Result;
40+
41+
var parentFiller = new Filler<Parent>();
42+
parentFiller.Setup().OnProperty(x => x.Child).Use(childSetup);
43+
44+
var parent = parentFiller.Create();
45+
Assert.AreEqual(givenValue, parent.Child.Value);
46+
}
47+
48+
[TestMethod]
49+
public void UseSetupsAgainForTypeConfigurations()
50+
{
51+
int givenValue = Randomizer<int>.Create();
52+
53+
var childFiller = new Filler<Child>();
54+
var childSetup = childFiller.Setup().OnProperty(x => x.Value).Use(givenValue).Result;
55+
56+
var parentFiller = new Filler<Parent>();
57+
parentFiller.Setup().OnType<Child>().Use(childSetup);
58+
59+
var parent = parentFiller.Create();
60+
Assert.AreEqual(givenValue, parent.Child.Value);
61+
}
62+
63+
[TestMethod]
64+
public void UseSetupsAgain()
65+
{
66+
int givenValue = Randomizer<int>.Create();
67+
68+
var firstChildFiller = new Filler<Child>();
69+
var childSetup = firstChildFiller.Setup().OnProperty(x => x.Value).Use(givenValue).Result;
70+
71+
var secondChildFiller = new Filler<Child>();
72+
secondChildFiller.Setup(childSetup);
73+
74+
var child = secondChildFiller.Create();
75+
76+
Assert.AreEqual(givenValue, child.Value);
77+
}
78+
79+
80+
}
81+
}

ObjectFiller/Randomizer.cs

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -39,32 +39,7 @@ static Randomizer()
3939
/// <returns>A value of type <see cref="T"/></returns>
4040
public static T Create()
4141
{
42-
Type targetType = typeof(T);
43-
if (!Setup.TypeToRandomFunc.ContainsKey(targetType))
44-
{
45-
if (targetType.IsClass)
46-
{
47-
var fillerType = typeof(Filler<>).MakeGenericType(typeof(T));
48-
var objectFiller = Activator.CreateInstance(fillerType);
49-
var methodInfo = objectFiller.GetType().GetMethods().Single(x => !x.GetParameters().Any() && x.Name == "Create");
50-
51-
try
52-
{
53-
return (T)methodInfo.Invoke(objectFiller, null);
54-
}
55-
catch (Exception ex)
56-
{
57-
throw new InvalidOperationException(
58-
"The type " + typeof(T).FullName + " needs additional information to get created. "
59-
+ "Please use the Filler class and call \"Setup\" to create a setup for that type. See Innerexception for more details.",
60-
ex);
61-
}
62-
}
63-
64-
return default(T);
65-
}
66-
67-
return (T)Setup.TypeToRandomFunc[typeof(T)]();
42+
return Create(null as FillerSetup);
6843
}
6944

7045
/// <summary>
@@ -93,5 +68,56 @@ public static T Create(IRandomizerPlugin<T> randomizerPlugin)
9368
Setup.TypeToRandomFunc[typeof(T)] = () => randomizerPlugin.GetValue();
9469
return randomizerPlugin.GetValue();
9570
}
71+
72+
/// <summary>
73+
/// Creates a factory method for the given type.
74+
/// </summary>
75+
/// <param name="setup">The setup which is used for the type.</param>
76+
/// <returns>A function with which the given type can be instantiated.</returns>
77+
internal static Func<T> CreateFactoryMethod(FillerSetup setup)
78+
{
79+
Type targetType = typeof(T);
80+
if (!Setup.TypeToRandomFunc.ContainsKey(targetType))
81+
{
82+
if (targetType.IsClass)
83+
{
84+
var fillerType = typeof(Filler<>).MakeGenericType(typeof(T));
85+
var objectFiller = Activator.CreateInstance(fillerType);
86+
87+
if (setup != null)
88+
{
89+
var setupMethod = objectFiller.GetType().GetMethods().Single(x => x.Name == "Setup" && x.GetParameters().Any());
90+
setupMethod.Invoke(objectFiller, new[] { setup });
91+
}
92+
93+
var createMethod = objectFiller.GetType().GetMethods().Single(x => !x.GetParameters().Any() && x.Name == "Create");
94+
return () => (T)createMethod.Invoke(objectFiller, null);
95+
}
96+
97+
return () => default(T);
98+
}
99+
100+
return () => (T)Setup.TypeToRandomFunc[typeof(T)]();
101+
}
102+
103+
public static T Create(FillerSetup setup)
104+
{
105+
var creationMethod = CreateFactoryMethod(setup);
106+
107+
T result;
108+
try
109+
{
110+
result = creationMethod();
111+
}
112+
catch (Exception ex)
113+
{
114+
throw new InvalidOperationException(
115+
"The type " + typeof(T).FullName + " needs additional information to get created. "
116+
+ "Please use the Filler class and call \"Setup\" to create a setup for that type. See Innerexception for more details.",
117+
ex);
118+
}
119+
120+
return result;
121+
}
96122
}
97123
}

ObjectFiller/Setup/FluentPropertyApi.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,21 @@ public FluentFillerApi<TTargetObject> Use(Func<TTargetType> randomizerFunc)
107107
return this.callback;
108108
}
109109

110+
/// <summary>
111+
/// Defines which <see cref="FillerSetup"/> is used to generate a value for the given <see cref="TTargetType"/>
112+
/// </summary>
113+
/// <param name="setup">The setup which is used for configuration.</param>
114+
public FluentFillerApi<TTargetObject> Use(FillerSetup setup)
115+
{
116+
foreach (PropertyInfo propertyInfo in this.affectedProperties)
117+
{
118+
var factoryMethod = Randomizer<TTargetType>.CreateFactoryMethod(setup);
119+
this.setupManager.GetFor<TTargetObject>().PropertyToRandomFunc[propertyInfo] = () => factoryMethod();
120+
}
121+
122+
return this.callback;
123+
}
124+
110125
/// <summary>
111126
/// Defines which implementation of the <see cref="IRandomizerPlugin{T}"/> interface will be used to generate a value for the given <see cref="TTargetType"/>
112127
/// </summary>

ObjectFiller/Setup/FluentTypeApi.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,19 @@ public FluentFillerApi<TTargetObject> Use(IEnumerable<TTargetType> enumerable)
8989
return this.Use(new EnumeratorPlugin<TTargetType>(enumerable));
9090
}
9191

92+
/// <summary>
93+
/// With this method you can use a previously defined setup for specific types.
94+
/// </summary>
95+
/// <param name="setup">The setup for the type.</param>
96+
/// <returns>Main FluentFiller API</returns>
97+
public FluentFillerApi<TTargetObject> Use(FillerSetup setup)
98+
{
99+
var factoryMethod = Randomizer<TTargetType>.CreateFactoryMethod(setup);
100+
this.setupManager.GetFor<TTargetObject>().TypeToRandomFunc[typeof(TTargetType)] = () => factoryMethod();
101+
102+
return this.callback;
103+
}
104+
92105
/// <summary>
93106
/// Ignores the entity for which the fluent setup is made (Type, Property)
94107
/// </summary>
@@ -108,7 +121,8 @@ public FluentFillerApi<TTargetObject> IgnoreIt()
108121
public FluentFillerApi<TTargetObject> CreateInstanceOf<TImplementation>()
109122
where TImplementation : class, TTargetType
110123
{
111-
this.setupManager.GetFor<TTargetObject>().InterfaceToImplementation.Add(typeof(TTargetType), typeof(TImplementation));
124+
this.setupManager.GetFor<TTargetObject>()
125+
.InterfaceToImplementation.Add(typeof(TTargetType), typeof(TImplementation));
112126

113127
return this.callback;
114128
}

0 commit comments

Comments
 (0)