diff --git a/NextVersion.txt b/NextVersion.txt index 359a5b9..50aea0e 100644 --- a/NextVersion.txt +++ b/NextVersion.txt @@ -1 +1 @@ -2.0.0 \ No newline at end of file +2.1.0 \ No newline at end of file diff --git a/README.md b/README.md index 2e824d1..4851392 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,26 @@ Then you either need to: * Make your builder class public * Add the following to your `AssemblyInfo.cs` file: `[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]` +Create Entities Implicitly +-------------------------- +In the previous examples, you have seen how to create entities *explicitly*, by calling the `Build()` and `BuildList()` methods. For the ultimate in terseness, you can omit these methods, and Dossier will *implicitly* call them for you. The one caveat is that you must explicitly declare the variable type rather than using the `var` keyword. + +So, to create a single entity: + + Customer customer = new CustomerBuilder(); + + Customer customer = new CustomerBuilder() + .WithFirstName("Matt") + .WithLastName("Kocaj") + .WhoJoinedIn(2010); + +Or to create a list of entities: + + List entities = BasicCustomerBuilder.CreateListOfSize(5); + + List data = CustomerBuilder.CreateListOfSize(3) + .All().With(b => b.WithFirstName(generator.Generate().ToString())); + Anonymous Values and Equivalence Classes ---------------------------------------- diff --git a/TestStack.Dossier.Tests/BuildListTests.cs b/TestStack.Dossier.Tests/BuildListTests.cs index 6dd0cee..2b498db 100644 --- a/TestStack.Dossier.Tests/BuildListTests.cs +++ b/TestStack.Dossier.Tests/BuildListTests.cs @@ -28,7 +28,7 @@ public void GivenAListBuilderProxyInstance_WhenCallingIsListBuilderProxy_ThenRet } [Fact] - public void GivenListOfBuilders_WhenCallingBuildList_ThenAListOfEntitiesOfTheRightSizeShouldBeReturned() + public void GivenListOfBuilders_WhenCallingBuildListExplicitly_ThenAListOfEntitiesOfTheRightSizeShouldBeReturned() { var builders = BasicCustomerBuilder.CreateListOfSize(5); @@ -38,7 +38,15 @@ public void GivenListOfBuilders_WhenCallingBuildList_ThenAListOfEntitiesOfTheRig } [Fact] - public void GivenListOfBuilders_WhenCallingBuildList_ThenAListOfEntitiesOfTheRightTypeShouldBeReturned() + public void GivenListOfBuilders_WhenCallingBuildListImplicitly_ThenAListOfEntitiesOfTheRightSizeShouldBeReturned() + { + List entities = BasicCustomerBuilder.CreateListOfSize(5); + + entities.Count.ShouldBe(5); + } + + [Fact] + public void GivenListOfBuilders_WhenCallingBuildListExplicitly_ThenAListOfEntitiesOfTheRightTypeShouldBeReturned() { var builders = BasicCustomerBuilder.CreateListOfSize(5); @@ -48,7 +56,15 @@ public void GivenListOfBuilders_WhenCallingBuildList_ThenAListOfEntitiesOfTheRig } [Fact] - public void GivenListOfBuilders_WhenCallingBuildList_ThenAListOfUniqueEntitiesShouldBeReturned() + public void GivenListOfBuilders_WhenCallingBuildListImplicitly_ThenAListOfEntitiesOfTheRightTypeShouldBeReturned() + { + List entities = BasicCustomerBuilder.CreateListOfSize(5); + + entities.ShouldBeAssignableTo>(); + } + + [Fact] + public void GivenListOfBuilders_WhenCallingBuildListExplicitly_ThenAListOfUniqueEntitiesShouldBeReturned() { var builders = BasicCustomerBuilder.CreateListOfSize(5); @@ -67,7 +83,24 @@ public void GivenListOfBuilders_WhenCallingBuildList_ThenAListOfUniqueEntitiesSh } [Fact] - public void GivenListOfBuildersWithCustomisation_WhenBuildingEntities_ThenTheCustomisationShouldTakeEffect() + public void GivenListOfBuilders_WhenCallingBuildListImplicitly_ThenAListOfUniqueEntitiesShouldBeReturned() + { + List entities = BasicCustomerBuilder.CreateListOfSize(5); + + entities[0].ShouldNotBe(entities[1]); + entities[0].ShouldNotBe(entities[2]); + entities[0].ShouldNotBe(entities[3]); + entities[0].ShouldNotBe(entities[4]); + entities[1].ShouldNotBe(entities[2]); + entities[1].ShouldNotBe(entities[3]); + entities[1].ShouldNotBe(entities[4]); + entities[2].ShouldNotBe(entities[3]); + entities[2].ShouldNotBe(entities[4]); + entities[3].ShouldNotBe(entities[4]); + } + + [Fact] + public void GivenListOfBuildersWithCustomisation_WhenBuildingEntitiesExplicitly_ThenTheCustomisationShouldTakeEffect() { var generator = new SequentialGenerator(0, 100); var list = CustomerBuilder.CreateListOfSize(3) @@ -80,7 +113,19 @@ public void GivenListOfBuildersWithCustomisation_WhenBuildingEntities_ThenTheCus } [Fact] - public void GivenListOfBuildersWithARangeOfCustomisationMethods_WhenBuildingEntities_ThenThenTheListIsBuiltAndModifiedCorrectly() + public void GivenListOfBuildersWithCustomisation_WhenBuildingEntitiesImplicitly_ThenTheCustomisationShouldTakeEffect() + { + var generator = new SequentialGenerator(0, 100); + + List data = CustomerBuilder.CreateListOfSize(3) + .All().With(b => b.WithFirstName(generator.Generate().ToString())); + + data.Select(c => c.FirstName).ToArray() + .ShouldBe(new[] { "0", "1", "2" }); + } + + [Fact] + public void GivenListOfBuildersWithARangeOfCustomisationMethods_WhenBuildingEntitiesExplicitly_ThenThenTheListIsBuiltAndModifiedCorrectly() { var i = 0; var customers = CustomerBuilder.CreateListOfSize(5) @@ -102,7 +147,28 @@ public void GivenListOfBuildersWithARangeOfCustomisationMethods_WhenBuildingEnti } [Fact] - public void WhenBuildingEntities_ThenTheAnonymousValueFixtureIsSharedAcrossBuilders() + public void GivenListOfBuildersWithARangeOfCustomisationMethods_WhenBuildingEntitiesImplicitly_ThenThenTheListIsBuiltAndModifiedCorrectly() + { + var i = 0; + List customers = CustomerBuilder.CreateListOfSize(5) + .TheFirst(1).WithFirstName("First") + .TheNext(1).WithLastName("Next Last") + .TheLast(1).WithLastName("Last Last") + .ThePrevious(2).With(b => b.WithLastName("last" + (++i).ToString())) + .All().WhoJoinedIn(1999); + + customers.ShouldBeAssignableTo>(); + customers.Count.ShouldBe(5); + customers[0].FirstName.ShouldBe("First"); + customers[1].LastName.ShouldBe("Next Last"); + customers[2].LastName.ShouldBe("last1"); + customers[3].LastName.ShouldBe("last2"); + customers[4].LastName.ShouldBe("Last Last"); + customers.ShouldAllBe(c => c.YearJoined == 1999); + } + + [Fact] + public void WhenBuildingEntitiesExplicitly_ThenTheAnonymousValueFixtureIsSharedAcrossBuilders() { var customers = CustomerBuilder.CreateListOfSize(5).BuildList(); @@ -112,5 +178,17 @@ public void WhenBuildingEntities_ThenTheAnonymousValueFixtureIsSharedAcrossBuild customers[3].CustomerClass.ShouldBe(CustomerClass.Gold); customers[4].CustomerClass.ShouldBe(CustomerClass.Platinum); } + + [Fact] + public void WhenBuildingEntitiesImplicitly_ThenTheAnonymousValueFixtureIsSharedAcrossBuilders() + { + List customers = CustomerBuilder.CreateListOfSize(5); + + customers[0].CustomerClass.ShouldBe(CustomerClass.Normal); + customers[1].CustomerClass.ShouldBe(CustomerClass.Bronze); + customers[2].CustomerClass.ShouldBe(CustomerClass.Silver); + customers[3].CustomerClass.ShouldBe(CustomerClass.Gold); + customers[4].CustomerClass.ShouldBe(CustomerClass.Platinum); + } } } diff --git a/TestStack.Dossier.Tests/BuildTests.cs b/TestStack.Dossier.Tests/BuildTests.cs index ccf305a..c2fcdf6 100644 --- a/TestStack.Dossier.Tests/BuildTests.cs +++ b/TestStack.Dossier.Tests/BuildTests.cs @@ -8,7 +8,7 @@ namespace TestStack.Dossier.Tests public class BuildTests { [Fact] - public void GivenBasicBuilder_WhenCallingBuild_ThenReturnAnObject() + public void GivenBasicBuilder_WhenCallingBuildExplicitly_ThenReturnAnObject() { var builder = new BasicCustomerBuilder(); @@ -18,7 +18,7 @@ public void GivenBasicBuilder_WhenCallingBuild_ThenReturnAnObject() } [Fact] - public void GivenBuilderWithMethodCalls_WhenCallingBuild_ThenReturnAnObjectWithTheConfiguredParameters() + public void GivenBuilderWithMethodCalls_WhenCallingBuildExplicitly_ThenReturnAnObjectWithTheConfiguredParameters() { var builder = new CustomerBuilder() .WithFirstName("Matt") @@ -33,7 +33,7 @@ public void GivenBuilderWithMethodCalls_WhenCallingBuild_ThenReturnAnObjectWithT } [Fact] - public void GivenBuilder_WhenCallingSet_ShouldOverrideValues() + public void GivenBuilder_WhenCallingSetExplicitly_ShouldOverrideValues() { var builder = new CustomerBuilder() .Set(x => x.FirstName, "Pi") @@ -46,5 +46,39 @@ public void GivenBuilder_WhenCallingSet_ShouldOverrideValues() customer.LastName.ShouldBe("Lanningham"); customer.YearJoined.ShouldBe(2014); } + + [Fact] + public void GivenBasicBuilder_WhenCallingBuildImplicitly_ThenReturnAnObject() + { + Customer customer = new BasicCustomerBuilder(); + + customer.ShouldBeOfType(); + } + + [Fact] + public void GivenBuilderWithMethodCalls_WhenCallingBuildImplicitly_ThenReturnAnObjectWithTheConfiguredParameters() + { + Customer customer = new CustomerBuilder() + .WithFirstName("Matt") + .WithLastName("Kocaj") + .WhoJoinedIn(2010); + + customer.FirstName.ShouldBe("Matt"); + customer.LastName.ShouldBe("Kocaj"); + customer.YearJoined.ShouldBe(2010); + } + + [Fact] + public void GivenBuilder_WhenCallingSetImplicitly_ShouldOverrideValues() + { + Customer customer = new CustomerBuilder() + .Set(x => x.FirstName, "Pi") + .Set(x => x.LastName, "Lanningham") + .Set(x => x.YearJoined, 2014); + + customer.FirstName.ShouldBe("Pi"); + customer.LastName.ShouldBe("Lanningham"); + customer.YearJoined.ShouldBe(2014); + } } -} +} \ No newline at end of file diff --git a/TestStack.Dossier/Lists/ListBuilder.cs b/TestStack.Dossier/Lists/ListBuilder.cs index aa7cbda..370a800 100644 --- a/TestStack.Dossier/Lists/ListBuilder.cs +++ b/TestStack.Dossier/Lists/ListBuilder.cs @@ -115,6 +115,15 @@ public IList BuildList() return _list.Select(b => b.Build()).ToArray(); } + /// + /// Builds the list of objects with implicit conversion operator. + /// + /// The built object + public static implicit operator List(ListBuilder builder) + { + return builder.BuildList().ToList(); + } + internal void Execute(IInvocation invocation) { _list.Skip(_start) diff --git a/TestStack.Dossier/TestDataBuilder.cs b/TestStack.Dossier/TestDataBuilder.cs index 4a4097e..078be5d 100644 --- a/TestStack.Dossier/TestDataBuilder.cs +++ b/TestStack.Dossier/TestDataBuilder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Linq.Expressions; using TestStack.Dossier.Lists; @@ -51,6 +52,24 @@ public TObject Build() return BuildObject(); } + /// + /// Builds the object with implicit conversion operator. + /// + /// The built object + public static implicit operator TObject(TestDataBuilder builder) + { + return builder.Build(); + } + + /// + /// Builds the list of objects with implicit conversion operator. + /// + /// The built object + public static implicit operator List(TestDataBuilder builder) + { + return builder.ListBuilder; + } + /// /// Build the actual object - override this and call the constructor and any other methods. ///