diff --git a/CONTRIBUTOR_GUIDELINES.md b/CONTRIBUTOR_GUIDELINES.md new file mode 100644 index 0000000..214b5b0 --- /dev/null +++ b/CONTRIBUTOR_GUIDELINES.md @@ -0,0 +1,11 @@ +Contributor Guidelines +====================== + +Hi! Thank you for your interest in contributing to this open source library! +We ask that you follow the following style guidelines when submitting pull +requests, to keep the code consistent and maintainable. + + - Do not put an if clause and it's statement on the same line: separate them + with a new-line and indent accordingly. + +(This file will be expanded as more guidelines are established by the maintainer) \ No newline at end of file diff --git a/TestStack.Dossier.Tests/BuildTests.cs b/TestStack.Dossier.Tests/BuildTests.cs index 9c6d1d4..010376a 100644 --- a/TestStack.Dossier.Tests/BuildTests.cs +++ b/TestStack.Dossier.Tests/BuildTests.cs @@ -1,4 +1,5 @@ -using Shouldly; +using System.Collections.Generic; +using Shouldly; using TestStack.Dossier.Tests.TestHelpers.Builders; using TestStack.Dossier.Tests.TestHelpers.Objects.Entities; using Xunit; @@ -47,6 +48,32 @@ public void GivenBuilder_WhenCallingSetExplicitly_ShouldOverrideValues() customer.YearJoined.ShouldBe(2014); } + [Fact] + public void GivenBuilder_WhenCallingSetWithLambda_ShouldInvokeEachTime() + { + int counter = 2014; + var builder = new CustomerBuilder() + .Set(x => x.FirstName, "Pi") + .Set(x => x.LastName, "Lanningham") + .Set(x => x.YearJoined, () => counter++); + + var customerA = builder.Build(); + var customerB = builder.Build(); + + customerA.YearJoined.ShouldBe(2014); + customerB.YearJoined.ShouldBe(2015); + + List customerList = CustomerBuilder.CreateListOfSize(10) + .All() + .Set(x => x.YearJoined, () => counter++); + int newCounter = 2016; + foreach (var c in customerList) + { + c.YearJoined.ShouldBe(newCounter++); + } + + } + [Fact] public void GivenBasicBuilder_WhenCallingBuildImplicitly_ThenReturnAnObject() { diff --git a/TestStack.Dossier.Tests/ProxyBuilderTests.cs b/TestStack.Dossier.Tests/ProxyBuilderTests.cs index e62b2a5..c6c662b 100644 --- a/TestStack.Dossier.Tests/ProxyBuilderTests.cs +++ b/TestStack.Dossier.Tests/ProxyBuilderTests.cs @@ -12,7 +12,7 @@ class ProxyBuilderTests [Fact] public void GivenClassToProxyWithNoProperties_WhenBuildingProxy_ReturnAClassWithNoReturnsValuesSet() { - var proxyBuilder = new ProxyBuilder(new Dictionary()); + var proxyBuilder = new ProxyBuilder(new Dictionary>()); var proxy = proxyBuilder.Build(); @@ -24,7 +24,7 @@ public void GivenClassToProxyWithNoProperties_WhenBuildingProxy_ReturnAClassWith [Fact] public void GivenClassToProxyWithNoProperties_WhenBuildingProxy_ReturnAnNSubstituteProxyOfThatClass() { - var proxyBuilder = new ProxyBuilder(new Dictionary()); + var proxyBuilder = new ProxyBuilder(new Dictionary>()); var proxy = proxyBuilder.Build(); @@ -32,13 +32,14 @@ public void GivenClassToProxyWithNoProperties_WhenBuildingProxy_ReturnAnNSubstit } [Fact] - public void GivenClassToProxyWithSinglePropertyValue_WhenBuildingProxy_ReturnAClassWithReturnValueSet() + public void GivenClassToProxyWithSinglePropertyValue_WhenBuildingProxy_ReturnAClassWithReturnValueSetFromFunction() { - var proxyBuilder = new ProxyBuilder(new Dictionary {{"FirstName", "FirstName"}}); + int nonce = new Random().Next(0, 100); + var proxyBuilder = new ProxyBuilder(new Dictionary> {{"FirstName", () => "FirstName" + nonce}}); var proxy = proxyBuilder.Build(); - proxy.FirstName.ShouldBe("FirstName"); + proxy.FirstName.ShouldBe("FirstName" + nonce); proxy.LastName.ShouldBe(string.Empty); proxy.YearJoined.ShouldBe(0); } @@ -46,11 +47,11 @@ public void GivenClassToProxyWithSinglePropertyValue_WhenBuildingProxy_ReturnACl [Fact] public void GivenClassToProxyWithMultiplePropertyValues_WhenBuildingProxy_ReturnAClassWithReturnValueSet() { - var proxyBuilder = new ProxyBuilder(new Dictionary + var proxyBuilder = new ProxyBuilder(new Dictionary> { - { "FirstName", "FirstName" }, - { "LastName", "LastName" }, - { "YearJoined", 1 }, + { "FirstName", () => "FirstName" }, + { "LastName", () => "LastName" }, + { "YearJoined", () => 1 }, } ); @@ -64,10 +65,10 @@ public void GivenClassToProxyWithMultiplePropertyValues_WhenBuildingProxy_Return [Fact] public void GivenClassWithSomeVirtualProperties_WhenBuildingProxy_ThenOnlyVirtualMembersAreProxied() { - var proxyBuilder = new ProxyBuilder(new Dictionary() + var proxyBuilder = new ProxyBuilder(new Dictionary>() { - {"Name", "Vandelay Industries"}, - {"EmployeeCount", 100} + {"Name", () => "Vandelay Industries"}, + {"EmployeeCount", () => 100} }); var proxy = proxyBuilder.Build(); diff --git a/TestStack.Dossier/ProxyBuilder.cs b/TestStack.Dossier/ProxyBuilder.cs index 5a7ff05..0efd431 100644 --- a/TestStack.Dossier/ProxyBuilder.cs +++ b/TestStack.Dossier/ProxyBuilder.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Reflection; using NSubstitute; @@ -11,13 +12,13 @@ namespace TestStack.Dossier /// The type being proxied public class ProxyBuilder where T : class { - private readonly Dictionary _properties; + private readonly Dictionary> _properties; /// /// Create a proxy builder to proxy the given property values for the type {T}. /// /// - public ProxyBuilder(Dictionary properties) + public ProxyBuilder(Dictionary> properties) { _properties = properties; } @@ -33,7 +34,7 @@ public T Build() foreach (var property in properties.Where(property => _properties.ContainsKey(property.Name))) { if (property.GetGetMethod().IsVirtual) - property.GetValue(proxy, null).Returns(_properties[property.Name]); + property.GetValue(proxy, null).Returns(_properties[property.Name]()); } return proxy; diff --git a/TestStack.Dossier/TestDataBuilder.cs b/TestStack.Dossier/TestDataBuilder.cs index 50e1167..24edb91 100644 --- a/TestStack.Dossier/TestDataBuilder.cs +++ b/TestStack.Dossier/TestDataBuilder.cs @@ -15,7 +15,7 @@ public abstract class TestDataBuilder where TObject : class where TBuilder : TestDataBuilder, new() { - private readonly Dictionary _properties = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + private readonly Dictionary> _properties = new Dictionary>(); private ProxyBuilder _proxyBuilder; /// @@ -107,16 +107,30 @@ public TBuilder AsProxy() /// /// The proxy object protected virtual void AlterProxy(TObject proxy) {} - + /// /// Records the given value for the given property from {TObject} and returns the builder to allow chaining. /// /// The type of the property /// A lambda expression specifying the property to record a value for - /// The builder so that other method calls can be chained + /// The value to set the property to + /// The builder so that other method calls can be chained public virtual TBuilder Set(Expression> property, TValue value) { - _properties[Reflector.GetPropertyNameFor(property)] = value; + _properties[Reflector.GetPropertyNameFor(property)] = () => value; + return this as TBuilder; + } + + /// + /// Records a given value provider for the given property from {TObject} and returns the builder to allow chaining. + /// + /// The type of the property + /// A lambda expression specifying the property to record a value for + /// A method which produces instances of {TValue} for the property. + /// The builder so that other method calls can be chained + public virtual TBuilder Set(Expression> property, Func factory) + { + _properties[Reflector.GetPropertyNameFor(property)] = () => factory() as object; return this as TBuilder; } @@ -129,10 +143,7 @@ public virtual TBuilder Set(Expression> property, /// The recorded value of the property or an anonymous value for it public TValue Get(Expression> property) { - if (!Has(property)) - return Any.Get(property); - - return (TValue)_properties[Reflector.GetPropertyNameFor(property)]; + return (TValue)Get(typeof (TValue), Reflector.GetPropertyNameFor(property)); } /// @@ -144,9 +155,11 @@ public TValue Get(Expression> property) /// public object Get(Type type, string propertyName) { - if (!Has(propertyName)) - return Any.Get(type, propertyName); - return _properties[propertyName]; + Func factory; + if (_properties.TryGetValue(propertyName, out factory)) + return factory(); + + return Any.Get(type, propertyName); } ///