diff --git a/.gitignore b/.gitignore index 6ea0185..550e699 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,7 @@ _ReSharper.* packages *.DotSettings *.ncrunchproject -*.ncrunchsolution \ No newline at end of file +*.ncrunchsolution + +# Visual Studio 2015 cache/options directory +.vs/ \ No newline at end of file diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md index 832cee6..cce0177 100644 --- a/BREAKING_CHANGES.md +++ b/BREAKING_CHANGES.md @@ -1,7 +1,65 @@ Breaking Changes ================ -Breaking change from NTestDataBuilder -> TestStack.Dossier 1.0 +Version 3.3 +----------- +The classes inheriting from `FileDictionarySource` have been marked as obsolete and will be removed in version 4. Instead you should use the new `Words` class, passing in the name of a file dictionary (either one of the built-in ones or one that you create). All the built-in ones are listed in the FromDictionary class where the constants match the filename embedded into Dossier. So, for example, instead of using the `GeoCountrySource` class you would instead use `Words(FromDictionary.GeoCountry)`. + +All of the file dictionaries have been added to the AnonymousValueFixture class as equivalence class extension methods. So, for example, in your builder class you can now call: + +```c# +Any.InternetURL(); +Any.LoremIpsum(); +Any.ColourName(); +``` + +Picking functionality has been added which allows you to select items from a list according to different strategies. Currently, two strategies have been added, `RandomItemFrom` and `RepeatingSequenceFrom`: + +```c# +var names = new Words(FromDictionary.PersonNameFirst).Data; +var days = new List {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"}; +var customers = Builder + .CreateListOfSize(15) + .All() + .Set(x => x.Name, Pick.RandomItemFrom(names).Next) + .Set(x => x.Day, Pick.RepeatingSequenceFrom(days).Next) + .BuildList(); +``` + +Version 3.0 +----------- + +The signature of `IAnonymousValueSupplier` has changed from: + +```c# +public interface IAnonymousValueSupplier +{ + bool CanSupplyValue(Type type, string propertyName); + TValue GenerateAnonymousValue(AnonymousValueFixture any, string propertyName); +} +``` + +To: + +```c# +public interface IAnonymousValueSupplier +{ + bool CanSupplyValue(Type type, string propertyName); + object GenerateAnonymousValue(AnonymousValueFixture any, Type type, string propertyName); +} +``` + +Note: the `CanSupplyValue` method and the `GenerateAnonymousValue` method are no longer generic. + +### Reason + +In order to implement the `BuildUsing` method that allows you to build an object by convention in one line rather than having to call the constructor yourself we needed to have a non-generic version of the methods. This change actually ended up making the anonymous value suppliers slightly easier to implement (no longer any need for type casting). + +### Fix + +If you have any custom anonymous value suppliers change the signature of your `CanSupplyValue` and `GenerateAnonymousValue` methods so they are no longer generic. + +Breaking change from NTestDataBuilder -> TestStack.Dossier 2.0 -------------------------------------------------------------- Namespace has changed from NTestDataBuilder to TestStack.Dossier. @@ -14,7 +72,7 @@ The project has been renamed. Do a global find and replace of `using NTestDataBuilder` with `using TestStack.Dossier`. -Breaking change from NTestDataBuilder -> TestStack.Dossier 1.0 +Breaking change from NTestDataBuilder -> TestStack.Dossier 2.0 -------------------------------------------------------------- When you don't `Set` a default value for a property that you later `Get` in your builder it will now generate an anonymous value for that property rather than throwing an exception. @@ -29,7 +87,7 @@ The old behaviour of throwing an exception if a value hasn't been specified is n If you want to fix a static value for a property then by all means you can still use `Set` calls in your builder constructor. If you aren't happy with the default anonymous value that is generated for a property you can use the `Any` property to generate a value from a different equivalence class in combination with a `Set` call in your builder constructor. -Breaking change from NTestDataBuilder -> TestStack.Dossier 1.0 +Breaking change from NTestDataBuilder -> TestStack.Dossier 2.0 -------------------------------------------------------------- The way that lists are generated no longer uses NBuilder - the new syntax is backwards compatible with NBuilder except that the namespace you need to include is different. You can also refactor your list generation to be a lot more terse, but that is optional. Any `BuildList` extension methods you created will now need to be deleted since they are no longer needed. You also need to ensure that all of the methods you call are marked virtual so the list generation can proxy those method calls. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..506dae4 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,15 @@ +Contributor Guidelines +====================== + +Hi! Thank you for your interest in contributing to this open source library! + +We welcome issues and pull requests. If you are starting on something major +please raise an issue first so we can discuss it with you, make sure it fits +in with the direction of the project and provide appropriate assistance :) + +We ask that you follow the following style guidelines when submitting pull +requests, to keep the code consistent and maintainable. + + - In general - follow the default ReSharper suggestions + - Do not put a single line if clause on the same line as the if statement it + belongs to; separate them with a new-line and an indent diff --git a/GitVersionConfig.yaml b/GitVersionConfig.yaml new file mode 100644 index 0000000..ae18bd7 --- /dev/null +++ b/GitVersionConfig.yaml @@ -0,0 +1,3 @@ +mode: ContinuousDelivery +next-version: 3.4.0 +branches: {} diff --git a/NextVersion.txt b/NextVersion.txt deleted file mode 100644 index 50aea0e..0000000 --- a/NextVersion.txt +++ /dev/null @@ -1 +0,0 @@ -2.1.0 \ No newline at end of file diff --git a/NuGet.config b/NuGet.config new file mode 100644 index 0000000..3f0e003 --- /dev/null +++ b/NuGet.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index f0b394d..69515f4 100644 --- a/README.md +++ b/README.md @@ -1,225 +1,162 @@ # TestStack.Dossier -TestStack.Dossier provides you with the code infrastructure to easily and quickly generate test fixture data for your automated tests in a terse, readable and maintainable way using the Test Data Builder pattern. +[![Build status](https://ci.appveyor.com/api/projects/status/h8d3xulha7ecwb6m/branch/master?svg=true)](https://ci.appveyor.com/project/MRCollective/nhibernate-sqlazure) +[![NuGet downloads](https://img.shields.io/nuget/dt/TestStack.Dossier.svg)](https://www.nuget.org/packages/TestStack.Dossier) +[![NuGet version](https://img.shields.io/nuget/vpre/TestStack.Dossier.svg)](https://www.nuget.org/packages/TestStack.Dossier) +[![Documentation](https://img.shields.io/badge/docs-up%20to%20date-green.svg)](http://dossier.teststack.net/) -For more information please see the [blog post](http://robdmoore.id.au/blog/2013/05/26/test-data-generation-the-right-way-object-mother-test-data-builders-nsubstitute-nbuilder/) that gives the theory behind the approach this library was intended for and the [presentation and example code](https://github.com/robdmoore/TestFixtureDataGenerationPresentation) that gives a concrete example of the usage of the library (and the theory behind it). +TestStack.Dossier provides you with the code infrastructure to easily and quickly generate test fixture data for your automated tests in a terse, readable and maintainable way using the Test Data Builder, anonymous value and equivalence class patterns. + +For more information please see the [blog post](https://robdmoore.id.au/blog/2013/05/25/test-data-generation-the-right-way-object-mother-test-data-builders-nsubstitute-nbuilder) that gives the theory behind the approach this library was intended for and the [presentation and example code](https://github.com/robdmoore/TestFixtureDataGenerationPresentation) that gives a concrete example of the usage of the library (and the theory behind it). TestStack.Dossier is integrated with NSubstitute for proxy/mock/substitute object generation and AutoFixture for anonymous value generation. Version 1 was integrated with NBuilder for list generation, but that is now replaced with internal code that uses Castle Dynamic Proxy (il-merged into the dll) for an even terser syntax. Prior to v2.0 this library was known as NTestDataBuilder. -## How do I get started? +## Getting started - building a single object 1. `Install-Package TestStack.Dossier` -2. Create a builder class for one of your objects, e.g. if you have a customer: - - // Customer.cs - - public class Customer - { - protected Customer() {} - - public Customer(string firstName, string lastName, int yearJoined) - { - if (string.IsNullOrEmpty(firstName)) - throw new ArgumentNullException("firstName"); - if (string.IsNullOrEmpty(lastName)) - throw new ArgumentNullException("lastName"); - - FirstName = firstName; - LastName = lastName; - YearJoined = yearJoined; - } - - public virtual int CustomerForHowManyYears(DateTime since) - { - if (since.Year < YearJoined) - throw new ArgumentException("Date must be on year or after year that customer joined.", "since"); - return since.Year - YearJoined; - } - - public virtual string FirstName { get; private set; } - public virtual string LastName { get; private set; } - public virtual int YearJoined { get; private set; } - } - - // CustomerBuilder.cs - - public class CustomerBuilder : TestDataBuilder - { - public CustomerBuilder() - { - // Can set up defaults here - any that you don't set will have an anonymous value generated by default. - WhoJoinedIn(2013); - } - - public CustomerBuilder WithFirstName(string firstName) - { - return Set(x => x.FirstName, firstName); - } - - public CustomerBuilder WithLastName(string lastName) - { - return Set(x => x.LastName, lastName); - } - - public CustomerBuilder WhoJoinedIn(int yearJoined) - { - return Set(x => x.YearJoined, yearJoined); - } - - protected override Customer BuildObject() - { - return new Customer( - Get(x => x.FirstName), - Get(x => x.LastName), - Get(x => x.YearJoined) - ); - } - } - -Note that overriding the BuildObject is optional. It can be useful to do this if you want full control over how your object is constructed, for example if you want to use a particular constructor. If you don't choose to override this method then Dossier will create the object for you. - -3. Use the builder in a test, e.g. - - var customer = new CustomerBuilder().WithFirstName("Robert").Build(); - -4. Consider using the Object Mother pattern in combination with the builders, see [my blog post](http://robdmoore.id.au/blog/2013/05/26/test-data-generation-the-right-way-object-mother-test-data-builders-nsubstitute-nbuilder/) for a description of how I use this library. - -How can I create a list of entities using my builders? ------------------------------------------------------- - -This library allows you to build a list of entities fluently and tersely. Here is an example: - -```c# - var 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) - .BuildList(); -``` - -This would create the following (represented as json): - -```json -[ - { - "FirstName":"First", - "LastName":"LastNameff51d5e5-9ce4-4710-830e-9042cfd48a8b", - "YearJoined":1999 - }, - { - "FirstName":"FirstName7b08da9c-8c13-47f7-abe9-09b73b935e1f", - "LastName":"Next Last", - "YearJoined":1999 - }, - { - "FirstName":"FirstName836d4c54-b227-4c1b-b684-de4cd940c251", - "LastName":"last1", - "YearJoined":1999 - }, - { - "FirstName":"FirstName5f53e895-921e-4130-8ed8-610b017f3b9b", - "LastName":"last2", - "YearJoined":1999 - }, - { - "FirstName":"FirstName9cf6b05f-38aa-47c1-9fd7-e3c1009cf3e4", - "LastName":"Last Last", - "YearJoined":1999 - } -] -``` -### Castle Dynamic Proxy Generator Exception error - -If you use the list builder functionality and get the following error: - -> Castle.DynamicProxy.Generators.GeneratorExceptionCan not create proxy for type because it is not accessible. Make it public, or internal and mark your assembly with [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] attribute, because assembly is not strong-named. - -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 ----------------------------------------- - -todo: Coming soon! +2. Are you building a DTO, view model, or other class you don't want to write a custom + test data builder class for? If so then check out our [generic test data builder implementation](http://dossier.teststack.net/v1.0/docs/create-object-without-requiring-custom-builder-cla) -How can I create proxy objects? -------------------------------- - -This library integrates with [NSubstitute](http://nsubstitute.github.io/) for generating proxy objects, this means you can call the `AsProxy` method on your builder to request that the result from calling `Build` will be an NSubstitute proxy with the public properties set to return the values you have specified via your builder, e.g. - - var customer = CustomerBuilder.WithFirstName("Rob").AsProxy().Build(); - customer.CustomerForHowManyYears(Arg.Any()).Returns(10); - var name = customer.FirstName; // "Rob" - var years = customer.CustomerForHowManyYears(DateTime.Now); // 10 - -If you need to alter the proxy before calling `Build` to add complex behaviours that can't be expressed by the default public properties returns values then you can override the `AlterProxy` method in your builder, e.g. - -```c# - class CustomerBuilder : TestDataBuilder - { - // ... - - private int _years; +3. If you want to build a custom builder class, e.g. for a domain object, so you can use the builder + as documentation and also to make the experience of building that class in your tests more rich + then you need to extend the TestDataBuilder class like in the following code example: +```csharp + // Customer.cs - public CustomerBuilder HasBeenMemberForYears(int years) + public class Customer { - _years = years; - return this; + protected Customer() {} + + public Customer(string firstName, string lastName, int yearJoined) + { + if (string.IsNullOrEmpty(firstName)) + throw new ArgumentNullException("firstName"); + if (string.IsNullOrEmpty(lastName)) + throw new ArgumentNullException("lastName"); + + FirstName = firstName; + LastName = lastName; + YearJoined = yearJoined; + } + + public virtual int CustomerForHowManyYears(DateTime since) + { + if (since.Year < YearJoined) + throw new ArgumentException("Date must be on year or after year that customer joined.", "since"); + return since.Year - YearJoined; + } + + public virtual string FirstName { get; private set; } + public virtual string LastName { get; private set; } + public virtual int YearJoined { get; private set; } } - protected override void AlterProxy(Customer proxy) + // CustomerBuilder.cs + + // Yep - you have to provide the custom builder type in as a generic type argument + // it's a bit weird, but necessary for the fluent chaining to work from the base class + public class CustomerBuilder : TestDataBuilder { - proxy.CustomerForHowManyYears(Arg.Any()).Returns(_years); - } + public CustomerBuilder() + { + // Can set up defaults here - any that you don't set or subsequently override + // will have an anonymous value generated by default + WhoJoinedIn(2013); + } - // ... - } - - // Then in your test you can use: - - var customer = new CustomerBuilder().AsProxy().HasBeenMemberForYears(10); - var years = customer.CustomerForHowManyYears(DateTime.Now); // 10 + // Note: the methods are virtual - this is important if you want to build lists (as per below) + public virtual CustomerBuilder WithFirstName(string firstName) + { + return Set(x => x.FirstName, firstName); + } + + // Note: we typically only start with the methods that are strictly needed so the + // builders are quick to write and aren't bloated + public virtual CustomerBuilder WithLastName(string lastName) + { + return Set(x => x.LastName, lastName); + } + + public virtual CustomerBuilder WhoJoinedIn(int yearJoined) + { + return Set(x => x.YearJoined, yearJoined); + } + + // This method is optional, by default it uses `BuildUsing()` + protected override Customer BuildObject() + { + return BuildUsing(); + // or, if you need more control / can't use the auto-construction assumptions + return new Customer( + Get(x => x.FirstName), + Get(x => x.LastName), + Get(x => x.YearJoined) + ); + } + } +``` +4. Use the builder in a test, e.g. +```csharp + var customer = new CustomerBuilder() + .WithFirstName("Robert") + .Build(); ``` +5. Consider using the Object Mother pattern in combination with the builders, see [my blog post](http://robdmoore.id.au/blog/2013/05/26/test-data-generation-the-right-way-object-mother-test-data-builders-nsubstitute-nbuilder/) for a description of how I use this library. + +## Getting started - building a list of objects -*Remember that when using proxy objects of real classes that you need to mark properties and methods as virtual and have a protected empty constructor.* +This library allows you to build a list of entities fluently and tersely. Here is an example: +```csharp + var 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) + .BuildList(); +``` +This would create the following (represented as json) - note the anonymous values that are generated: +```json + [ + { + "FirstName":"First", + "LastName":"LastNameff51d5e5-9ce4-4710-830e-9042cfd48a8b", + "YearJoined":1999 + }, + { + "FirstName":"FirstName7b08da9c-8c13-47f7-abe9-09b73b935e1f", + "LastName":"Next Last", + "YearJoined":1999 + }, + { + "FirstName":"FirstName836d4c54-b227-4c1b-b684-de4cd940c251", + "LastName":"last1", + "YearJoined":1999 + }, + { + "FirstName":"FirstName5f53e895-921e-4130-8ed8-610b017f3b9b", + "LastName":"last2", + "YearJoined":1999 + }, + { + "FirstName":"FirstName9cf6b05f-38aa-47c1-9fd7-e3c1009cf3e4", + "LastName":"Last Last", + "YearJoined":1999 + } + ] +``` -Why does TestStack.Dossier have NSubstitute and AutoFixture as dependencies? ------------------------------------------------------------------------- +The same works with the generic `Builder` implementation too. -TestStack.Dossier is an opinionated framework and as such prescribes how to build your fixture data, including how to build lists, anonymous data and mock objects. Because of this we have decided to bundle it with the best of breed libraries for this purpose: AutoFixture and NSubstitute. +## Documentation -This allows for this library to provide a rich value-add on top of the basics of tracking properties in a dictionary in the `TestDataBuilder` base class. If you want to use different libraries or want a cut down version that doesn't come with NSubstitute or AutoFixture and the extra functionality they bring then take the `TestDataBuilder.cs` file and cut out the bits you don't want - open source ftw :). +More comprehensive documentation is available on our [documentation website](http://dossier.teststack.net/). -If you have a suggestion for the library that can incorporate this value-add without bundling these libraries feel free to submit a pull request. +## Contributions / Questions -Contributions / Questions -------------------------- +If you would like to contribute to this project then feel free to communicate with us via Twitter ([@teststacknet](https://twitter.com/teststacknet)) or alternatively submit a [pull request](https://github.com/TestStack/TestStack.Dossier/compare/) / [issue](https://github.com/TestStack/TestStack.Dossier/issues/new). -If you would like to contribute to this project then feel free to communicate with me via Twitter @robdmoore or alternatively submit a pull request / issue. +Feel free to check out our [up-for-grabs issues if you don't know where to start](https://github.com/TestStack/TestStack.Dossier/labels/up-for-grabs). diff --git a/TestStack.Dossier.Tests/AsProxyTests.cs b/TestStack.Dossier.Tests/AsProxyTests.cs index ddf8036..4711568 100644 --- a/TestStack.Dossier.Tests/AsProxyTests.cs +++ b/TestStack.Dossier.Tests/AsProxyTests.cs @@ -1,7 +1,7 @@ using System; using NSubstitute; using Shouldly; -using TestStack.Dossier.Tests.Builders; +using TestStack.Dossier.Tests.TestHelpers.Builders; using Xunit; namespace TestStack.Dossier.Tests diff --git a/TestStack.Dossier.Tests/Assembly.cs b/TestStack.Dossier.Tests/Assembly.cs new file mode 100644 index 0000000..7db8497 --- /dev/null +++ b/TestStack.Dossier.Tests/Assembly.cs @@ -0,0 +1,3 @@ +using Xunit; + +[assembly: CollectionBehavior(DisableTestParallelization = true)] \ No newline at end of file diff --git a/TestStack.Dossier.Tests/BuildListTests.cs b/TestStack.Dossier.Tests/BuildListTests.cs index e2651b2..4c8ad8b 100644 --- a/TestStack.Dossier.Tests/BuildListTests.cs +++ b/TestStack.Dossier.Tests/BuildListTests.cs @@ -3,8 +3,8 @@ using Shouldly; using TestStack.Dossier.DataSources.Generators; using TestStack.Dossier.Lists; -using TestStack.Dossier.Tests.Builders; -using TestStack.Dossier.Tests.Stubs.Entities; +using TestStack.Dossier.Tests.TestHelpers.Builders; +using TestStack.Dossier.Tests.TestHelpers.Objects.Entities; using Xunit; namespace TestStack.Dossier.Tests @@ -172,5 +172,38 @@ public void WhenBuildingEntitiesImplicitly_ThenTheAnonymousValueFixtureIsSharedA customers[3].CustomerClass.ShouldBe(CustomerClass.Gold); customers[4].CustomerClass.ShouldBe(CustomerClass.Platinum); } + + [Fact] + public void GivenBuilderWithSetCallsInConstructor_WhenBuildingAListOfTheBuilders_ThenDefaultValuesShouldBeRespectedUnlessOverridden() + { + const string overriddenFirstName = "FirstOverride"; + const string overriddenLastName = "LastOverride"; + + var customers = BuilderWithDefaults.CreateListOfSize(3) + .TheFirst(1).With(x => x.Set(y => y.FirstName, overriddenFirstName)) + .TheNext(1).With(x => x.Set(y => y.LastName, overriddenLastName)) + .BuildList(); + + customers[0].FirstName.ShouldBe(overriddenFirstName); + customers[0].LastName.ShouldBe(BuilderWithDefaults.DefaultLastName); + customers[1].FirstName.ShouldBe(BuilderWithDefaults.DefaultFirstName); + customers[1].LastName.ShouldBe(overriddenLastName); + customers[2].FirstName.ShouldBe(BuilderWithDefaults.DefaultFirstName); + customers[2].LastName.ShouldBe(BuilderWithDefaults.DefaultLastName); + } + + [Fact] + public void GivenListOfBuilders_WhenCallingGetBuilders_ThenTheListOfBuildersShouldBeReturned() + { + var list = BasicCustomerBuilder.CreateListOfSize(5); + + var builders = list.GetBuilders(); + + builders.ShouldSatisfyAllConditions( + () => builders.ShouldBeAssignableTo>(), + () => builders.Count().ShouldBe(5), + () => builders.All(b => b != null), + () => builders.ShouldBeUnique()); + } } } diff --git a/TestStack.Dossier.Tests/BuildTests.cs b/TestStack.Dossier.Tests/BuildTests.cs index f6088aa..8067a7a 100644 --- a/TestStack.Dossier.Tests/BuildTests.cs +++ b/TestStack.Dossier.Tests/BuildTests.cs @@ -1,6 +1,7 @@ -using Shouldly; -using TestStack.Dossier.Tests.Builders; -using TestStack.Dossier.Tests.Stubs.Entities; +using System.Collections.Generic; +using Shouldly; +using TestStack.Dossier.Tests.TestHelpers.Builders; +using TestStack.Dossier.Tests.TestHelpers.Objects.Entities; using Xunit; namespace TestStack.Dossier.Tests diff --git a/TestStack.Dossier.Tests/BuilderBuildListTests.cs b/TestStack.Dossier.Tests/BuilderBuildListTests.cs deleted file mode 100644 index 458e112..0000000 --- a/TestStack.Dossier.Tests/BuilderBuildListTests.cs +++ /dev/null @@ -1,171 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Shouldly; -using TestStack.Dossier.DataSources.Generators; -using TestStack.Dossier.Lists; -using TestStack.Dossier.Tests.Builders; -using TestStack.Dossier.Tests.Stubs.ViewModels; -using Xunit; - -namespace TestStack.Dossier.Tests -{ - public class BuilderBuildListTests - { - private DateTime _enrollmentDate = new DateTime(2004, 9, 9); - - [Fact] - public void GivenANormalBuilderInstance_WhenCallingIsListBuilderProxy_ThenReturnFalse() - { - var builder = Builder.CreateNew(); - - builder.IsListBuilderProxy().ShouldBe(false); - } - - [Fact] - public void GivenAListBuilderProxyInstance_WhenCallingIsListBuilderProxy_ThenReturnTrue() - { - var builder = Builder.CreateListOfSize(1).TheFirst(1); - - builder.IsListBuilderProxy().ShouldBe(true); - } - - [Fact] - public void GivenListOfBuilders_WhenCallingBuildListExplicitly_ThenAListOfEntitiesOfTheRightSizeShouldBeReturned() - { - var builders = Builder.CreateListOfSize(5); - - var entities = builders.BuildList(); - - entities.Count.ShouldBe(5); - } - - [Fact] - public void GivenListOfBuilders_WhenCallingBuildListImplicitly_ThenAListOfEntitiesOfTheRightSizeShouldBeReturned() - { - List entities = Builder.CreateListOfSize(5); - - entities.Count.ShouldBe(5); - } - - [Fact] - public void GivenListOfBuilders_WhenCallingBuildListExplicitly_ThenAListOfEntitiesOfTheRightTypeShouldBeReturned() - { - var builders = Builder.CreateListOfSize(5); - - var entities = builders.BuildList(); - - entities.ShouldBeAssignableTo>(); - } - - [Fact] - public void GivenListOfBuilders_WhenCallingBuildListImplicitly_ThenAListOfEntitiesOfTheRightTypeShouldBeReturned() - { - List entities = Builder.CreateListOfSize(5); - - entities.ShouldBeAssignableTo>(); - } - - [Fact] - public void GivenListOfBuilders_WhenCallingBuildListExplicitly_ThenAListOfUniqueEntitiesShouldBeReturned() - { - var builders = Builder.CreateListOfSize(5); - - var entities = builders.BuildList(); - - entities.ShouldBeUnique(); - } - - [Fact] - public void GivenListOfBuilders_WhenCallingBuildListImplicitly_ThenAListOfUniqueEntitiesShouldBeReturned() - { - List entities = Builder.CreateListOfSize(5); - - entities.ShouldBeUnique(); - } - - [Fact] - public void GivenListOfBuildersWithCustomisation_WhenBuildingEntitiesExplicitly_ThenTheCustomisationShouldTakeEffect() - { - var generator = new SequentialGenerator(0, 100); - var list = StudentViewModelBuilder.CreateListOfSize(3) - .All().With(b => b.WithFirstName(generator.Generate().ToString())); - - var data = list.BuildList(); - - data.Select(c => c.FirstName).ToArray() - .ShouldBe(new[] { "0", "1", "2" }); - } - - [Fact] - public void GivenListOfBuildersWithCustomisation_WhenBuildingEntitiesImplicitly_ThenTheCustomisationShouldTakeEffect() - { - var generator = new SequentialGenerator(0, 100); - - List data = StudentViewModelBuilder.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 studentViewModels = StudentViewModelBuilder.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().WhoEntrolledIn(_enrollmentDate) - .BuildList(); - - studentViewModels.ShouldBeAssignableTo>(); - studentViewModels.Count.ShouldBe(5); - studentViewModels[0].FirstName.ShouldBe("First"); - studentViewModels[1].LastName.ShouldBe("Next Last"); - studentViewModels[2].LastName.ShouldBe("last1"); - studentViewModels[3].LastName.ShouldBe("last2"); - studentViewModels[4].LastName.ShouldBe("Last Last"); - studentViewModels.ShouldAllBe(c => c.EnrollmentDate == _enrollmentDate); - } - - [Fact] - public void GivenListOfBuildersWithARangeOfCustomisationMethods_WhenBuildingEntitiesImplicitly_ThenThenTheListIsBuiltAndModifiedCorrectly() - { - var i = 0; - List studentViewModels = StudentViewModelBuilder.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().WhoEntrolledIn(_enrollmentDate); - - studentViewModels.ShouldBeAssignableTo>(); - studentViewModels.Count.ShouldBe(5); - studentViewModels[0].FirstName.ShouldBe("First"); - studentViewModels[1].LastName.ShouldBe("Next Last"); - studentViewModels[2].LastName.ShouldBe("last1"); - studentViewModels[3].LastName.ShouldBe("last2"); - studentViewModels[4].LastName.ShouldBe("Last Last"); - studentViewModels.ShouldAllBe(c => c.EnrollmentDate == _enrollmentDate); - } - - [Fact] - public void WhenBuildingEntitiesExplicitly_ThenTheAnonymousValueFixtureIsSharedAcrossBuilders() - { - var studentViewModels = StudentViewModelBuilder.CreateListOfSize(5).BuildList(); - - studentViewModels.Select(x => x.Grade).ShouldBeUnique(); - } - - [Fact] - public void WhenBuildingEntitiesImplicitly_ThenTheAnonymousValueFixtureIsSharedAcrossBuilders() - { - List studentViewModels = StudentViewModelBuilder.CreateListOfSize(5); - - studentViewModels.Select(x => x.Grade).ShouldBeUnique(); - } - } -} \ No newline at end of file diff --git a/TestStack.Dossier.Tests/BuilderBuildTests.cs b/TestStack.Dossier.Tests/BuilderBuildTests.cs deleted file mode 100644 index 87530a8..0000000 --- a/TestStack.Dossier.Tests/BuilderBuildTests.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using Shouldly; -using TestStack.Dossier.Tests.Builders; -using TestStack.Dossier.Tests.Stubs.Entities; -using TestStack.Dossier.Tests.Stubs.ViewModels; -using Xunit; - -namespace TestStack.Dossier.Tests -{ - public class BuilderBuildTests - { - [Fact] - public void GivenBasicBuilder_WhenCallingBuildExplicitly_ThenReturnAnObject() - { - var builder = Builder.CreateNew(); - - var customer = builder.Build(); - - customer.ShouldBeOfType(); - } - - [Fact] - public void GivenBuilder_WhenCallingSetExplicitly_ShouldOverrideValues() - { - var builder = Builder.CreateNew() - .Set(x => x.FirstName, "Pi") - .Set(x => x.LastName, "Lanningham") - .Set(x => x.YearJoined, 2014); - - var customer = builder.Build(); - - customer.FirstName.ShouldBe("Pi"); - customer.LastName.ShouldBe("Lanningham"); - customer.YearJoined.ShouldBe(2014); - } - - [Fact] - public void GivenBasicBuilder_WhenCallingBuildImplicitly_ThenReturnAnObject() - { - Customer customer = Builder.CreateNew(); - - customer.ShouldBeOfType(); - } - - [Fact] - public void GivenBuilder_WhenCallingSetImplicitly_ShouldOverrideValues() - { - Customer customer = Builder.CreateNew() - .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); - } - - [Fact] - public void GivenBuilder_WhenBuildingObjectWithCtorAndPrivateSetters_ShouldSetPrivateSetters() - { - var id = Guid.NewGuid(); - InstructorViewModel instructor = Builder.CreateNew() - .Set(x => x.FirstName, "Pi") - .Set(x => x.LastName, "Lanningham") - .Set(x => x.Id, id); - - instructor.FirstName.ShouldBe("Pi"); - instructor.LastName.ShouldBe("Lanningham"); - instructor.Id.ShouldBe(id); - } - } -} \ No newline at end of file diff --git a/TestStack.Dossier.Tests/Builder_CreateListTests.cs b/TestStack.Dossier.Tests/Builder_CreateListTests.cs new file mode 100644 index 0000000..dde56aa --- /dev/null +++ b/TestStack.Dossier.Tests/Builder_CreateListTests.cs @@ -0,0 +1,222 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Shouldly; +using TestStack.Dossier.DataSources.Generators; +using TestStack.Dossier.Factories; +using TestStack.Dossier.Lists; +using TestStack.Dossier.Tests.TestHelpers.Objects.Examples; +using TestStack.Dossier.Tests.TestHelpers.Objects.ViewModels; +using Xunit; + +namespace TestStack.Dossier.Tests +{ + // ReSharper disable once InconsistentNaming + public class Builder_CreateListTests + { + private readonly DateTime _enrollmentDate = new DateTime(2004, 9, 9); + + [Fact] + public void GivenANormalBuilderInstance_WhenCallingIsListBuilderProxy_ThenReturnFalse() + { + var builder = Builder.CreateNew(); + + builder.IsListBuilderProxy().ShouldBe(false); + } + + [Fact] + public void GivenAListBuilderProxyInstance_WhenCallingIsListBuilderProxy_ThenReturnTrue() + { + var builder = Builder.CreateListOfSize(1).TheFirst(1); + + builder.IsListBuilderProxy().ShouldBe(true); + } + + [Fact] + public void GivenListOfBuilders_WhenCallingBuildListExplicitly_ThenAListOfObjectsOfTheRightSizeShouldBeReturned() + { + var builders = Builder.CreateListOfSize(5); + + var objects = builders.BuildList(); + + objects.Count.ShouldBe(5); + } + + [Fact] + public void GivenListOfBuilders_WhenCallingBuildListImplicitly_ThenAListOfObjectsOfTheRightSizeShouldBeReturned() + { + List objects = Builder.CreateListOfSize(5); + + objects.Count.ShouldBe(5); + } + + [Fact] + public void GivenListOfBuilders_WhenCallingBuildListExplicitly_ThenAListOfObjectsOfTheRightTypeShouldBeReturned() + { + var builders = Builder.CreateListOfSize(5); + + var objects = builders.BuildList(); + + objects.ShouldBeAssignableTo>(); + } + + [Fact] + public void GivenListOfBuilders_WhenCallingBuildListImplicitly_ThenAListOfObjectsOfTheRightTypeShouldBeReturned() + { + List objects = Builder.CreateListOfSize(5); + + objects.ShouldBeAssignableTo>(); + } + + [Fact] + public void GivenListOfBuilders_WhenCallingBuildListExplicitly_ThenAListOfUniqueObjectsShouldBeReturned() + { + var builders = Builder.CreateListOfSize(5); + + var objects = builders.BuildList(); + + objects.ShouldBeUnique(); + } + + [Fact] + public void GivenListOfBuilders_WhenCallingBuildListImplicitly_ThenAListOfUniqueObjectsShouldBeReturned() + { + List objects = Builder.CreateListOfSize(5); + + objects.ShouldBeUnique(); + } + + [Fact] + public void GivenListOfBuildersWithCustomisation_WhenBuildingObjectsExplicitly_ThenTheCustomisationShouldTakeEffect() + { + var generator = new SequentialGenerator(0, 100); + var list = Builder.CreateListOfSize(3) + .All().With(b => b.Set(x => x.FirstName, generator.Generate().ToString())); + + var data = list.BuildList(); + + data.Select(c => c.FirstName).ToArray() + .ShouldBe(new[] { "0", "1", "2" }); + } + + [Fact] + public void GivenListOfBuildersWithCustomisation_WhenBuildingObjectsImplicitly_ThenTheCustomisationShouldTakeEffect() + { + var generator = new SequentialGenerator(0, 100); + + List data = Builder.CreateListOfSize(3) + .All().With(b => b.Set(x => x.FirstName, generator.Generate().ToString())); + + data.Select(c => c.FirstName).ToArray() + .ShouldBe(new[] { "0", "1", "2" }); + } + + [Fact] + public void GivenListOfBuildersWithComplexCustomisations_WhenBuildingObjectsExplicitly_ThenThenTheListIsBuiltAndModifiedCorrectly() + { + var i = 0; + var studentViewModels = Builder.CreateListOfSize(5) + .TheFirst(1).Set(x => x.FirstName, "First") + .TheNext(1).Set(x => x.LastName, "Next Last") + .TheLast(1).Set(x => x.LastName, "Last Last") + .ThePrevious(2).With(b => b.Set(x => x.LastName, "last" + (++i).ToString())) + .All().Set(x => x.EnrollmentDate, _enrollmentDate) + .BuildList(); + + studentViewModels.ShouldBeAssignableTo>(); + studentViewModels.Count.ShouldBe(5); + studentViewModels[0].FirstName.ShouldBe("First"); + studentViewModels[1].LastName.ShouldBe("Next Last"); + studentViewModels[2].LastName.ShouldBe("last1"); + studentViewModels[3].LastName.ShouldBe("last2"); + studentViewModels[4].LastName.ShouldBe("Last Last"); + studentViewModels.ShouldAllBe(c => c.EnrollmentDate == _enrollmentDate); + } + + [Fact] + public void GivenListOfBuildersWithComplexCustomisations_WhenBuildingObjectsImplicitly_ThenThenTheListIsBuiltAndModifiedCorrectly() + { + var i = 0; + List studentViewModels = Builder.CreateListOfSize(5) + .TheFirst(1).Set(x => x.FirstName, "First") + .TheNext(1).Set(x => x.LastName, "Next Last") + .TheLast(1).Set(x => x.LastName, "Last Last") + .ThePrevious(2).With(b => b.Set(x => x.LastName, "last" + (++i).ToString())) + .All().Set(x => x.EnrollmentDate, _enrollmentDate); + + studentViewModels.ShouldBeAssignableTo>(); + studentViewModels.Count.ShouldBe(5); + studentViewModels[0].FirstName.ShouldBe("First"); + studentViewModels[1].LastName.ShouldBe("Next Last"); + studentViewModels[2].LastName.ShouldBe("last1"); + studentViewModels[3].LastName.ShouldBe("last2"); + studentViewModels[4].LastName.ShouldBe("Last Last"); + studentViewModels.ShouldAllBe(c => c.EnrollmentDate == _enrollmentDate); + } + + [Fact] + public void WhenBuildingObjectsExplicitly_ThenTheAnonymousValueFixtureIsSharedAcrossBuilders() + { + var studentViewModels = Builder.CreateListOfSize(5).BuildList(); + + studentViewModels.Select(x => x.Grade).ShouldBeUnique(); + } + + [Fact] + public void WhenBuildingObjectsImplicitly_ThenTheAnonymousValueFixtureIsSharedAcrossBuilders() + { + List studentViewModels = Builder.CreateListOfSize(5); + + studentViewModels.Select(x => x.Grade).ShouldBeUnique(); + } + + [Fact] + public void WhenBuildingObjectsWithCtorAndPrivateSetters_ThenSetPrivateSettersByDefault() + { + var dto = Builder.CreateListOfSize(1) + .TheFirst(1) + .Set(x => x.SetByCtorWithPublicSetter, "1") + .Set(x => x.SetByCtorWithPrivateSetter, "2") + .Set(x => x.NotSetByCtorWithPrivateSetter, "3") + .Set(x => x.NotSetByCtorWithPublicSetter, "4") + .BuildList() + [0]; + + dto.SetByCtorWithPublicSetter.ShouldBe("1"); + dto.SetByCtorWithPrivateSetter.ShouldBe("2"); + dto.NotSetByCtorWithPrivateSetter.ShouldBe("3"); + dto.NotSetByCtorWithPublicSetter.ShouldBe("4"); + } + + [Fact] + public void GivenBuilderListWithFactoryOverride_WhenBuildingObjects_ThenRespectOverriddenFactory() + { + var dto = Builder.CreateListOfSize(1, new CallConstructorFactory()) + .TheFirst(1) + .Set(x => x.SetByCtorWithPublicSetter, "1") + .Set(x => x.SetByCtorWithPrivateSetter, "2") + .Set(x => x.NotSetByCtorWithPrivateSetter, "3") + .Set(x => x.NotSetByCtorWithPublicSetter, "4") + .BuildList() + [0]; + + dto.SetByCtorWithPublicSetter.ShouldBe("1"); + dto.SetByCtorWithPrivateSetter.ShouldBe("2"); + dto.NotSetByCtorWithPrivateSetter.ShouldNotBe("3"); + dto.NotSetByCtorWithPublicSetter.ShouldNotBe("4"); + } + + [Fact] + public void GivenBuilder_WhenCallingSetWithLambda_ThenInvokeEachTime() + { + var grade = Grade.A; + var customers = Builder.CreateListOfSize(10) + .All().Set(x => x.Grade, () => grade++) + .BuildList(); + + var gradeAssertion = Grade.A; + foreach (var c in customers) + c.Grade.ShouldBe(gradeAssertion++); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier.Tests/Builder_CreateNewTests.cs b/TestStack.Dossier.Tests/Builder_CreateNewTests.cs new file mode 100644 index 0000000..de36834 --- /dev/null +++ b/TestStack.Dossier.Tests/Builder_CreateNewTests.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using Shouldly; +using TestStack.Dossier.Factories; +using TestStack.Dossier.Tests.TestHelpers.Objects.Examples; +using TestStack.Dossier.Tests.TestHelpers.Objects.ViewModels; +using Xunit; + +namespace TestStack.Dossier.Tests +{ + // ReSharper disable once InconsistentNaming + public class Builder_CreateNewTests + { + [Fact] + public void GivenBuilder_WhenCallingBuildExplicitly_ThenReturnAnObject() + { + var builder = Builder.CreateNew(); + + var viewModel = builder.Build(); + + viewModel.ShouldBeOfType(); + } + + [Fact] + public void GivenBuilder_WhenCallingBuildImplicitly_ThenReturnAnObject() + { + StudentViewModel viewModel = Builder.CreateNew(); + + viewModel.ShouldBeOfType(); + } + + [Fact] + public void GivenBuilderWithModifications_WhenCallingBuildExplicitly_ThenOverrideValues() + { + var builder = Builder.CreateNew() + .Set(x => x.FirstName, "Pi") + .Set(x => x.LastName, "Lanningham") + .Set(x => x.EnrollmentDate, new DateTime(2000, 1, 1)); + + var vm = builder.Build(); + + vm.FirstName.ShouldBe("Pi"); + vm.LastName.ShouldBe("Lanningham"); + vm.EnrollmentDate.ShouldBe(new DateTime(2000, 1, 1)); + } + + [Fact] + public void GivenBuilderWithModifications_WhenCallingBuildImplicitly_ThenOverrideValues() + { + StudentViewModel vm = Builder.CreateNew() + .Set(x => x.FirstName, "Pi") + .Set(x => x.LastName, "Lanningham") + .Set(x => x.EnrollmentDate, new DateTime(2000, 1, 1)); + + vm.FirstName.ShouldBe("Pi"); + vm.LastName.ShouldBe("Lanningham"); + vm.EnrollmentDate.ShouldBe(new DateTime(2000, 1, 1)); + } + + [Fact] + public void GivenBuilder_WhenBuildingObjectWithCtorAndPrivateSetters_ThenSetPrivateSettersByDefault() + { + MixedAccessibilityDto dto = Builder.CreateNew() + .Set(x => x.SetByCtorWithPublicSetter, "1") + .Set(x => x.SetByCtorWithPrivateSetter, "2") + .Set(x => x.NotSetByCtorWithPrivateSetter, "3") + .Set(x => x.NotSetByCtorWithPublicSetter, "4"); + + dto.SetByCtorWithPublicSetter.ShouldBe("1"); + dto.SetByCtorWithPrivateSetter.ShouldBe("2"); + dto.NotSetByCtorWithPrivateSetter.ShouldBe("3"); + dto.NotSetByCtorWithPublicSetter.ShouldBe("4"); + } + + [Fact] + public void GivenBuilderWithFactoryOverride_WhenBuildingObject_ThenRespectOverriddenFactory() + { + MixedAccessibilityDto dto = Builder.CreateNew(new CallConstructorFactory()) + .Set(x => x.SetByCtorWithPublicSetter, "1") + .Set(x => x.SetByCtorWithPrivateSetter, "2") + .Set(x => x.NotSetByCtorWithPrivateSetter, "3") + .Set(x => x.NotSetByCtorWithPublicSetter, "4"); + + dto.SetByCtorWithPublicSetter.ShouldBe("1"); + dto.SetByCtorWithPrivateSetter.ShouldBe("2"); + dto.NotSetByCtorWithPrivateSetter.ShouldNotBe("3"); + dto.NotSetByCtorWithPublicSetter.ShouldNotBe("4"); + } + + [Fact] + public void GivenBuilder_WhenCallingSetWithLambda_ThenInvokeEachTime() + { + var grade = Grade.A; + var builder = Builder.CreateNew() + .Set(x => x.FirstName, "Pi") + .Set(x => x.LastName, "Lanningham") + .Set(x => x.Grade, () => grade++); + + var customerA = builder.Build(); + var customerB = builder.Build(); + + customerA.Grade.ShouldBe(Grade.A); + customerB.Grade.ShouldBe(Grade.B); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier.Tests/Builder_SetUsingBuilderTests.cs b/TestStack.Dossier.Tests/Builder_SetUsingBuilderTests.cs new file mode 100644 index 0000000..ff548b7 --- /dev/null +++ b/TestStack.Dossier.Tests/Builder_SetUsingBuilderTests.cs @@ -0,0 +1,116 @@ +using Shouldly; +using TestStack.Dossier.Lists; +using TestStack.Dossier.Tests.TestHelpers.Builders; +using TestStack.Dossier.Tests.TestHelpers.Objects.ViewModels; +using Xunit; + +namespace TestStack.Dossier.Tests +{ + // ReSharper disable once InconsistentNaming + public class Builder_SetUsingBuilderTests + { + [Fact] + public void GivenBuilderWithObjectPropertyNotSet_WhenBuildingTheObject_ThenThePropertyWillBeNull() + { + var vm = Builder.CreateNew().Build(); + + vm.Address.ShouldBe(null); + } + + [Fact] + public void GivenBuilderWithObjectPropertyNotSet_WhenBuildingAListOfObjects_ThenThePropertyWillBeNull() + { + var vm = Builder.CreateListOfSize(1).BuildList()[0]; + + vm.Address.ShouldBe(null); + } + + [Fact] + public void GivenBuilderWithObjectPropertySetViaBuilder_WhenBuildingTheObject_ThenThePropertyWillBeSet() + { + var vm = Builder.CreateNew() + .SetUsingBuilder(x => x.Address) + .Build(); + + vm.Address.ShouldNotBe(null); + } + + [Fact] + public void GivenBuilderWithObjectPropertySetViaBuilder_WhenBuildingAListOfObjects_ThenThePropertyWillBeSet() + { + var vm = Builder.CreateListOfSize(1) + .TheFirst(1) + .SetUsingBuilder(x => x.Address) + .BuildList()[0]; + + vm.Address.ShouldNotBe(null); + } + + [Fact] + public void GivenBuilderWithObjectPropertySetViaBuilderAndCustomisation_WhenBuildingTheObject_ThenThePropertyWillBeSetIncludingTheCustomisation() + { + var vm = Builder.CreateNew() + .SetUsingBuilder(x => x.Address, b => b.Set(x => x.Street, "A street")) + .Build(); + + vm.Address.ShouldNotBe(null); + vm.Address.Street.ShouldBe("A street"); + } + + [Fact] + public void GivenBuilderWithObjectPropertySetViaBuilderAndCustomisation_WhenBuildingAListOfObjects_ThenThePropertyWillBeSetIncludingTheCustomisation() + { + var vm = Builder.CreateListOfSize(1) + .All() + .SetUsingBuilder(x => x.Address, b => b.Set(x => x.Street, "A street")) + .BuildList()[0]; + + vm.Address.ShouldNotBe(null); + vm.Address.Street.ShouldBe("A street"); + } + + [Fact] + public void GivenBuilderWithObjectPropertySetViaCustomBuilder_WhenBuildingTheObject_ThenThePropertyWillBeSet() + { + var vm = Builder.CreateNew() + .SetUsingBuilder(x => x.Address) + .Build(); + + vm.Address.ShouldNotBe(null); + } + + [Fact] + public void GivenBuilderWithObjectPropertySetViaCustomBuilder_WhenBuildingAListOfObjects_ThenThePropertyWillBeSet() + { + var vm = Builder.CreateListOfSize(1) + .All() + .SetUsingBuilder(x => x.Address) + .BuildList()[0]; + + vm.Address.ShouldNotBe(null); + } + + [Fact] + public void GivenBuilderWithObjectPropertySetViaCustomBuilderAndCustomisation_WhenBuildingTheObject_ThenThePropertyWillBeSetIncludingTheCustomisation() + { + var vm = Builder.CreateNew() + .SetUsingBuilder(x => x.Address, b => b.WithStreet("A street")) + .Build(); + + vm.Address.ShouldNotBe(null); + vm.Address.Street.ShouldBe("A street"); + } + + [Fact] + public void GivenBuilderWithObjectPropertySetViaCustomBuilderAndCustomisation_WhenBuildingAListOfObjects_ThenThePropertyWillBeSetIncludingTheCustomisation() + { + var vm = Builder.CreateListOfSize(1) + .All() + .SetUsingBuilder(x => x.Address, b => b.WithStreet("A street")) + .BuildList()[0]; + + vm.Address.ShouldNotBe(null); + vm.Address.Street.ShouldBe("A street"); + } + } +} diff --git a/TestStack.Dossier.Tests/Builders/BasicCustomerBuilder.cs b/TestStack.Dossier.Tests/Builders/BasicCustomerBuilder.cs deleted file mode 100644 index dc6462f..0000000 --- a/TestStack.Dossier.Tests/Builders/BasicCustomerBuilder.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Linq.Expressions; -using TestStack.Dossier.Tests.Stubs.Entities; - -namespace TestStack.Dossier.Tests.Builders -{ - public class BasicCustomerBuilder : TestDataBuilder - { - protected override Customer BuildObject() - { - return new Customer("customer1", "First Name", "Last Name", 2013, CustomerClass.Normal); - } - - public new BasicCustomerBuilder Set(Expression> property, TValue value) - { - return base.Set(property, value); - } - } -} diff --git a/TestStack.Dossier.Tests/Builders/StudentViewModelBuilder.cs b/TestStack.Dossier.Tests/Builders/StudentViewModelBuilder.cs deleted file mode 100644 index d57a028..0000000 --- a/TestStack.Dossier.Tests/Builders/StudentViewModelBuilder.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using TestStack.Dossier.Factories; -using TestStack.Dossier.Tests.Stubs.ViewModels; - -namespace TestStack.Dossier.Tests.Builders -{ - public class StudentViewModelBuilder : TestDataBuilder - { - public virtual StudentViewModelBuilder WithFirstName(string firstName) - { - return Set(x => x.FirstName, firstName); - } - - public virtual StudentViewModelBuilder WithLastName(string lastName) - { - return Set(x => x.LastName, lastName); - } - - public virtual StudentViewModelBuilder WhoEntrolledIn(DateTime enrollmentDate) - { - return Set(x => x.EnrollmentDate, enrollmentDate); - } - - protected override StudentViewModel BuildObject() - { - return BuildUsing(); - } - } -} diff --git a/TestStack.Dossier.Tests/ChildBuilderTests.cs b/TestStack.Dossier.Tests/ChildBuilderTests.cs index 3c447bd..7891162 100644 --- a/TestStack.Dossier.Tests/ChildBuilderTests.cs +++ b/TestStack.Dossier.Tests/ChildBuilderTests.cs @@ -68,12 +68,12 @@ public class ParentBuilder : TestDataBuilder { public ParentBuilder() { - Set(x => x.Child, new ChildBuilder().Build()); + Set(x => x.Child, new ChildBuilder()); } public ParentBuilder WithChildBuilder(Func modifier = null) { - return Set(x => x.Child, GetChildBuilder(modifier).Build()); + return Set(x => x.Child, GetChildBuilder(modifier)); } protected override ParentObject BuildObject() diff --git a/TestStack.Dossier.Tests/DataSources/DataSourceConventionTests.cs b/TestStack.Dossier.Tests/DataSources/DataSourceConventionTests.cs index a5c3167..8087e27 100644 --- a/TestStack.Dossier.Tests/DataSources/DataSourceConventionTests.cs +++ b/TestStack.Dossier.Tests/DataSources/DataSourceConventionTests.cs @@ -2,17 +2,15 @@ using System.Linq; using Shouldly; using TestStack.Dossier.DataSources; -using TestStack.Dossier.DataSources.Geography; -using TestStack.Dossier.DataSources.Person; +using TestStack.Dossier.DataSources.Dictionaries; using Xunit; -using Xunit.Extensions; namespace TestStack.Dossier.Tests.DataSources { public class DataSourceConventionTests { [Theory] - [PropertyData("TestCases")] + [MemberData(nameof(TestCases))] public void DataSourceConventions(DataSource sut, int expectedCount) { var collection = sut.Data.ToList(); @@ -25,21 +23,21 @@ public static IEnumerable TestCases { get { - yield return new object[] { new GeoContinentSource(), 7 }; - yield return new object[] { new GeoCountrySource(), 249 }; - yield return new object[] { new GeoCountryCodeSource(), 64 }; - yield return new object[] { new GeoLatitudeSource(), 1000 }; - yield return new object[] { new GeoLongitudeSource(), 1000 }; + yield return new object[] { new Words(FromDictionary.GeoContinent), 7 }; + yield return new object[] { new Words(FromDictionary.GeoCountry), 249 }; + yield return new object[] { new Words(FromDictionary.GeoCountryCode), 64 }; + yield return new object[] { new Words(FromDictionary.GeoLatitude), 1000 }; + yield return new object[] { new Words(FromDictionary.GeoLongitude), 1000 }; - yield return new object[] { new PersonEmailAddressSource(), 1000 }; - yield return new object[] { new PersonLanguageSource(), 97 }; - yield return new object[] { new PersonNameFirstFemaleSource(), 100 }; - yield return new object[] { new PersonNameFirstSource(), 479 }; - yield return new object[] { new PersonNameFullSource(), 1000 }; - yield return new object[] { new PersonNameLastSource(), 747 }; - yield return new object[] { new PersonNameFirstMaleSource(), 100 }; - yield return new object[] { new PersonNameSuffixSource(), 5 }; - yield return new object[] { new PersonNameTitleSource(), 9 }; + yield return new object[] { new Words(FromDictionary.PersonEmailAddress), 1000 }; + yield return new object[] { new Words(FromDictionary.PersonLanguage), 97 }; + yield return new object[] { new Words(FromDictionary.PersonNameFirstFemale), 100 }; + yield return new object[] { new Words(FromDictionary.PersonNameFirst), 479 }; + yield return new object[] { new Words(FromDictionary.PersonNameFull), 1000 }; + yield return new object[] { new Words(FromDictionary.PersonNameLast), 747 }; + yield return new object[] { new Words(FromDictionary.PersonNameFirstMale), 100 }; + yield return new object[] { new Words(FromDictionary.PersonNameSuffix), 5 }; + yield return new object[] { new Words(FromDictionary.PersonNameTitle), 9 }; } } } diff --git a/TestStack.Dossier.Tests/DataSources/Dictionaries/CacheTests.cs b/TestStack.Dossier.Tests/DataSources/Dictionaries/CacheTests.cs deleted file mode 100644 index 45d34ec..0000000 --- a/TestStack.Dossier.Tests/DataSources/Dictionaries/CacheTests.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Collections.Generic; -using Shouldly; -using TestStack.Dossier.DataSources.Dictionaries; -using Xunit; - -namespace TestStack.Dossier.Tests.DataSources.Dictionaries -{ - public class CacheTests : IDisposable - { - public CacheTests() - { - Cache.Clear(); - } - - [Fact] - public void WhenRequestingAnItemNotInTheCache_ThenReturnsNull() - { - Cache.Get("SomethingThatDoesNotExist").ShouldBe(null); - } - - [Fact] - public void WhenAddingAnItemToTheCache_ThenTheItemIsPersistedInTheCache() - { - var collection = new List{"item1", "item2"}; - Cache.Set("myCollection", collection); - Cache.Get("myCollection").ShouldBeSameAs(collection); - } - - [Fact] - public void WhenAddingAnItemToTheCacheWithTheSameKeyAsAnExistingItem_ThenTheOriginalItemIsReplacedWithTheNewItem() - { - var collection = new List { "item1", "item2" }; - var collection2 = new List { "item3" }; - Cache.Set("myCollection", collection); - - Cache.Set("myCollection", collection2); - - Cache.Get("myCollection").ShouldBeSameAs(collection2); - } - - [Fact] - public void WhenCheckingCacheContainesAnItemThatIsInCache_ThenShouldReturnTrue() - { - var collection = new List {"item1", "item2"}; - Cache.Set("myCollection", collection); - Cache.Contains("myCollection").ShouldBe(true); - } - - [Fact] - public void WhenCheckingCacheContainesAnItemThatIsNotInCache_ThenShouldReturnFalse() - { - Cache.Contains("SomethingThatDoesNotExist").ShouldBe(false); - } - - - public void Dispose() - { - Cache.Clear(); - } - } -} diff --git a/TestStack.Dossier.Tests/DataSources/Dictionaries/FileDictionaryRepositoryIntegrationTests.cs b/TestStack.Dossier.Tests/DataSources/Dictionaries/CachedFileDictionaryRepositoryIntegrationTests.cs similarity index 94% rename from TestStack.Dossier.Tests/DataSources/Dictionaries/FileDictionaryRepositoryIntegrationTests.cs rename to TestStack.Dossier.Tests/DataSources/Dictionaries/CachedFileDictionaryRepositoryIntegrationTests.cs index 50171e7..1665ced 100644 --- a/TestStack.Dossier.Tests/DataSources/Dictionaries/FileDictionaryRepositoryIntegrationTests.cs +++ b/TestStack.Dossier.Tests/DataSources/Dictionaries/CachedFileDictionaryRepositoryIntegrationTests.cs @@ -5,7 +5,7 @@ namespace TestStack.Dossier.Tests.DataSources.Dictionaries { - public class FileDictionaryRepositoryIntegrationTests + public class CachedFileDictionaryRepositoryIntegrationTests { [Fact] public void GivenAnExternalFileDictionaryExists_WhenRetrievingWords_ThenExternalDictionaryIsUsed() diff --git a/TestStack.Dossier.Tests/DataSources/Dictionaries/Resources/FileDataConventions.cs b/TestStack.Dossier.Tests/DataSources/Dictionaries/Resources/FileDataConventions.cs index afd5b62..4cfd92c 100644 --- a/TestStack.Dossier.Tests/DataSources/Dictionaries/Resources/FileDataConventions.cs +++ b/TestStack.Dossier.Tests/DataSources/Dictionaries/Resources/FileDataConventions.cs @@ -13,7 +13,7 @@ public class FileDataConventions [Fact] public void ApplyConventions() { - var assembly = typeof(IAnonymousValueSupplier).Assembly; + var assembly = typeof(IAnonymousValueSupplier).GetTypeInfo().Assembly; var resources = assembly .GetManifestResourceNames() .Where(x => x.EndsWith(".txt")) @@ -27,7 +27,7 @@ public void ApplyConventions() } } - public void Should_not_contain_duplicates(List collection, string fileName) + private void Should_not_contain_duplicates(List collection, string fileName) { var duplicates = collection .GroupBy(x => x) @@ -43,7 +43,7 @@ public void Should_not_contain_duplicates(List collection, string fileNa } } - public void Should_not_contain_null_or_empty_values(List collection, string fileName) + private void Should_not_contain_null_or_empty_values(List collection, string fileName) { var blanks = collection.Where(string.IsNullOrEmpty).ToList(); if (blanks.Any()) diff --git a/TestStack.Dossier.Tests/DataSources/Dictionaries/WordsCacheTests.cs b/TestStack.Dossier.Tests/DataSources/Dictionaries/WordsCacheTests.cs new file mode 100644 index 0000000..f0ca164 --- /dev/null +++ b/TestStack.Dossier.Tests/DataSources/Dictionaries/WordsCacheTests.cs @@ -0,0 +1,45 @@ +using System; +using System.IO; +using Shouldly; +using TestStack.Dossier.DataSources.Dictionaries; +using Xunit; + +namespace TestStack.Dossier.Tests.DataSources.Dictionaries +{ + public class WordsCacheTests : IDisposable + { + private const string DictionaryThatDoesNotExist = "DictionaryThatDoesNotExist"; + + public WordsCacheTests() + { + WordsCache.Clear(); + } + + [Fact] + public void WhenRequestingAnItemInTheCache_ThenReturnsSameItem() + { + var words1 = WordsCache.Get(FromDictionary.InternetUrl); + var words2 = WordsCache.Get(FromDictionary.InternetUrl); + words1.ShouldBeSameAs(words2); + } + + [Fact] + public void WhenRequestingAnItemNotInTheCache_ThenReturnsWordsSourceForItemDictionary() + { + var words = WordsCache.Get(DictionaryThatDoesNotExist); + words.DictionaryName.ShouldBe(DictionaryThatDoesNotExist); + } + + [Fact] + public void WhenUsingCachedWordsForNonExistentDictionary_ThenWordsSourceThrowsFileNotFoundException() + { + var words = WordsCache.Get(DictionaryThatDoesNotExist); + Should.Throw(() => words.Next()); + } + + public void Dispose() + { + WordsCache.Clear(); + } + } +} diff --git a/TestStack.Dossier.Tests/DataSources/Dictionaries/FileDictionarySourceTests.cs b/TestStack.Dossier.Tests/DataSources/Dictionaries/WordsTests.cs similarity index 79% rename from TestStack.Dossier.Tests/DataSources/Dictionaries/FileDictionarySourceTests.cs rename to TestStack.Dossier.Tests/DataSources/Dictionaries/WordsTests.cs index 0394497..1053125 100644 --- a/TestStack.Dossier.Tests/DataSources/Dictionaries/FileDictionarySourceTests.cs +++ b/TestStack.Dossier.Tests/DataSources/Dictionaries/WordsTests.cs @@ -5,7 +5,7 @@ namespace TestStack.Dossier.Tests.DataSources.Dictionaries { - public class FileDictionarySourceTests + public class WordsTests { [Fact] public void WhenInitializingList_ThenPassClassNameToRepositoryAsDictionaryName() @@ -19,9 +19,9 @@ public void WhenInitializingList_ThenPassClassNameToRepositoryAsDictionaryName() } } - public class DummySource : FileDictionarySource + public class DummySource : Words { internal DummySource(IDictionaryRepository repository) - : base(Substitute.For(), repository) { } + : base(Substitute.For(), repository, "Dummy") { } } } diff --git a/TestStack.Dossier.Tests/DataSources/Generators/RandomGeneratorTests.cs b/TestStack.Dossier.Tests/DataSources/Generators/RandomGeneratorTests.cs index 3670841..9c94484 100644 --- a/TestStack.Dossier.Tests/DataSources/Generators/RandomGeneratorTests.cs +++ b/TestStack.Dossier.Tests/DataSources/Generators/RandomGeneratorTests.cs @@ -3,7 +3,6 @@ using Shouldly; using TestStack.Dossier.DataSources.Generators; using Xunit; -using Xunit.Extensions; namespace TestStack.Dossier.Tests.DataSources.Generators { diff --git a/TestStack.Dossier.Tests/DataSources/Generators/SequentiaGeneratorTests.cs b/TestStack.Dossier.Tests/DataSources/Generators/SequentiaGeneratorTests.cs index a3f22ae..113cbb9 100644 --- a/TestStack.Dossier.Tests/DataSources/Generators/SequentiaGeneratorTests.cs +++ b/TestStack.Dossier.Tests/DataSources/Generators/SequentiaGeneratorTests.cs @@ -2,7 +2,6 @@ using Shouldly; using TestStack.Dossier.DataSources.Generators; using Xunit; -using Xunit.Extensions; namespace TestStack.Dossier.Tests.DataSources.Generators { diff --git a/TestStack.Dossier.Tests/DataSources/Picking/PickingTests.cs b/TestStack.Dossier.Tests/DataSources/Picking/PickingTests.cs new file mode 100644 index 0000000..566161c --- /dev/null +++ b/TestStack.Dossier.Tests/DataSources/Picking/PickingTests.cs @@ -0,0 +1,48 @@ +using System.Linq; +using Shouldly; +using TestStack.Dossier.DataSources.Picking; +using TestStack.Dossier.Lists; +using TestStack.Dossier.Tests.TestHelpers.Objects.Entities; +using Xunit; + +namespace TestStack.Dossier.Tests.DataSources.Picking +{ + public class PickingTests + { + [Fact] + public void RandomItemFrom_should_add_items_from_list_randomly() + { + var addresses = Builder
.CreateListOfSize(15).BuildList(); + var customers = Builder + .CreateListOfSize(15) + .All() + .Set(x => x.PostalAddress, Pick.RandomItemFrom(addresses).Next) + .BuildList(); + + var uniqueAddresses = customers.Select(x => x.PostalAddress).Distinct().Count(); + uniqueAddresses.ShouldBeGreaterThan(3); + uniqueAddresses.ShouldBeLessThan(15); + } + + [Fact] + public void RepeatingSequenceFrom_should_add_items_from_list_sequentially_and_repeat_when_list_completes() + { + var addresses = Builder
.CreateListOfSize(3).BuildList(); + var customers = Builder + .CreateListOfSize(9) + .All() + .Set(x => x.PostalAddress, Pick.RepeatingSequenceFrom(addresses).Next) + .BuildList(); + + for (int i = 0; i < 2; i++) + { + var address = customers[i].PostalAddress; + address.ShouldBeSameAs(customers[i + 3].PostalAddress); + address.ShouldBeSameAs(customers[i + 6].PostalAddress); + + address.ShouldNotBeSameAs(customers[i + 1].PostalAddress); + address.ShouldNotBeSameAs(customers[i + 2].PostalAddress); + } + } + } +} diff --git a/TestStack.Dossier.Tests/EquivalenceClasses/AddressAusEquivalenceTests.cs b/TestStack.Dossier.Tests/EquivalenceClasses/AddressAusEquivalenceTests.cs new file mode 100644 index 0000000..03efd7d --- /dev/null +++ b/TestStack.Dossier.Tests/EquivalenceClasses/AddressAusEquivalenceTests.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using TestStack.Dossier.DataSources; +using TestStack.Dossier.DataSources.Dictionaries; +using Xunit; + +namespace TestStack.Dossier.Tests.EquivalenceClasses +{ + public class AddressAusEquivalenceTests : FileDictionaryEquivalenceTests + { + [Theory] + [ClassData(typeof(AddressAusTestCases))] + public override void WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(DataSource source, List testCases) + { + base.WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(source, testCases); + } + } + + public class AddressAusTestCases : FileDictionaryEquivalenceTestCases + { + protected override List GetData() + { + return new List + { + new object[] + {new Words(FromDictionary.AddressAusCity), GenerateTestCasesForSut(Any.AddressAus.City)}, + new object[] + {new Words(FromDictionary.AddressAusCompany), GenerateTestCasesForSut(Any.AddressAus.Company)}, + new object[] + {new Words(FromDictionary.AddressAusPhone), GenerateTestCasesForSut(Any.AddressAus.Phone)}, + new object[] + {new Words(FromDictionary.AddressAusPostCode), GenerateTestCasesForSut(Any.AddressAus.PostCode)}, + new object[] + {new Words(FromDictionary.AddressAusState), GenerateTestCasesForSut(Any.AddressAus.State)}, + new object[] + { + new Words(FromDictionary.AddressAusStateAbbreviation), + GenerateTestCasesForSut(Any.AddressAus.StateAbbreviation) + }, + new object[] + {new Words(FromDictionary.AddressAusStreet), GenerateTestCasesForSut(Any.AddressAus.Street)}, + new object[] + {new Words(FromDictionary.AddressAusWebsite), GenerateTestCasesForSut(Any.AddressAus.Website)}, + }; + } + } +} diff --git a/TestStack.Dossier.Tests/EquivalenceClasses/AddressUkEquivalenceTests.cs b/TestStack.Dossier.Tests/EquivalenceClasses/AddressUkEquivalenceTests.cs new file mode 100644 index 0000000..578daea --- /dev/null +++ b/TestStack.Dossier.Tests/EquivalenceClasses/AddressUkEquivalenceTests.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using TestStack.Dossier.DataSources; +using TestStack.Dossier.DataSources.Dictionaries; +using Xunit; + +namespace TestStack.Dossier.Tests.EquivalenceClasses +{ + public class AddressUkEquivalenceClasses : FileDictionaryEquivalenceTests + { + [Theory] + [ClassData(typeof(AddressUkTestCases))] + public override void WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(DataSource source, List testCases) + { + base.WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(source, testCases); + } + } + + public class AddressUkTestCases : FileDictionaryEquivalenceTestCases + { + protected override List GetData() + { + return new List + { + new object[] + {new Words(FromDictionary.AddressUkCounty), GenerateTestCasesForSut(Any.AddressUk.County)}, + new object[] + {new Words(FromDictionary.AddressUkCity), GenerateTestCasesForSut(Any.AddressUk.City)}, + new object[] + {new Words(FromDictionary.AddressUkCompany), GenerateTestCasesForSut(Any.AddressUk.Company)}, + new object[] + {new Words(FromDictionary.AddressUkPhone), GenerateTestCasesForSut(Any.AddressUk.Phone)}, + new object[] + {new Words(FromDictionary.AddressUkPostCode), GenerateTestCasesForSut(Any.AddressUk.PostCode)}, + new object[] + {new Words(FromDictionary.AddressUkStreet), GenerateTestCasesForSut(Any.AddressUk.Street)}, + new object[] + {new Words(FromDictionary.AddressUkWebsite), GenerateTestCasesForSut(Any.AddressUk.Website)}, + }; + } + } +} diff --git a/TestStack.Dossier.Tests/EquivalenceClasses/AddressUsEquivalenceTests.cs b/TestStack.Dossier.Tests/EquivalenceClasses/AddressUsEquivalenceTests.cs new file mode 100644 index 0000000..2f13ccd --- /dev/null +++ b/TestStack.Dossier.Tests/EquivalenceClasses/AddressUsEquivalenceTests.cs @@ -0,0 +1,48 @@ +using System.Collections.Generic; +using TestStack.Dossier.DataSources; +using TestStack.Dossier.DataSources.Dictionaries; +using Xunit; + +namespace TestStack.Dossier.Tests.EquivalenceClasses +{ + public class AddressUsEquivalenceTests : FileDictionaryEquivalenceTests + { + [Theory] + [ClassData(typeof(AddressUsTestCases))] + public override void WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(DataSource source, List testCases) + { + base.WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(source, testCases); + } + } + + public class AddressUsTestCases : FileDictionaryEquivalenceTestCases + { + protected override List GetData() + { + return new List + { + new object[] + {new Words(FromDictionary.AddressUsCity), GenerateTestCasesForSut(Any.AddressUs.City)}, + new object[] + {new Words(FromDictionary.AddressUsCompany), GenerateTestCasesForSut(Any.AddressUs.Company)}, + new object[] + {new Words(FromDictionary.AddressUsPhone), GenerateTestCasesForSut(Any.AddressUs.Phone)}, + new object[] + {new Words(FromDictionary.AddressUsSocialSecurityNumber), GenerateTestCasesForSut(Any.AddressUs.SocialSecurityNumber)}, + new object[] + {new Words(FromDictionary.AddressUsState), GenerateTestCasesForSut(Any.AddressUs.State)}, + new object[] + { + new Words(FromDictionary.AddressUsStateAbbreviation), + GenerateTestCasesForSut(Any.AddressUs.StateAbbreviation) + }, + new object[] + {new Words(FromDictionary.AddressUsStreet), GenerateTestCasesForSut(Any.AddressUs.Street)}, + new object[] + {new Words(FromDictionary.AddressUsWebsite), GenerateTestCasesForSut(Any.AddressUs.Website)}, + new object[] + {new Words(FromDictionary.AddressUsZipCode), GenerateTestCasesForSut(Any.AddressUs.ZipCode)} + }; + } + } +} diff --git a/TestStack.Dossier.Tests/EquivalenceClasses/ColourEquivalenceTests.cs b/TestStack.Dossier.Tests/EquivalenceClasses/ColourEquivalenceTests.cs new file mode 100644 index 0000000..ca48af8 --- /dev/null +++ b/TestStack.Dossier.Tests/EquivalenceClasses/ColourEquivalenceTests.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using TestStack.Dossier.DataSources; +using TestStack.Dossier.DataSources.Dictionaries; +using Xunit; + +namespace TestStack.Dossier.Tests.EquivalenceClasses +{ + public class ColourEquivalenceTests : FileDictionaryEquivalenceTests + { + [Theory] + [ClassData(typeof(ColourTestCases))] + public override void WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(DataSource source, List testCases) + { + base.WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(source, testCases); + } + } + + public class ColourTestCases : FileDictionaryEquivalenceTestCases + { + protected override List GetData() + { + return new List + { + new object[] + {new Words(FromDictionary.ColourHex), GenerateTestCasesForSut(Any.Colour.Hex)}, + new object[] + {new Words(FromDictionary.ColourName), GenerateTestCasesForSut(Any.Colour.Name)} + }; + } + } +} diff --git a/TestStack.Dossier.Tests/EquivalenceClasses/CompanyEquivalenceTests.cs b/TestStack.Dossier.Tests/EquivalenceClasses/CompanyEquivalenceTests.cs new file mode 100644 index 0000000..60a4530 --- /dev/null +++ b/TestStack.Dossier.Tests/EquivalenceClasses/CompanyEquivalenceTests.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using TestStack.Dossier.DataSources; +using TestStack.Dossier.DataSources.Dictionaries; +using Xunit; + +namespace TestStack.Dossier.Tests.EquivalenceClasses +{ + public class CompanyEquivalenceTests : FileDictionaryEquivalenceTests + { + [Theory] + [ClassData(typeof(CompanyTestCases))] + public override void WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(DataSource source, List testCases) + { + base.WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(source, testCases); + } + } + + public class CompanyTestCases : FileDictionaryEquivalenceTestCases + { + protected override List GetData() + { + return new List + { + new object[] + {new Words(FromDictionary.CompanyName), GenerateTestCasesForSut(Any.Company.Name)}, + new object[] + {new Words(FromDictionary.CompanyIndustry), GenerateTestCasesForSut(Any.Company.Industry)}, + new object[] + {new Words(FromDictionary.CompanyJobTitle), GenerateTestCasesForSut(Any.Company.JobTitle)}, + new object[] + {new Words(FromDictionary.CompanyLocation), GenerateTestCasesForSut(Any.Company.Location)} + }; + } + } +} diff --git a/TestStack.Dossier.Tests/EquivalenceClasses/FileDictionaryEquivalenceTestCases.cs b/TestStack.Dossier.Tests/EquivalenceClasses/FileDictionaryEquivalenceTestCases.cs new file mode 100644 index 0000000..315e23b --- /dev/null +++ b/TestStack.Dossier.Tests/EquivalenceClasses/FileDictionaryEquivalenceTestCases.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace TestStack.Dossier.Tests.EquivalenceClasses +{ + public abstract class FileDictionaryEquivalenceTestCases : IEnumerable + { + protected abstract List GetData(); + + protected AnonymousValueFixture Any = new AnonymousValueFixture(); + + private List _data; + public List Data + { + get + { + if (_data == null) + { + _data = GetData(); + } + return _data; + } + } + + protected List GenerateTestCasesForSut(Func any) + { + var results = new List(); + for (int i = 0; i < 10; i++) + { + results.Add(any()); + } + return results; + } + + public IEnumerator GetEnumerator() + { + return Data.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier.Tests/EquivalenceClasses/FileDictionaryEquivalenceTests.cs b/TestStack.Dossier.Tests/EquivalenceClasses/FileDictionaryEquivalenceTests.cs new file mode 100644 index 0000000..5ab0c3d --- /dev/null +++ b/TestStack.Dossier.Tests/EquivalenceClasses/FileDictionaryEquivalenceTests.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using System.Linq; +using Shouldly; +using TestStack.Dossier.DataSources; + +namespace TestStack.Dossier.Tests.EquivalenceClasses +{ + public abstract class FileDictionaryEquivalenceTests + { + protected AnonymousValueFixture Any = new AnonymousValueFixture(); + + public virtual void WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(DataSource source, + List testCases) + { + foreach (var testCase in testCases) + { + testCase.ShouldBeOfType(); + testCase.ShouldNotBeNullOrEmpty(); + source.Data.ShouldContain(testCase); + } + if (source.Data.Count > 15) + { + var unique = testCases.Distinct().Count(); + unique.ShouldBeGreaterThan(5); + } + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier.Tests/EquivalenceClasses/FinanceEquivalenceTests.cs b/TestStack.Dossier.Tests/EquivalenceClasses/FinanceEquivalenceTests.cs new file mode 100644 index 0000000..35aa1fa --- /dev/null +++ b/TestStack.Dossier.Tests/EquivalenceClasses/FinanceEquivalenceTests.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using TestStack.Dossier.DataSources; +using TestStack.Dossier.DataSources.Dictionaries; +using Xunit; + +namespace TestStack.Dossier.Tests.EquivalenceClasses +{ + public class FinanceEquivalenceTests : FileDictionaryEquivalenceTests + { + [Theory] + [ClassData(typeof(FinanceTestCases))] + public override void WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(DataSource source, List testCases) + { + base.WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(source, testCases); + } + } + + public class FinanceTestCases : FileDictionaryEquivalenceTestCases + { + protected override List GetData() + { + return new List + { + new object[] + {new Words(FromDictionary.FinanceCreditCardNumber), GenerateTestCasesForSut(Any.Finance.CreditCardNumber)}, + new object[] + {new Words(FromDictionary.FinanceCreditCardType), GenerateTestCasesForSut(Any.Finance.CreditCardType)}, + new object[] + {new Words(FromDictionary.FinanceCurrency), GenerateTestCasesForSut(Any.Finance.Currency)}, + new object[] + {new Words(FromDictionary.FinanceCurrencyCode), GenerateTestCasesForSut(Any.Finance.CurrencyCode)} + }; + } + } +} diff --git a/TestStack.Dossier.Tests/EquivalenceClasses/FrequencyEquivalenceTests.cs b/TestStack.Dossier.Tests/EquivalenceClasses/FrequencyEquivalenceTests.cs new file mode 100644 index 0000000..ab7e107 --- /dev/null +++ b/TestStack.Dossier.Tests/EquivalenceClasses/FrequencyEquivalenceTests.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using TestStack.Dossier.DataSources; +using TestStack.Dossier.DataSources.Dictionaries; +using Xunit; + +namespace TestStack.Dossier.Tests.EquivalenceClasses +{ + public class FrequencyEquivalenceTests : FileDictionaryEquivalenceTests + { + [Theory] + [ClassData(typeof(FrequencyTestCases))] + public override void WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(DataSource source, List testCases) + { + base.WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(source, testCases); + } + } + + public class FrequencyTestCases : FileDictionaryEquivalenceTestCases + { + protected override List GetData() + { + return new List + { + new object[] + {new Words(FromDictionary.Frequency), GenerateTestCasesForSut(Any.Frequency)} + }; + } + } +} diff --git a/TestStack.Dossier.Tests/EquivalenceClasses/GeoEquivalenceClassesTests.cs b/TestStack.Dossier.Tests/EquivalenceClasses/GeoEquivalenceClassesTests.cs index c5fa667..40a5181 100644 --- a/TestStack.Dossier.Tests/EquivalenceClasses/GeoEquivalenceClassesTests.cs +++ b/TestStack.Dossier.Tests/EquivalenceClasses/GeoEquivalenceClassesTests.cs @@ -1,62 +1,33 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Shouldly; +using System.Collections.Generic; using TestStack.Dossier.DataSources; -using TestStack.Dossier.DataSources.Geography; +using TestStack.Dossier.DataSources.Dictionaries; using TestStack.Dossier.EquivalenceClasses.Geo; using Xunit; -using Xunit.Extensions; namespace TestStack.Dossier.Tests.EquivalenceClasses { - public class GeoEquivalenceClassesTests + public class GeoEquivalenceClassesTests : FileDictionaryEquivalenceTests { - public static AnonymousValueFixture Any { get; private set; } - - public GeoEquivalenceClassesTests() - { - Any = new AnonymousValueFixture(); - } - [Theory] - [PropertyData("TestCases")] - public void WhenGettingAnyGeoData_ThenReturnRandomGeoDataWhichIsReasonablyUnique(DataSource source, - List testCases) + [ClassData(typeof(GeographyTestCases))] + public override void WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(DataSource source, List testCases) { - foreach (var testCase in testCases) - { - testCase.ShouldBeOfType(); - testCase.ShouldNotBeNullOrEmpty(); - source.Data.ShouldContain(testCase); - } - if (source.Data.Count > 15) - { - var unique = testCases.Distinct().Count(); - unique.ShouldBeGreaterThan(5); - } + base.WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(source, testCases); } + } - public static IEnumerable TestCases + public class GeographyTestCases : FileDictionaryEquivalenceTestCases + { + protected override List GetData() { - get + return new List { - yield return new object[] { new GeoContinentSource(), GenerateTestCasesForSut(Any.Continent) }; - yield return new object[] { new GeoCountrySource(), GenerateTestCasesForSut(Any.Country) }; - yield return new object[] { new GeoCountryCodeSource(), GenerateTestCasesForSut(Any.CountryCode) }; - yield return new object[] { new GeoLatitudeSource(), GenerateTestCasesForSut(Any.Latitude) }; - yield return new object[] { new GeoLongitudeSource(), GenerateTestCasesForSut(Any.Longitude) }; - } + new object[] {new Words(FromDictionary.GeoContinent), GenerateTestCasesForSut(Any.Geography.Continent)}, + new object[] {new Words(FromDictionary.GeoCountry), GenerateTestCasesForSut(Any.Geography.Country)}, + new object[] {new Words(FromDictionary.GeoCountryCode), GenerateTestCasesForSut(Any.Geography.CountryCode)}, + new object[] {new Words(FromDictionary.GeoLatitude), GenerateTestCasesForSut(Any.Geography.Latitude)}, + new object[] {new Words(FromDictionary.GeoLongitude), GenerateTestCasesForSut(Any.Geography.Longitude)}, + }; } - - private static List GenerateTestCasesForSut(Func any) - { - var results = new List(); - for (int i = 0; i < 10; i++) - { - results.Add(any()); - } - return results; - } } } diff --git a/TestStack.Dossier.Tests/EquivalenceClasses/GeoEquivalenceTests.cs b/TestStack.Dossier.Tests/EquivalenceClasses/GeoEquivalenceTests.cs new file mode 100644 index 0000000..69e5803 --- /dev/null +++ b/TestStack.Dossier.Tests/EquivalenceClasses/GeoEquivalenceTests.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using TestStack.Dossier.DataSources; +using TestStack.Dossier.DataSources.Dictionaries; +using Xunit; + +namespace TestStack.Dossier.Tests.EquivalenceClasses +{ + public class GeoEquivalenceTests : FileDictionaryEquivalenceTests + { + [Theory] + [ClassData(typeof(GeoTestCases))] + public override void WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(DataSource source, List testCases) + { + base.WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(source, testCases); + } + } + + public class GeoTestCases : FileDictionaryEquivalenceTestCases + { + protected override List GetData() + { + return new List + { + new object[] {new Words(FromDictionary.GeoContinent), GenerateTestCasesForSut(Any.Geography.Continent)}, + new object[] {new Words(FromDictionary.GeoCountry), GenerateTestCasesForSut(Any.Geography.Country)}, + new object[] {new Words(FromDictionary.GeoCountryCode), GenerateTestCasesForSut(Any.Geography.CountryCode)}, + new object[] {new Words(FromDictionary.GeoLatitude), GenerateTestCasesForSut(Any.Geography.Latitude)}, + new object[] {new Words(FromDictionary.GeoLongitude), GenerateTestCasesForSut(Any.Geography.Longitude)}, + }; + } + } +} diff --git a/TestStack.Dossier.Tests/EquivalenceClasses/IdentifierEquivalenceTests.cs b/TestStack.Dossier.Tests/EquivalenceClasses/IdentifierEquivalenceTests.cs new file mode 100644 index 0000000..45950ba --- /dev/null +++ b/TestStack.Dossier.Tests/EquivalenceClasses/IdentifierEquivalenceTests.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using TestStack.Dossier.DataSources; +using TestStack.Dossier.DataSources.Dictionaries; +using Xunit; + +namespace TestStack.Dossier.Tests.EquivalenceClasses +{ + public class IdentifierEquivalenceTests : FileDictionaryEquivalenceTests + { + [Theory] + [ClassData(typeof(IdentifierTestCases))] + public override void WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(DataSource source, List testCases) + { + base.WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(source, testCases); + } + } + + public class IdentifierTestCases : FileDictionaryEquivalenceTestCases + { + protected override List GetData() + { + return new List + { + new object[] + { + new Words(FromDictionary.IdentifierBitcoinAddress), + GenerateTestCasesForSut(Any.Identifier.BitcoinAddress) + }, + new object[] + {new Words(FromDictionary.IdentifierIban), GenerateTestCasesForSut(Any.Identifier.Iban)}, + new object[] + { + new Words(FromDictionary.IdentifierIpAddressV4), GenerateTestCasesForSut(Any.Identifier.IpAddressV4) + }, + new object[] + { + new Words(FromDictionary.IdentifierIpAddressV6), GenerateTestCasesForSut(Any.Identifier.IpAddressV6) + }, + new object[] + {new Words(FromDictionary.IdentifierIsbn), GenerateTestCasesForSut(Any.Identifier.Isbn)}, + new object[] + { + new Words(FromDictionary.IdentifierMacAddress), + GenerateTestCasesForSut(Any.Identifier.MacAddress) + } + }; + } + } +} diff --git a/TestStack.Dossier.Tests/EquivalenceClasses/IntegerEquivalenceTests.cs b/TestStack.Dossier.Tests/EquivalenceClasses/IntegerEquivalenceTests.cs new file mode 100644 index 0000000..9df140e --- /dev/null +++ b/TestStack.Dossier.Tests/EquivalenceClasses/IntegerEquivalenceTests.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using TestStack.Dossier.DataSources; +using TestStack.Dossier.DataSources.Dictionaries; +using Xunit; + +namespace TestStack.Dossier.Tests.EquivalenceClasses +{ + public class InternetEquivalenceTests : FileDictionaryEquivalenceTests + { + [Theory] + [ClassData(typeof(InternetTestCases))] + public override void WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(DataSource source, List testCases) + { + base.WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(source, testCases); + } + } + + public class InternetTestCases : FileDictionaryEquivalenceTestCases + { + protected override List GetData() + { + return new List + { + new object[] + { + new Words(FromDictionary.InternetDomainCountryCodeTopLevelDomain), + GenerateTestCasesForSut(Any.Internet.DomainCountryCodeTopLevelDomain) + }, + new object[] + {new Words(FromDictionary.InternetDomainName), GenerateTestCasesForSut(Any.Internet.DomainName)}, + new object[] + { + new Words(FromDictionary.InternetDomainTopLevel), + GenerateTestCasesForSut(Any.Internet.DomainTopLevel) + }, + new object[] + {new Words(FromDictionary.InternetUrl), GenerateTestCasesForSut(Any.Internet.Url)} + }; + } + } +} diff --git a/TestStack.Dossier.Tests/EquivalenceClasses/LoremIpsumEquivalenceTests.cs b/TestStack.Dossier.Tests/EquivalenceClasses/LoremIpsumEquivalenceTests.cs new file mode 100644 index 0000000..b652093 --- /dev/null +++ b/TestStack.Dossier.Tests/EquivalenceClasses/LoremIpsumEquivalenceTests.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using TestStack.Dossier.DataSources; +using TestStack.Dossier.DataSources.Dictionaries; +using Xunit; + +namespace TestStack.Dossier.Tests.EquivalenceClasses +{ + public class LoremIpsumEquivalenceTests : FileDictionaryEquivalenceTests + { + [Theory] + [ClassData(typeof(LoremIpsumTestCases))] + public override void WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(DataSource source, List testCases) + { + base.WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(source, testCases); + } + } + + public class LoremIpsumTestCases : FileDictionaryEquivalenceTestCases + { + protected override List GetData() + { + return new List + { + new object[] + {new Words(FromDictionary.LoremIpsum), GenerateTestCasesForSut(Any.LoremIpsum)} + }; + } + } +} diff --git a/TestStack.Dossier.Tests/EquivalenceClasses/PersonEquivalenceClassesTests.cs b/TestStack.Dossier.Tests/EquivalenceClasses/PersonEquivalenceClassesTests.cs index 81db6dd..7f13c4a 100644 --- a/TestStack.Dossier.Tests/EquivalenceClasses/PersonEquivalenceClassesTests.cs +++ b/TestStack.Dossier.Tests/EquivalenceClasses/PersonEquivalenceClassesTests.cs @@ -1,83 +1,61 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Shouldly; using TestStack.Dossier.DataSources; -using TestStack.Dossier.DataSources.Person; +using TestStack.Dossier.DataSources.Dictionaries; using TestStack.Dossier.EquivalenceClasses.Person; using Xunit; -using Xunit.Extensions; namespace TestStack.Dossier.Tests.EquivalenceClasses { - public class PersonEquivalenceClassesTests + public class PersonEquivalenceClassesTests : FileDictionaryEquivalenceTests { - public static AnonymousValueFixture Any { get; private set; } - - public PersonEquivalenceClassesTests() - { - Any = new AnonymousValueFixture(); - } - [Theory] - [PropertyData("TestCases")] - public void WhenGettingAnyPersonData_ThenReturnRandomPersonDataWhichIsReasonablyUnique(DataSource source, - List testCases) + [ClassData(typeof(PersonTestCases2))] + public override void WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(DataSource source, List testCases) { - foreach (var testCase in testCases) - { - testCase.ShouldBeOfType(); - testCase.ShouldNotBeNullOrEmpty(); - source.Data.ShouldContain(testCase); - } - if (source.Data.Count > 15) - { - var unique = testCases.Distinct().Count(); - unique.ShouldBeGreaterThan(5); - } + base.WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(source, testCases); } [Fact] public void WhenGettingUniqueEmail_ThenReturnUniqueEmailsAcrossFixtureInstances() { - var source = new PersonEmailAddressSource(); + var source = new Words(FromDictionary.PersonEmailAddress); var generatedValues = new List(); var any2 = new AnonymousValueFixture(); - generatedValues.Add(any2.UniqueEmailAddress()); + PersonEquivalenceExtensions.InitializeUniqueEmailAddressSource(); + generatedValues.Add(any2.Person.UniqueEmailAddress()); for (var i = 0; i < source.Data.Count - 1; i++) { - generatedValues.Add(Any.UniqueEmailAddress()); + generatedValues.Add(Any.Person.UniqueEmailAddress()); } generatedValues.Distinct().Count() .ShouldBe(generatedValues.Count); } + } - public static IEnumerable TestCases + public class PersonTestCases2 : FileDictionaryEquivalenceTestCases + { + protected override List GetData() { - get + return new List { - yield return new object[] { new PersonEmailAddressSource(), GenerateTestCasesForSut(Any.EmailAddress) }; - yield return new object[] { new PersonLanguageSource(), GenerateTestCasesForSut(Any.Language) }; - yield return new object[] { new PersonNameFirstFemaleSource(), GenerateTestCasesForSut(Any.FemaleFirstName) }; - yield return new object[] { new PersonNameFirstSource(), GenerateTestCasesForSut(Any.FirstName) }; - yield return new object[] { new PersonNameFullSource(), GenerateTestCasesForSut(Any.FullName) }; - yield return new object[] { new PersonNameLastSource(), GenerateTestCasesForSut(Any.LastName) }; - yield return new object[] { new PersonNameFirstMaleSource(), GenerateTestCasesForSut(Any.MaleFirstName) }; - yield return new object[] { new PersonNameSuffixSource(), GenerateTestCasesForSut(Any.Suffix) }; - yield return new object[] { new PersonNameTitleSource(), GenerateTestCasesForSut(Any.Title) }; - } + new object[] + {new Words(FromDictionary.PersonEmailAddress), GenerateTestCasesForSut(Any.Person.EmailAddress)}, + new object[] {new Words(FromDictionary.PersonLanguage), GenerateTestCasesForSut(Any.Person.Language)}, + new object[] + {new Words(FromDictionary.PersonNameFirstFemale), GenerateTestCasesForSut(Any.Person.NameFirstFemale)}, + new object[] {new Words(FromDictionary.PersonNameFirst), GenerateTestCasesForSut(Any.Person.NameFirst)}, + new object[] {new Words(FromDictionary.PersonNameFull), GenerateTestCasesForSut(Any.Person.NameFull)}, + new object[] {new Words(FromDictionary.PersonNameLast), GenerateTestCasesForSut(Any.Person.NameLast)}, + new object[] + {new Words(FromDictionary.PersonNameFirstMale), GenerateTestCasesForSut(Any.Person.NameFirstMale)}, + new object[] {new Words(FromDictionary.PersonNameSuffix), GenerateTestCasesForSut(Any.Person.NameSuffix)}, + new object[] {new Words(FromDictionary.PersonNameTitle), GenerateTestCasesForSut(Any.Person.NameTitle)}, + }; } - - private static List GenerateTestCasesForSut(Func any) - { - var results = new List(); - for (int i = 0; i < 10; i++) - { - results.Add(any()); - } - return results; - } } + } diff --git a/TestStack.Dossier.Tests/EquivalenceClasses/PersonEquivalenceTests.cs b/TestStack.Dossier.Tests/EquivalenceClasses/PersonEquivalenceTests.cs new file mode 100644 index 0000000..f057e2d --- /dev/null +++ b/TestStack.Dossier.Tests/EquivalenceClasses/PersonEquivalenceTests.cs @@ -0,0 +1,59 @@ +using System.Collections.Generic; +using System.Linq; +using Shouldly; +using TestStack.Dossier.DataSources; +using TestStack.Dossier.DataSources.Dictionaries; +using Xunit; + +namespace TestStack.Dossier.Tests.EquivalenceClasses +{ + public class PersonEquivalenceTests : FileDictionaryEquivalenceTests + { + [Theory] + [ClassData(typeof(PersonTestCases))] + public override void WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(DataSource source, List testCases) + { + base.WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(source, testCases); + } + + [Fact] + public void WhenGettingUniqueEmail_ThenReturnUniqueEmailsAcrossFixtureInstances() + { + var source = new Words(FromDictionary.PersonEmailAddress); + var generatedValues = new List(); + var any2 = new AnonymousValueFixture(); + + PersonEquivalenceExtensions.InitializeUniqueEmailAddressSource(); + generatedValues.Add(any2.Person.UniqueEmailAddress()); + for (var i = 0; i < source.Data.Count - 1; i++) + { + generatedValues.Add(Any.Person.UniqueEmailAddress()); + } + + generatedValues.Distinct().Count() + .ShouldBe(generatedValues.Count); + } + } + + public class PersonTestCases : FileDictionaryEquivalenceTestCases + { + protected override List GetData() + { + return new List + { + new object[] + {new Words(FromDictionary.PersonEmailAddress), GenerateTestCasesForSut(Any.Person.EmailAddress)}, + new object[] {new Words(FromDictionary.PersonLanguage), GenerateTestCasesForSut(Any.Person.Language)}, + new object[] + {new Words(FromDictionary.PersonNameFirstFemale), GenerateTestCasesForSut(Any.Person.NameFirstFemale)}, + new object[] {new Words(FromDictionary.PersonNameFirst), GenerateTestCasesForSut(Any.Person.NameFirst)}, + new object[] {new Words(FromDictionary.PersonNameFull), GenerateTestCasesForSut(Any.Person.NameFull)}, + new object[] {new Words(FromDictionary.PersonNameLast), GenerateTestCasesForSut(Any.Person.NameLast)}, + new object[] + {new Words(FromDictionary.PersonNameFirstMale), GenerateTestCasesForSut(Any.Person.NameFirstMale)}, + new object[] {new Words(FromDictionary.PersonNameSuffix), GenerateTestCasesForSut(Any.Person.NameSuffix)}, + new object[] {new Words(FromDictionary.PersonNameTitle), GenerateTestCasesForSut(Any.Person.NameTitle)}, + }; + } + } +} diff --git a/TestStack.Dossier.Tests/EquivalenceClasses/ShirtSizeEquivalenceTests.cs b/TestStack.Dossier.Tests/EquivalenceClasses/ShirtSizeEquivalenceTests.cs new file mode 100644 index 0000000..2795f7c --- /dev/null +++ b/TestStack.Dossier.Tests/EquivalenceClasses/ShirtSizeEquivalenceTests.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using TestStack.Dossier.DataSources; +using TestStack.Dossier.DataSources.Dictionaries; +using Xunit; + +namespace TestStack.Dossier.Tests.EquivalenceClasses +{ + public class ShirtSizeEquivalenceTests : FileDictionaryEquivalenceTests + { + [Theory] + [ClassData(typeof(ShirtSizeTestCases))] + public override void WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(DataSource source, List testCases) + { + base.WhenGettingAnyData_ThenReturnRandomDataWhichIsReasonablyUnique(source, testCases); + } + } + + public class ShirtSizeTestCases : FileDictionaryEquivalenceTestCases + { + protected override List GetData() + { + return new List + { + new object[] + {new Words(FromDictionary.ShirtSize), GenerateTestCasesForSut(Any.ShirtSize)} + }; + } + } +} diff --git a/TestStack.Dossier.Tests/Factories/AllPropertiesFactoryTests.cs b/TestStack.Dossier.Tests/Factories/AllPropertiesFactoryTests.cs new file mode 100644 index 0000000..cbd8956 --- /dev/null +++ b/TestStack.Dossier.Tests/Factories/AllPropertiesFactoryTests.cs @@ -0,0 +1,41 @@ +using System; +using Shouldly; +using TestStack.Dossier.Factories; +using TestStack.Dossier.Tests.TestHelpers.Objects.Examples; +using Xunit; + +namespace TestStack.Dossier.Tests.Factories +{ + public class AllPropertiesFactoryTests + { + [Fact] + public void GivenAllPropertiesFactory_WhenBuilding_ThenAllPropertiesSet() + { + MixedAccessibilityDto dto = Builder.CreateNew(new AllPropertiesFactory()); + + dto.SetByCtorNoPropertySetter.ShouldNotBe(null); + dto.SetByCtorWithPrivateSetter.ShouldNotBe(null); + dto.SetByCtorWithPublicSetter.ShouldNotBe(null); + dto.NotSetByCtorWithPrivateSetter.ShouldNotBe(null); + dto.NotSetByCtorWithPublicSetter.ShouldNotBe(null); + } + + [Fact] + public void GivenAllPropertiesFactoryAgainstBuilderWithModifications_WhenBuilding_ThenCustomisationsAreUsed() + { + MixedAccessibilityDto dto = Builder + .CreateNew(new AllPropertiesFactory()) + .Set(x => x.SetByCtorNoPropertySetter, "0") + .Set(x => x.SetByCtorWithPrivateSetter, "1") + .Set(x => x.SetByCtorWithPublicSetter, "2") + .Set(x => x.NotSetByCtorWithPrivateSetter, "3") + .Set(x => x.NotSetByCtorWithPublicSetter, "4"); + + dto.SetByCtorNoPropertySetter.ShouldBe("0"); + dto.SetByCtorWithPrivateSetter.ShouldBe("1"); + dto.SetByCtorWithPublicSetter.ShouldBe("2"); + dto.NotSetByCtorWithPrivateSetter.ShouldBe("3"); + dto.NotSetByCtorWithPublicSetter.ShouldBe("4"); + } + } +} diff --git a/TestStack.Dossier.Tests/Factories/AutoFixtureFactoryTests.cs b/TestStack.Dossier.Tests/Factories/AutoFixtureFactoryTests.cs new file mode 100644 index 0000000..899135b --- /dev/null +++ b/TestStack.Dossier.Tests/Factories/AutoFixtureFactoryTests.cs @@ -0,0 +1,40 @@ +using Shouldly; +using TestStack.Dossier.Factories; +using TestStack.Dossier.Tests.TestHelpers.Objects.Examples; +using Xunit; + +namespace TestStack.Dossier.Tests.Factories +{ + public class AutoFixtureFactoryTests + { + [Fact] + public void GivenAutoFixtureFactory_WhenBuilding_ThenOnlyConstructorAndPublicPropertiesSet() + { + MixedAccessibilityDto dto = Builder.CreateNew(new AutoFixtureFactory()); + + dto.SetByCtorNoPropertySetter.ShouldNotBe(null); + dto.SetByCtorWithPrivateSetter.ShouldNotBe(null); + dto.SetByCtorWithPublicSetter.ShouldNotBe(null); + dto.NotSetByCtorWithPrivateSetter.ShouldBe(null); + dto.NotSetByCtorWithPublicSetter.ShouldNotBe(null); + } + + [Fact] + public void GivenAutoFixtureFactoryAgainstBuilderWithModifications_WhenBuilding_ThenNoCustomisationsAreUsed() + { + MixedAccessibilityDto dto = Builder + .CreateNew(new AutoFixtureFactory()) + .Set(x => x.SetByCtorNoPropertySetter, "0") + .Set(x => x.SetByCtorWithPrivateSetter, "1") + .Set(x => x.SetByCtorWithPublicSetter, "2") + .Set(x => x.NotSetByCtorWithPrivateSetter, "3") + .Set(x => x.NotSetByCtorWithPublicSetter, "4"); + + dto.SetByCtorNoPropertySetter.ShouldNotBe("0"); + dto.SetByCtorWithPrivateSetter.ShouldNotBe("1"); + dto.SetByCtorWithPublicSetter.ShouldNotBe("2"); + dto.NotSetByCtorWithPrivateSetter.ShouldNotBe("3"); + dto.NotSetByCtorWithPublicSetter.ShouldNotBe("4"); + } + } +} diff --git a/TestStack.Dossier.Tests/Factories/CallConstructorFactoryTests.cs b/TestStack.Dossier.Tests/Factories/CallConstructorFactoryTests.cs new file mode 100644 index 0000000..61a9d01 --- /dev/null +++ b/TestStack.Dossier.Tests/Factories/CallConstructorFactoryTests.cs @@ -0,0 +1,40 @@ +using Shouldly; +using TestStack.Dossier.Factories; +using TestStack.Dossier.Tests.TestHelpers.Objects.Examples; +using Xunit; + +namespace TestStack.Dossier.Tests.Factories +{ + public class CallConstructorFactoryTests + { + [Fact] + public void GivenCallConstructorFactory_WhenBuilding_ThenOnlyConstructorPropertiesSet() + { + MixedAccessibilityDto dto = Builder.CreateNew(new CallConstructorFactory()); + + dto.SetByCtorNoPropertySetter.ShouldNotBe(null); + dto.SetByCtorWithPrivateSetter.ShouldNotBe(null); + dto.SetByCtorWithPublicSetter.ShouldNotBe(null); + dto.NotSetByCtorWithPrivateSetter.ShouldBe(null); + dto.NotSetByCtorWithPublicSetter.ShouldBe(null); + } + + [Fact] + public void GivenCallConstructorFactoryAgainstBuilderWithModifications_WhenBuilding_ThenCustomisationsAreUsed() + { + MixedAccessibilityDto dto = Builder + .CreateNew(new CallConstructorFactory()) + .Set(x => x.SetByCtorNoPropertySetter, "0") + .Set(x => x.SetByCtorWithPrivateSetter, "1") + .Set(x => x.SetByCtorWithPublicSetter, "2") + .Set(x => x.NotSetByCtorWithPrivateSetter, "3") + .Set(x => x.NotSetByCtorWithPublicSetter, "4"); + + dto.SetByCtorNoPropertySetter.ShouldBe("0"); + dto.SetByCtorWithPrivateSetter.ShouldBe("1"); + dto.SetByCtorWithPublicSetter.ShouldBe("2"); + dto.NotSetByCtorWithPrivateSetter.ShouldBe(null); + dto.NotSetByCtorWithPublicSetter.ShouldBe(null); + } + } +} diff --git a/TestStack.Dossier.Tests/Factories/FactoryTests.cs b/TestStack.Dossier.Tests/Factories/FactoryTests.cs deleted file mode 100644 index c90dc01..0000000 --- a/TestStack.Dossier.Tests/Factories/FactoryTests.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using Shouldly; -using TestStack.Dossier.Factories; -using TestStack.Dossier.Tests.Stubs.Entities; -using TestStack.Dossier.Tests.Stubs.ViewModels; -using Xunit; - -namespace TestStack.Dossier.Tests.Factories -{ - public class FactoryTests - { - [Fact] - public void GivenAllPropertiesFactory_WhenBuilding_ThenAllPropertiesSet() - { - InstructorViewModel instructor = Builder.CreateNew(new AllPropertiesFactory()); - - // ctor properties - instructor.Id.ShouldNotBe(Guid.Empty); - instructor.FirstName.ShouldNotBe(null); - instructor.LastName.ShouldNotBe(null); - - // public properties - instructor.Room.ShouldNotBe(null); - instructor.NumberOfStudents.ShouldNotBe(0); - - // private properties - instructor.Subject.ShouldNotBe(null); - instructor.YearsAtSchool.ShouldNotBe(0); - } - - [Fact] - public void GivenAutoFixtureFactory_WhenBuilding_ThenOnlyConstructorAndPublicPropertiesSet() - { - InstructorViewModel instructor = Builder.CreateNew(new AutoFixtureFactory()); - - // ctor properties - instructor.Id.ShouldNotBe(Guid.Empty); - instructor.FirstName.ShouldNotBe(null); - instructor.LastName.ShouldNotBe(null); - - // public properties - instructor.Room.ShouldNotBe(null); - instructor.NumberOfStudents.ShouldNotBe(0); - - // private properties - instructor.Subject.ShouldBe(null); - instructor.YearsAtSchool.ShouldBe(0); - } - - [Fact] - public void GivenConstructorPropertiesFactory_WhenBuilding_ThenOnlyConstructorPropertiesSet() - { - InstructorViewModel instructor = Builder.CreateNew(new ConstructorFactory()); - - // ctor properties - instructor.Id.ShouldNotBe(Guid.Empty); - instructor.FirstName.ShouldNotBe(null); - instructor.LastName.ShouldNotBe(null); - - // public properties - instructor.Room.ShouldBe(null); - instructor.NumberOfStudents.ShouldBe(0); - - // private properties - instructor.Subject.ShouldBe(null); - instructor.YearsAtSchool.ShouldBe(0); - } - - [Fact] - public void GivenPublicPropertiesFactory_WhenBuilding_ThenOnlyConstructorAndPublicPropertiesSet() - { - InstructorViewModel instructor = Builder.CreateNew(new PublicPropertiesFactory()); - - // ctor properties - instructor.Id.ShouldNotBe(Guid.Empty); - instructor.FirstName.ShouldNotBe(null); - instructor.LastName.ShouldNotBe(null); - - // public properties - instructor.Room.ShouldNotBe(null); - instructor.NumberOfStudents.ShouldBeGreaterThan(0); - - // private properties - instructor.Subject.ShouldBe(null); - instructor.YearsAtSchool.ShouldBe(0); - } - } -} diff --git a/TestStack.Dossier.Tests/Factories/PublicPropertySettersFactoryTests.cs b/TestStack.Dossier.Tests/Factories/PublicPropertySettersFactoryTests.cs new file mode 100644 index 0000000..3dbe57c --- /dev/null +++ b/TestStack.Dossier.Tests/Factories/PublicPropertySettersFactoryTests.cs @@ -0,0 +1,40 @@ +using Shouldly; +using TestStack.Dossier.Factories; +using TestStack.Dossier.Tests.TestHelpers.Objects.Examples; +using Xunit; + +namespace TestStack.Dossier.Tests.Factories +{ + public class PublicPropertySettersFactoryTests + { + [Fact] + public void GivenPublicPropertySettersFactory_WhenBuilding_ThenOnlyConstructorAndPublicPropertiesSet() + { + MixedAccessibilityDto dto = Builder.CreateNew(new PublicPropertySettersFactory()); + + dto.SetByCtorNoPropertySetter.ShouldNotBe(null); + dto.SetByCtorWithPrivateSetter.ShouldNotBe(null); + dto.SetByCtorWithPublicSetter.ShouldNotBe(null); + dto.NotSetByCtorWithPrivateSetter.ShouldBe(null); + dto.NotSetByCtorWithPublicSetter.ShouldNotBe(null); + } + + [Fact] + public void GivenPublicPropertySettersFactoryAgainstBuilderWithModifications_WhenBuilding_ThenCustomisationsAreUsed() + { + MixedAccessibilityDto dto = Builder + .CreateNew(new PublicPropertySettersFactory()) + .Set(x => x.SetByCtorNoPropertySetter, "0") + .Set(x => x.SetByCtorWithPrivateSetter, "1") + .Set(x => x.SetByCtorWithPublicSetter, "2") + .Set(x => x.NotSetByCtorWithPrivateSetter, "3") + .Set(x => x.NotSetByCtorWithPublicSetter, "4"); + + dto.SetByCtorNoPropertySetter.ShouldBe("0"); + dto.SetByCtorWithPrivateSetter.ShouldBe("1"); + dto.SetByCtorWithPublicSetter.ShouldBe("2"); + dto.NotSetByCtorWithPrivateSetter.ShouldBe(null); + dto.NotSetByCtorWithPublicSetter.ShouldBe("4"); + } + } +} diff --git a/TestStack.Dossier.Tests/GetAnonymousTests.cs b/TestStack.Dossier.Tests/GetAnonymousTests.cs index c415c73..3a2203e 100644 --- a/TestStack.Dossier.Tests/GetAnonymousTests.cs +++ b/TestStack.Dossier.Tests/GetAnonymousTests.cs @@ -1,9 +1,9 @@ using System; using Shouldly; -using TestStack.Dossier.DataSources.Person; +using TestStack.Dossier.DataSources.Dictionaries; using TestStack.Dossier.Lists; -using TestStack.Dossier.Tests.Builders; using TestStack.Dossier.Tests.TestHelpers; +using TestStack.Dossier.Tests.TestHelpers.Builders; using Xunit; namespace TestStack.Dossier.Tests @@ -55,7 +55,7 @@ public void GivenNoValueHasBeenSetForAPropertyNamedFirstName_WhenRetrievingTheVa { var firstName = _b.Get(x => x.FirstName); - new PersonNameFirstSource().Data + new Words(FromDictionary.PersonNameFirst).Data .ShouldContain(firstName); } @@ -64,7 +64,7 @@ public void GivenNoValueHasBeenSetForAPropertyNamedLastName_WhenRetrievingTheVal { var lastName = _b.Get(x => x.LastName); - new PersonNameLastSource().Data + new Words(FromDictionary.PersonNameLast).Data .ShouldContain(lastName); } diff --git a/TestStack.Dossier.Tests/GetOrDefaultTests.cs b/TestStack.Dossier.Tests/GetOrDefaultTests.cs index 71713a1..5bfbd6b 100644 --- a/TestStack.Dossier.Tests/GetOrDefaultTests.cs +++ b/TestStack.Dossier.Tests/GetOrDefaultTests.cs @@ -1,5 +1,5 @@ using Shouldly; -using TestStack.Dossier.Tests.Builders; +using TestStack.Dossier.Tests.TestHelpers.Builders; using Xunit; namespace TestStack.Dossier.Tests diff --git a/TestStack.Dossier.Tests/GetSetTests.cs b/TestStack.Dossier.Tests/GetSetTests.cs index 4addf96..18c98e7 100644 --- a/TestStack.Dossier.Tests/GetSetTests.cs +++ b/TestStack.Dossier.Tests/GetSetTests.cs @@ -1,6 +1,6 @@ using System; using Shouldly; -using TestStack.Dossier.Tests.Builders; +using TestStack.Dossier.Tests.TestHelpers.Builders; using Xunit; namespace TestStack.Dossier.Tests @@ -25,6 +25,27 @@ public void GivenAValueHasBeenSetAgainstAProperty_WhenRetrievingTheValueForThatP retrieved.ShouldBe(SetValue); } + [Fact] + public void GivenAValueHasBeenSetAgainstANestedProperty_WhenRetrievingTheValueForThatProperty_ThenTheSetValueIsReturned() + { + _b.Set(x => x.PostalAddress.Identifier, SetValue); + + var retrieved = _b.Get(x => x.PostalAddress.Identifier); + + retrieved.ShouldBe(SetValue); + } + + [Fact] + public void GivenAValueHasBeenSetAgainstANestedPropertyAndDifferentVaLueHasBeenSetAgainstANonNestedPropertyWithTheSameName_WhenRetrievingTheValueForThatNestedProperty_ThenTheSetValueIsReturned() + { + _b.Set(x => x.PostalAddress.Identifier, SetValue); + _b.Set(x => x.Identifier, (string)null); + + var retrieved = _b.Get(x => x.PostalAddress.Identifier); + + retrieved.ShouldBe(SetValue); + } + [Fact] public void GivenTwoValuesHaveBeenSetAgainstAProperty_WhenRetrievingTheValueForThatProperty_ThenTheLastSetValueIsReturned() { diff --git a/TestStack.Dossier.Tests/Properties/AssemblyInfo.cs b/TestStack.Dossier.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index e5d5cf8..0000000 --- a/TestStack.Dossier.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("TestStack.Dossier.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("TestStack.Dossier.Tests")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("295d98e2-8a24-4bbb-9455-08f915d782b7")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/TestStack.Dossier.Tests/ProxyBuilderTests.cs b/TestStack.Dossier.Tests/ProxyBuilderTests.cs index ae9aef8..62cbc2a 100644 --- a/TestStack.Dossier.Tests/ProxyBuilderTests.cs +++ b/TestStack.Dossier.Tests/ProxyBuilderTests.cs @@ -2,17 +2,17 @@ using System.Collections.Generic; using NSubstitute; using Shouldly; -using TestStack.Dossier.Tests.Stubs.Entities; +using TestStack.Dossier.Tests.TestHelpers.Objects.Entities; using Xunit; namespace TestStack.Dossier.Tests { - class ProxyBuilderTests + public 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.Tests/PublicApiApproval/PublicApiApproverTests.GivenDossierAssembly_WhenPublicApiChecked_ShouldHaveNoChanges.approved.txt b/TestStack.Dossier.Tests/PublicApiApproval/PublicApiApproverTests.GivenDossierAssembly_WhenPublicApiChecked_ShouldHaveNoChanges.approved.txt new file mode 100644 index 0000000..ad5a50a --- /dev/null +++ b/TestStack.Dossier.Tests/PublicApiApproval/PublicApiApproverTests.GivenDossierAssembly_WhenPublicApiChecked_ShouldHaveNoChanges.approved.txt @@ -0,0 +1,620 @@ +namespace TestStack.Dossier +{ + public class AddressAusEquivalence + { + public AddressAusEquivalence(TestStack.Dossier.AnonymousValueFixture fixture) { } + public string City() { } + public string Company() { } + public string Phone() { } + public string PostCode() { } + public string State() { } + public string StateAbbreviation() { } + public string Street() { } + public string Website() { } + } + public class AddressUkEquivalence + { + public AddressUkEquivalence(TestStack.Dossier.AnonymousValueFixture fixture) { } + public string City() { } + public string Company() { } + public string County() { } + public string Phone() { } + public string PostCode() { } + public string Street() { } + public string Website() { } + } + public class AddressUsEquivalence + { + public AddressUsEquivalence(TestStack.Dossier.AnonymousValueFixture fixture) { } + public string City() { } + public string Company() { } + public string Phone() { } + public string SocialSecurityNumber() { } + public string State() { } + public string StateAbbreviation() { } + public string Street() { } + public string Website() { } + public string ZipCode() { } + } + public class AnonymousValueFixture + { + public AnonymousValueFixture() { } + public TestStack.Dossier.AddressAusEquivalence AddressAus { get; } + public TestStack.Dossier.AddressUkEquivalence AddressUk { get; } + public TestStack.Dossier.AddressUsEquivalence AddressUs { get; } + [System.Runtime.CompilerServices.DynamicAttribute()] + public object Bag { get; } + public TestStack.Dossier.ColourEquivalence Colour { get; } + public TestStack.Dossier.CompanyEquivalence Company { get; } + public static System.Collections.Generic.IEnumerable DefaultValueSuppliers { get; } + public TestStack.Dossier.FinanceEquivalence Finance { get; } + public AutoFixture.Fixture Fixture { get; } + public TestStack.Dossier.GeoEquivalence Geography { get; } + public static System.Collections.Generic.ICollection GlobalValueSuppliers { get; } + public TestStack.Dossier.IdentifierEquivalence Identifier { get; } + public TestStack.Dossier.InternetEquivalence Internet { get; } + public System.Collections.Generic.ICollection LocalValueSuppliers { get; } + public TestStack.Dossier.PersonEquivalence Person { get; } + public AutoFixture.RegularExpressionGenerator RegexGenerator { get; } + public T Get(System.Linq.Expressions.Expression> property) { } + public object Get(System.Type type, string propertyName) { } + public TestStack.Dossier.DataSources.Dictionaries.Words Words(string dictionaryName) { } + } + public class Builder : TestStack.Dossier.TestDataBuilder> + where T : class + { + public Builder() { } + protected override T BuildObject() { } + public static TestStack.Dossier.Lists.ListBuilder> CreateListOfSize(int size, TestStack.Dossier.Factories.IFactory factory) { } + public static TestStack.Dossier.Builder CreateNew(TestStack.Dossier.Factories.IFactory factory = null) { } + public virtual TestStack.Dossier.Builder SetUsingBuilder(System.Linq.Expressions.Expression> property, System.Func modifier = null) + where TPropertyType : class + where TPropertyBuilder : TestStack.Dossier.TestDataBuilder<, >, new () { } + public virtual TestStack.Dossier.Builder SetUsingBuilder(System.Linq.Expressions.Expression> property, System.Func, TestStack.Dossier.Builder> modifier = null) + where TPropertyType : class { } + } + public class ColourEquivalence + { + public ColourEquivalence(TestStack.Dossier.AnonymousValueFixture fixture) { } + public string Hex() { } + public string Name() { } + } + public class CompanyEquivalence + { + public CompanyEquivalence(TestStack.Dossier.AnonymousValueFixture fixture) { } + public string Industry() { } + public string JobTitle() { } + public string Location() { } + public string Name() { } + } + public class FinanceEquivalence + { + public FinanceEquivalence(TestStack.Dossier.AnonymousValueFixture fixture) { } + public string CreditCardNumber() { } + public string CreditCardType() { } + public string Currency() { } + public string CurrencyCode() { } + } + public class static FrequencyEquivalence + { + public static string Frequency(this TestStack.Dossier.AnonymousValueFixture fixture) { } + } + public class GeoEquivalence + { + public GeoEquivalence(TestStack.Dossier.AnonymousValueFixture fixture) { } + public string Continent() { } + public string Country() { } + public string CountryCode() { } + public string Latitude() { } + public string Longitude() { } + } + public interface IAnonymousValueSupplier + { + bool CanSupplyValue(System.Type type, string propertyName); + object GenerateAnonymousValue(TestStack.Dossier.AnonymousValueFixture any, System.Type type, string propertyName); + } + public class IdentifierEquivalence + { + public IdentifierEquivalence(TestStack.Dossier.AnonymousValueFixture fixture) { } + public string BitcoinAddress() { } + public string Iban() { } + public string IpAddressV4() { } + public string IpAddressV6() { } + public string Isbn() { } + public string MacAddress() { } + } + public class InternetEquivalence + { + public InternetEquivalence(TestStack.Dossier.AnonymousValueFixture fixture) { } + public string DomainCountryCodeTopLevelDomain() { } + public string DomainName() { } + public string DomainTopLevel() { } + public string Url() { } + } + public interface ITestDataBuilder + where out TObject : class + { + TObject Build(); + } + public class static LoremIpsumEquivalence + { + public static string LoremIpsum(this TestStack.Dossier.AnonymousValueFixture fixture) { } + } + public class PersonEquivalence + { + public PersonEquivalence(TestStack.Dossier.AnonymousValueFixture fixture) { } + public string EmailAddress() { } + public string Language() { } + public string NameFirst() { } + public string NameFirstFemale() { } + public string NameFirstMale() { } + public string NameFull() { } + public string NameLast() { } + public string NameSuffix() { } + public string NameTitle() { } + public string Password() { } + public string Race() { } + public string Username() { } + } + public class static PersonEquivalenceExtensions + { + public static string UniqueEmailAddress(this TestStack.Dossier.PersonEquivalence personEquivalence) { } + } + public class ProxyBuilder + where T : class + { + public ProxyBuilder(System.Collections.Generic.Dictionary> properties) { } + public T Build() { } + } + public class static ShirtSizeEquivalence + { + public static string ShirtSize(this TestStack.Dossier.AnonymousValueFixture fixture) { } + } + public abstract class TestDataBuilder : TestStack.Dossier.ITestDataBuilder + where TObject : class + where TBuilder : TestStack.Dossier.TestDataBuilder<, >, new () + { + protected TestDataBuilder() { } + public TestStack.Dossier.AnonymousValueFixture Any { get; } + public TestStack.Dossier.Lists.ListBuilder ListBuilder { get; } + protected virtual void AlterProxy(TObject proxy) { } + public TBuilder AsProxy() { } + public TObject Build() { } + protected virtual TObject BuildObject() { } + protected TObject BuildUsing() + where TFactory : TestStack.Dossier.Factories.IFactory, new () { } + public static TestStack.Dossier.Lists.ListBuilder CreateListOfSize(int size) { } + public TValue Get(System.Linq.Expressions.Expression> property) { } + public object Get(System.Type type, string propertyName) { } + protected virtual TChildBuilder GetChildBuilder(System.Func modifier = null) + where TChildObject : class + where TChildBuilder : TestStack.Dossier.TestDataBuilder<, >, new () { } + public TValue GetOrDefault(System.Linq.Expressions.Expression> property) { } + protected bool Has(System.Linq.Expressions.Expression> property) { } + protected bool Has(string propertyName) { } + public virtual bool IsListBuilderProxy() { } + public static TObject op_Implicit(TestStack.Dossier.TestDataBuilder builder) { } + public static System.Collections.Generic.List op_Implicit(TestStack.Dossier.TestDataBuilder builder) { } + public virtual TBuilder Set(System.Linq.Expressions.Expression> property, TValue value) { } + public virtual TBuilder Set(System.Linq.Expressions.Expression> property, System.Func factory) { } + } +} +namespace TestStack.Dossier.DataSources +{ + public abstract class DataSource : TestStack.Dossier.DataSources.IDataSource + { + protected DataSource(TestStack.Dossier.DataSources.Generators.IGenerator generator) { } + protected DataSource() { } + public System.Collections.Generic.IList Data { get; } + public TestStack.Dossier.DataSources.Generators.IGenerator Generator { get; } + protected abstract System.Collections.Generic.IList InitializeDataSource(); + public virtual T Next() { } + } + public interface IDataSource + { + System.Collections.Generic.IList Data { get; } + TestStack.Dossier.DataSources.Generators.IGenerator Generator { get; } + T Next(); + } +} +namespace TestStack.Dossier.DataSources.Dictionaries +{ + [System.ObsoleteAttribute("FileDictionarySource is deprecated, please use Words(FromDictionary) instead.")] + public abstract class FileDictionarySource : TestStack.Dossier.DataSources.DataSource + { + protected FileDictionarySource() { } + protected override System.Collections.Generic.IList InitializeDataSource() { } + } + public class FromDictionary + { + public const string AddressAusCity = "AddressAusCity"; + public const string AddressAusCompany = "AddressAusCompany"; + public const string AddressAusPhone = "AddressAusPhone"; + public const string AddressAusPostCode = "AddressAusPostCode"; + public const string AddressAusState = "AddressAusState"; + public const string AddressAusStateAbbreviation = "AddressAusStateAbbreviation"; + public const string AddressAusStreet = "AddressAusStreet"; + public const string AddressAusWebsite = "AddressAusWebsite"; + public const string AddressUkCity = "AddressUKCity"; + public const string AddressUkCompany = "AddressUKCompany"; + public const string AddressUkCounty = "AddressUKCounty"; + public const string AddressUkPhone = "AddressUKPhone"; + public const string AddressUkPostCode = "AddressUKPostCode"; + public const string AddressUkStreet = "AddressUKStreet"; + public const string AddressUkWebsite = "AddressUKWebsite"; + public const string AddressUsCity = "AddressUSCity"; + public const string AddressUsCompany = "AddressUSCompany"; + public const string AddressUsPhone = "AddressUSPhone"; + public const string AddressUsSocialSecurityNumber = "AddressUSSocialSecurityNumber"; + public const string AddressUsState = "AddressUSState"; + public const string AddressUsStateAbbreviation = "AddressUSStateAbbreviation"; + public const string AddressUsStreet = "AddressUSStreet"; + public const string AddressUsWebsite = "AddressUSWebsite"; + public const string AddressUsZipCode = "AddressUSZipCode"; + public const string ColourHex = "ColourHex"; + public const string ColourName = "ColourName"; + public const string CompanyIndustry = "CompanyIndustry"; + public const string CompanyJobTitle = "CompanyJobTitle"; + public const string CompanyLocation = "CompanyLocation"; + public const string CompanyName = "CompanyName"; + public const string FinanceCreditCardNumber = "FinanceCreditCardNumber"; + public const string FinanceCreditCardType = "FinanceCreditCardType"; + public const string FinanceCurrency = "FinanceCurrency"; + public const string FinanceCurrencyCode = "FinanceCurrencyCode"; + public const string Frequency = "Frequency"; + public const string GeoContinent = "GeoContinent"; + public const string GeoCountry = "GeoCountry"; + public const string GeoCountryCode = "GeoCountryCode"; + public const string GeoLatitude = "GeoLatitude"; + public const string GeoLongitude = "GeoLongitude"; + public const string IdentifierBitcoinAddress = "IdentifierBitcoinAddress"; + public const string IdentifierIban = "IdentifierIBAN"; + public const string IdentifierIpAddressV4 = "IdentifierIPAddressV4"; + public const string IdentifierIpAddressV6 = "IdentifierIPAddressV6"; + public const string IdentifierIsbn = "IdentifierISBN"; + public const string IdentifierMacAddress = "IdentifierMacAddress"; + public const string InternetDomainCountryCodeTopLevelDomain = "InternetDomainCountryCodeTopLevelDomain"; + public const string InternetDomainName = "InternetDomainName"; + public const string InternetDomainTopLevel = "InternetDomainTopLevel"; + public const string InternetUrl = "InternetURL"; + public const string LoremIpsum = "LoremIpsum"; + public const string PersonEmailAddress = "PersonEmailAddress"; + public const string PersonLanguage = "PersonLanguage"; + public const string PersonNameFirst = "PersonNameFirst"; + public const string PersonNameFirstFemale = "PersonNameFirstFemale"; + public const string PersonNameFirstMale = "PersonNameFirstMale"; + public const string PersonNameFull = "PersonNameFull"; + public const string PersonNameLast = "PersonNameLast"; + public const string PersonNameSuffix = "PersonNameSuffix"; + public const string PersonNameTitle = "PersonNameTitle"; + public const string PersonPassword = "PersonPassword"; + public const string PersonRace = "PersonRace"; + public const string PersonUsername = "PersonUsername"; + public const string ShirtSize = "ShirtSize"; + public FromDictionary() { } + } + public class Words : TestStack.Dossier.DataSources.DataSource + { + public Words(string dictionaryName) { } + protected override System.Collections.Generic.IList InitializeDataSource() { } + } +} +namespace TestStack.Dossier.DataSources.Generators +{ + public interface IGenerator + { + int ListSize { get; set; } + int StartIndex { get; set; } + int Generate(); + } + public class RandomGenerator : TestStack.Dossier.DataSources.Generators.IGenerator + { + public RandomGenerator() { } + public RandomGenerator(int startIndex, int listSize) { } + public int ListSize { get; set; } + public int StartIndex { get; set; } + public int Generate() { } + } + public class SequentialGenerator : TestStack.Dossier.DataSources.Generators.IGenerator + { + public SequentialGenerator() { } + public SequentialGenerator(int startIndex, int listSize, bool listShouldBeUnique = False) { } + public bool ListShouldBeUnique { get; } + public int ListSize { get; set; } + public int StartIndex { get; set; } + public int Generate() { } + } +} +namespace TestStack.Dossier.DataSources.Geography +{ + [System.ObsoleteAttribute("GeoContinentSource is deprecated, please use Words(FromDictionary.GeoContinent) i" + + "nstead.")] + public class GeoContinentSource : TestStack.Dossier.DataSources.Dictionaries.FileDictionarySource + { + public GeoContinentSource() { } + } + [System.ObsoleteAttribute("GeoCountryCodeSource is deprecated, please use Words(FromDictionary.GeoCountryCod" + + "e) instead.")] + public class GeoCountryCodeSource : TestStack.Dossier.DataSources.Dictionaries.FileDictionarySource + { + public GeoCountryCodeSource() { } + } + [System.ObsoleteAttribute("GeoCountrySource is deprecated, please use Words(FromDictionary.GeoCountry) inste" + + "ad.")] + public class GeoCountrySource : TestStack.Dossier.DataSources.Dictionaries.FileDictionarySource + { + public GeoCountrySource() { } + } + [System.ObsoleteAttribute("GeoLatitudeSource is deprecated, please use Words(FromDictionary.GeoLatitude) ins" + + "tead.")] + public class GeoLatitudeSource : TestStack.Dossier.DataSources.Dictionaries.FileDictionarySource + { + public GeoLatitudeSource() { } + } + [System.ObsoleteAttribute("GeoLongitudeSource is deprecated, please use Words(FromDictionary.GeoLongitude) i" + + "nstead.")] + public class GeoLongitudeSource : TestStack.Dossier.DataSources.Dictionaries.FileDictionarySource + { + public GeoLongitudeSource() { } + } +} +namespace TestStack.Dossier.DataSources.Person +{ + [System.ObsoleteAttribute("PersonEmailAddressSource is deprecated, please use Words(FromDictionary.PersonEma" + + "ilAddress) instead.")] + public class PersonEmailAddressSource : TestStack.Dossier.DataSources.Dictionaries.FileDictionarySource + { + public PersonEmailAddressSource() { } + public PersonEmailAddressSource(TestStack.Dossier.DataSources.Generators.IGenerator generator) { } + } + [System.ObsoleteAttribute("PersonLanguageSource is deprecated, please use Words(FromDictionary.PersonLanguag" + + "e) instead.")] + public class PersonLanguageSource : TestStack.Dossier.DataSources.Dictionaries.FileDictionarySource + { + public PersonLanguageSource() { } + } + [System.ObsoleteAttribute("PersonNameFirstFemaleSource is deprecated, please use Words(FromDictionary.Person" + + "NameFirstFemale) instead.")] + public class PersonNameFirstFemaleSource : TestStack.Dossier.DataSources.Dictionaries.FileDictionarySource + { + public PersonNameFirstFemaleSource() { } + } + [System.ObsoleteAttribute("PersonNameFirstMaleSource is deprecated, please use Words(FromDictionary.PersonNa" + + "meFirstMale) instead.")] + public class PersonNameFirstMaleSource : TestStack.Dossier.DataSources.Dictionaries.FileDictionarySource + { + public PersonNameFirstMaleSource() { } + } + [System.ObsoleteAttribute("PersonNameFirstSource is deprecated, please use Words(FromDictionary.PersonNameFi" + + "rst) instead.")] + public class PersonNameFirstSource : TestStack.Dossier.DataSources.Dictionaries.FileDictionarySource + { + public PersonNameFirstSource() { } + } + [System.ObsoleteAttribute("PersonNameFullSource is deprecated, please use Words(FromDictionary.PersonNameFul" + + "l) instead.")] + public class PersonNameFullSource : TestStack.Dossier.DataSources.Dictionaries.FileDictionarySource + { + public PersonNameFullSource() { } + } + [System.ObsoleteAttribute("PersonNameLastSource is deprecated, please use Words(FromDictionary.PersonNameLas" + + "t) instead.")] + public class PersonNameLastSource : TestStack.Dossier.DataSources.Dictionaries.FileDictionarySource + { + public PersonNameLastSource() { } + } + [System.ObsoleteAttribute("PersonNameSuffixSource is deprecated, please use Words(FromDictionary.PersonNameS" + + "uffix) instead.")] + public class PersonNameSuffixSource : TestStack.Dossier.DataSources.Dictionaries.FileDictionarySource + { + public PersonNameSuffixSource() { } + } + [System.ObsoleteAttribute("PersonNameTitleSource is deprecated, please use Words(FromDictionary.PersonNameTi" + + "tle) instead.")] + public class PersonNameTitleSource : TestStack.Dossier.DataSources.Dictionaries.FileDictionarySource + { + public PersonNameTitleSource() { } + } +} +namespace TestStack.Dossier.DataSources.Picking +{ + public class Pick + { + public Pick() { } + public static TestStack.Dossier.DataSources.Picking.RandomItemSource RandomItemFrom(System.Collections.Generic.IList list) { } + public static TestStack.Dossier.DataSources.Picking.RepeatingSequenceSource RepeatingSequenceFrom(System.Collections.Generic.IList list) { } + } + public class RandomItemSource : TestStack.Dossier.DataSources.DataSource + { + public RandomItemSource(System.Collections.Generic.IList list) { } + protected override System.Collections.Generic.IList InitializeDataSource() { } + } + public class RepeatingSequenceSource : TestStack.Dossier.DataSources.DataSource + { + public RepeatingSequenceSource(System.Collections.Generic.IList list) { } + protected override System.Collections.Generic.IList InitializeDataSource() { } + } +} +namespace TestStack.Dossier.EquivalenceClasses +{ + public class static EnumEquivalenceClasses + { + public static TEnum Except(this TestStack.Dossier.AnonymousValueFixture fixture, params TEnum[] except) + where TEnum : struct, System.IComparable, System.IFormattable, System.IConvertible { } + public static TEnum Of(this TestStack.Dossier.AnonymousValueFixture fixture) + where TEnum : struct, System.IComparable, System.IFormattable, System.IConvertible { } + } + public class static IntegerEquivalenceClasses + { + public static int IntegerExcept(this TestStack.Dossier.AnonymousValueFixture fixture, params int[] exceptFor) { } + public static int NegativeInteger(this TestStack.Dossier.AnonymousValueFixture fixture) { } + public static int PositiveInteger(this TestStack.Dossier.AnonymousValueFixture fixture) { } + } + public class static StringEquivalenceClasses + { + public static string String(this TestStack.Dossier.AnonymousValueFixture fixture) { } + public static string StringEndingWith(this TestStack.Dossier.AnonymousValueFixture fixture, string suffix) { } + public static string StringMatching(this TestStack.Dossier.AnonymousValueFixture fixture, string regexPattern) { } + public static string StringOfLength(this TestStack.Dossier.AnonymousValueFixture fixture, int length) { } + public static string StringStartingWith(this TestStack.Dossier.AnonymousValueFixture fixture, string prefix) { } + } +} +namespace TestStack.Dossier.EquivalenceClasses.Geo +{ + public class static GeographyEquivalenceClassescs + { + [System.ObsoleteAttribute("Continent is deprecated, please use Geography.Continent instead.")] + public static string Continent(this TestStack.Dossier.AnonymousValueFixture fixture) { } + [System.ObsoleteAttribute("Country is deprecated, please use Geography.Country instead.")] + public static string Country(this TestStack.Dossier.AnonymousValueFixture fixture) { } + [System.ObsoleteAttribute("CountryCode is deprecated, please use Geography.CountryCode instead.")] + public static string CountryCode(this TestStack.Dossier.AnonymousValueFixture fixture) { } + [System.ObsoleteAttribute("Latitude is deprecated, please use Geography.Latitude instead.")] + public static string Latitude(this TestStack.Dossier.AnonymousValueFixture fixture) { } + [System.ObsoleteAttribute("Longitude is deprecated, please use Geography.Longitude instead.")] + public static string Longitude(this TestStack.Dossier.AnonymousValueFixture fixture) { } + } +} +namespace TestStack.Dossier.EquivalenceClasses.Person +{ + public class static PersonEquivalenceClasses + { + [System.ObsoleteAttribute("EmailAddress is deprecated, please use Person.EmailAddress instead.")] + public static string EmailAddress(this TestStack.Dossier.AnonymousValueFixture fixture) { } + [System.ObsoleteAttribute("FemaleFirstName is deprecated, please use Person.NameFirstFemale instead.")] + public static string FemaleFirstName(this TestStack.Dossier.AnonymousValueFixture fixture) { } + [System.ObsoleteAttribute("FirstName is deprecated, please use Person.NameFirst instead.")] + public static string FirstName(this TestStack.Dossier.AnonymousValueFixture fixture) { } + [System.ObsoleteAttribute("FullName is deprecated, please use Person.NameFull instead.")] + public static string FullName(this TestStack.Dossier.AnonymousValueFixture fixture) { } + [System.ObsoleteAttribute("Language is deprecated, please use Person.Language instead.")] + public static string Language(this TestStack.Dossier.AnonymousValueFixture fixture) { } + [System.ObsoleteAttribute("LastName is deprecated, please use Person.NameLast instead.")] + public static string LastName(this TestStack.Dossier.AnonymousValueFixture fixture) { } + [System.ObsoleteAttribute("MaleFirstName is deprecated, please use Person.NameFirstMale instead.")] + public static string MaleFirstName(this TestStack.Dossier.AnonymousValueFixture fixture) { } + [System.ObsoleteAttribute("Suffix is deprecated, please use Person.NameSuffix instead.")] + public static string Suffix(this TestStack.Dossier.AnonymousValueFixture fixture) { } + [System.ObsoleteAttribute("Title is deprecated, please use Person.Title instead.")] + public static string Title(this TestStack.Dossier.AnonymousValueFixture fixture) { } + [System.ObsoleteAttribute("UniqueEmailAddress is deprecated, please use Person.UniqueEmailAddress instead.")] + public static string UniqueEmailAddress(this TestStack.Dossier.AnonymousValueFixture fixture) { } + } +} +namespace TestStack.Dossier.Factories +{ + public class AllPropertiesFactory : TestStack.Dossier.Factories.CallConstructorFactory + { + public AllPropertiesFactory() { } + public override TObject BuildObject(TestStack.Dossier.TestDataBuilder builder) + where TObject : class + where TBuilder : TestStack.Dossier.TestDataBuilder<, >, new () { } + } + public class AutoFixtureFactory : TestStack.Dossier.Factories.IFactory + { + public AutoFixtureFactory() { } + public TObject BuildObject(TestStack.Dossier.TestDataBuilder builder) + where TObject : class + where TBuilder : TestStack.Dossier.TestDataBuilder<, >, new () { } + } + public class CallConstructorFactory : TestStack.Dossier.Factories.IFactory + { + public CallConstructorFactory() { } + public virtual TObject BuildObject(TestStack.Dossier.TestDataBuilder builder) + where TObject : class + where TBuilder : TestStack.Dossier.TestDataBuilder<, >, new () { } + } + public interface IFactory + { + TObject BuildObject(TestStack.Dossier.TestDataBuilder builder) + where TObject : class + where TBuilder : TestStack.Dossier.TestDataBuilder<, >, new (); + } + public class PublicPropertySettersFactory : TestStack.Dossier.Factories.CallConstructorFactory + { + public PublicPropertySettersFactory() { } + public override TObject BuildObject(TestStack.Dossier.TestDataBuilder builder) + where TObject : class + where TBuilder : TestStack.Dossier.TestDataBuilder<, >, new () { } + } +} +namespace TestStack.Dossier.Lists +{ + public class ListBuilder + where TObject : class + where TBuilder : TestStack.Dossier.TestDataBuilder<, >, new () + { + public TBuilder All() { } + public System.Collections.Generic.IList BuildList() { } + public System.Collections.Generic.IEnumerable GetBuilders() { } + public static System.Collections.Generic.List op_Implicit(TestStack.Dossier.Lists.ListBuilder builder) { } + public TBuilder TheFirst(int howMany) { } + public TBuilder TheLast(int howMany) { } + public TBuilder TheNext(int howMany) { } + public TBuilder ThePrevious(int howMany) { } + public TestStack.Dossier.Lists.ListBuilder With(System.Func modifier) { } + } + public class static ListBuilderExtensions + { + public static TBuilder All(this TestStack.Dossier.TestDataBuilder builder) + where TObject : class + where TBuilder : TestStack.Dossier.TestDataBuilder<, >, new () { } + public static System.Collections.Generic.IList BuildList(this TestStack.Dossier.TestDataBuilder builder) + where TObject : class + where TBuilder : TestStack.Dossier.TestDataBuilder<, >, new () { } + public static TBuilder TheFirst(this TestStack.Dossier.TestDataBuilder builder, int howMany) + where TObject : class + where TBuilder : TestStack.Dossier.TestDataBuilder<, >, new () { } + public static TBuilder TheLast(this TestStack.Dossier.TestDataBuilder builder, int howMany) + where TObject : class + where TBuilder : TestStack.Dossier.TestDataBuilder<, >, new () { } + public static TBuilder TheNext(this TestStack.Dossier.TestDataBuilder builder, int howMany) + where TObject : class + where TBuilder : TestStack.Dossier.TestDataBuilder<, >, new () { } + public static TBuilder ThePrevious(this TestStack.Dossier.TestDataBuilder builder, int howMany) + where TObject : class + where TBuilder : TestStack.Dossier.TestDataBuilder<, >, new () { } + public static TestStack.Dossier.Lists.ListBuilder With(this TestStack.Dossier.TestDataBuilder builder, System.Func modifier) + where TObject : class + where TBuilder : TestStack.Dossier.TestDataBuilder<, >, new () { } + } +} +namespace TestStack.Dossier.Suppliers +{ + public class DefaultEmailValueSupplier : TestStack.Dossier.IAnonymousValueSupplier + { + public DefaultEmailValueSupplier() { } + public bool CanSupplyValue(System.Type type, string propertyName) { } + public object GenerateAnonymousValue(TestStack.Dossier.AnonymousValueFixture any, System.Type type, string propertyName) { } + } + public class DefaultFirstNameValueSupplier : TestStack.Dossier.IAnonymousValueSupplier + { + public DefaultFirstNameValueSupplier() { } + public bool CanSupplyValue(System.Type type, string propertyName) { } + public object GenerateAnonymousValue(TestStack.Dossier.AnonymousValueFixture any, System.Type type, string propertyName) { } + } + public class DefaultLastNameValueSupplier : TestStack.Dossier.IAnonymousValueSupplier + { + public DefaultLastNameValueSupplier() { } + public bool CanSupplyValue(System.Type type, string propertyName) { } + public object GenerateAnonymousValue(TestStack.Dossier.AnonymousValueFixture any, System.Type type, string propertyName) { } + } + public class DefaultStringValueSupplier : TestStack.Dossier.IAnonymousValueSupplier + { + public DefaultStringValueSupplier() { } + public bool CanSupplyValue(System.Type type, string propertyName) { } + public object GenerateAnonymousValue(TestStack.Dossier.AnonymousValueFixture any, System.Type type, string propertyName) { } + } + public class DefaultValueSupplier : TestStack.Dossier.IAnonymousValueSupplier + { + public DefaultValueSupplier() { } + public bool CanSupplyValue(System.Type type, string propertyName) { } + public object GenerateAnonymousValue(TestStack.Dossier.AnonymousValueFixture any, System.Type type, string propertyName) { } + } + public class DefaultValueTypeValueSupplier : TestStack.Dossier.IAnonymousValueSupplier + { + public DefaultValueTypeValueSupplier() { } + public bool CanSupplyValue(System.Type type, string propertyName) { } + public object GenerateAnonymousValue(TestStack.Dossier.AnonymousValueFixture any, System.Type type, string propertyName) { } + } +} \ No newline at end of file diff --git a/TestStack.Dossier.Tests/PublicApiApproval/PublicApiApproverTests.cs b/TestStack.Dossier.Tests/PublicApiApproval/PublicApiApproverTests.cs new file mode 100644 index 0000000..fd38952 --- /dev/null +++ b/TestStack.Dossier.Tests/PublicApiApproval/PublicApiApproverTests.cs @@ -0,0 +1,17 @@ +using Shouldly; +using Xunit; + +namespace TestStack.Dossier.Tests.PublicApiApproval +{ + public class PublicApiApproverTests + { + [Fact] + public void GivenDossierAssembly_WhenPublicApiChecked_ShouldHaveNoChanges() + { + ShouldlyConfiguration.DiffTools.KnownDoNotLaunchStrategies.TeamCity.ShouldNotLaunch(); + var dossierAssembly = typeof(AnonymousValueFixture).Assembly; + var publicApi = PublicApiGenerator.ApiGenerator.GeneratePublicApi(dossierAssembly, shouldIncludeAssemblyAttributes: false); + publicApi.ShouldMatchApproved(); + } + } +} diff --git a/TestStack.Dossier.Tests/Stubs/ViewModels/Grade.cs b/TestStack.Dossier.Tests/Stubs/ViewModels/Grade.cs deleted file mode 100644 index 8598bb2..0000000 --- a/TestStack.Dossier.Tests/Stubs/ViewModels/Grade.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace TestStack.Dossier.Tests.Stubs.ViewModels -{ - public enum Grade - { - A, B, C, D, F - } -} \ No newline at end of file diff --git a/TestStack.Dossier.Tests/Stubs/ViewModels/InstructorViewModel.cs b/TestStack.Dossier.Tests/Stubs/ViewModels/InstructorViewModel.cs deleted file mode 100644 index b0db3e9..0000000 --- a/TestStack.Dossier.Tests/Stubs/ViewModels/InstructorViewModel.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; - -namespace TestStack.Dossier.Tests.Stubs.ViewModels -{ - public class InstructorViewModel - { - public InstructorViewModel(Guid id, string firstName, string lastName) - { - Id = id; - FirstName = firstName; - LastName = lastName; - } - - public Guid Id { get; private set; } - - public string LastName { get; set; } - public string FirstName { get; private set; } - - public string FullName - { - get - { - return FirstName + " " + LastName; - } - } - public string Room{ get; set; } - - public string Subject{ get; private set; } - public int YearsAtSchool { get; private set; } - public int NumberOfStudents { get; set; } - } -} diff --git a/TestStack.Dossier.Tests/TestHelpers/Builders/AddressViewModelBuilder.cs b/TestStack.Dossier.Tests/TestHelpers/Builders/AddressViewModelBuilder.cs new file mode 100644 index 0000000..512b120 --- /dev/null +++ b/TestStack.Dossier.Tests/TestHelpers/Builders/AddressViewModelBuilder.cs @@ -0,0 +1,18 @@ +using TestStack.Dossier.Factories; +using TestStack.Dossier.Tests.TestHelpers.Objects.ViewModels; + +namespace TestStack.Dossier.Tests.TestHelpers.Builders +{ + public class AddressViewModelBuilder : TestDataBuilder + { + public virtual AddressViewModelBuilder WithStreet(string street) + { + return Set(x => x.Street, street); + } + + protected override AddressViewModel BuildObject() + { + return BuildUsing(); + } + } +} diff --git a/TestStack.Dossier.Tests/Builders/AutoConstructorCustomerBuilder.cs b/TestStack.Dossier.Tests/TestHelpers/Builders/AutoConstructorCustomerBuilder.cs similarity index 79% rename from TestStack.Dossier.Tests/Builders/AutoConstructorCustomerBuilder.cs rename to TestStack.Dossier.Tests/TestHelpers/Builders/AutoConstructorCustomerBuilder.cs index 15d37ba..b413c49 100644 --- a/TestStack.Dossier.Tests/Builders/AutoConstructorCustomerBuilder.cs +++ b/TestStack.Dossier.Tests/TestHelpers/Builders/AutoConstructorCustomerBuilder.cs @@ -1,7 +1,7 @@ using TestStack.Dossier.Factories; -using TestStack.Dossier.Tests.Stubs.Entities; +using TestStack.Dossier.Tests.TestHelpers.Objects.Entities; -namespace TestStack.Dossier.Tests.Builders +namespace TestStack.Dossier.Tests.TestHelpers.Builders { class AutoConstructorCustomerBuilder : TestDataBuilder { @@ -22,7 +22,7 @@ public AutoConstructorCustomerBuilder WhoJoinedIn(int year) protected override Customer BuildObject() { - return BuildUsing(); + return BuildUsing(); } } } diff --git a/TestStack.Dossier.Tests/TestHelpers/Builders/BasicCustomerBuilder.cs b/TestStack.Dossier.Tests/TestHelpers/Builders/BasicCustomerBuilder.cs new file mode 100644 index 0000000..fc9952d --- /dev/null +++ b/TestStack.Dossier.Tests/TestHelpers/Builders/BasicCustomerBuilder.cs @@ -0,0 +1,12 @@ +using TestStack.Dossier.Tests.TestHelpers.Objects.Entities; + +namespace TestStack.Dossier.Tests.TestHelpers.Builders +{ + public class BasicCustomerBuilder : TestDataBuilder + { + protected override Customer BuildObject() + { + return new Customer("customer1", "First Name", "Last Name", 2013, new Address("AddressIdentifier", 5, "Street Name", "Suburb", "City", "PostCode"), CustomerClass.Normal); + } + } +} diff --git a/TestStack.Dossier.Tests/TestHelpers/Builders/BuilderWithDefaults.cs b/TestStack.Dossier.Tests/TestHelpers/Builders/BuilderWithDefaults.cs new file mode 100644 index 0000000..32f9bec --- /dev/null +++ b/TestStack.Dossier.Tests/TestHelpers/Builders/BuilderWithDefaults.cs @@ -0,0 +1,16 @@ +using TestStack.Dossier.Tests.TestHelpers.Objects.Entities; + +namespace TestStack.Dossier.Tests.TestHelpers.Builders +{ + public class BuilderWithDefaults : TestDataBuilder + { + public const string DefaultFirstName = "Joe"; + public const string DefaultLastName = "Bloggs"; + + public BuilderWithDefaults() + { + Set(x => x.FirstName, DefaultFirstName); + Set(x => x.LastName, DefaultLastName); + } + } +} diff --git a/TestStack.Dossier.Tests/Builders/CustomerBuilder.cs b/TestStack.Dossier.Tests/TestHelpers/Builders/CustomerBuilder.cs similarity index 55% rename from TestStack.Dossier.Tests/Builders/CustomerBuilder.cs rename to TestStack.Dossier.Tests/TestHelpers/Builders/CustomerBuilder.cs index 319a57c..17efdae 100644 --- a/TestStack.Dossier.Tests/Builders/CustomerBuilder.cs +++ b/TestStack.Dossier.Tests/TestHelpers/Builders/CustomerBuilder.cs @@ -1,6 +1,6 @@ -using TestStack.Dossier.Tests.Stubs.Entities; +using TestStack.Dossier.Tests.TestHelpers.Objects.Entities; -namespace TestStack.Dossier.Tests.Builders +namespace TestStack.Dossier.Tests.TestHelpers.Builders { public class CustomerBuilder : TestDataBuilder { @@ -19,6 +19,11 @@ public virtual CustomerBuilder WhoJoinedIn(int yearJoined) return Set(x => x.YearJoined, yearJoined); } + public virtual CustomerBuilder WithPostalAdressIdentifier(string identifier) + { + return Set(x => x.PostalAddress.Identifier, identifier); + } + protected override Customer BuildObject() { return new Customer( @@ -26,6 +31,14 @@ protected override Customer BuildObject() Get(x => x.FirstName), Get(x => x.LastName), Get(x => x.YearJoined), + new Address( + Get(x => x.PostalAddress.Identifier), + Get(x => x.PostalAddress.StreetNo), + Get(x => x.PostalAddress.StreetName), + Get(x => x.PostalAddress.Suburb), + Get(x => x.PostalAddress.City), + Get(x => x.PostalAddress.PostCode) + ), Get(x => x.CustomerClass) ); } diff --git a/TestStack.Dossier.Tests/Builders/ProxyAlteringCustomerBuilder.cs b/TestStack.Dossier.Tests/TestHelpers/Builders/ProxyAlteringCustomerBuilder.cs similarity index 84% rename from TestStack.Dossier.Tests/Builders/ProxyAlteringCustomerBuilder.cs rename to TestStack.Dossier.Tests/TestHelpers/Builders/ProxyAlteringCustomerBuilder.cs index 2419fdf..97a156e 100644 --- a/TestStack.Dossier.Tests/Builders/ProxyAlteringCustomerBuilder.cs +++ b/TestStack.Dossier.Tests/TestHelpers/Builders/ProxyAlteringCustomerBuilder.cs @@ -1,8 +1,8 @@ using System; using NSubstitute; -using TestStack.Dossier.Tests.Stubs.Entities; +using TestStack.Dossier.Tests.TestHelpers.Objects.Entities; -namespace TestStack.Dossier.Tests.Builders +namespace TestStack.Dossier.Tests.TestHelpers.Builders { class ProxyAlteringCustomerBuilder : TestDataBuilder { diff --git a/TestStack.Dossier.Tests/TestHelpers/Objects/Entities/Address.cs b/TestStack.Dossier.Tests/TestHelpers/Objects/Entities/Address.cs new file mode 100644 index 0000000..01dfc5b --- /dev/null +++ b/TestStack.Dossier.Tests/TestHelpers/Objects/Entities/Address.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TestStack.Dossier.Tests.TestHelpers.Objects.Entities +{ + public class Address + { + protected Address() { } + + public Address(string identifier, int streetNo, string streetName, string suburb, string city, string postCode) + { + Identifier = identifier; + StreetNo = streetNo; + StreetName = streetName; + Suburb = suburb; + City = city; + PostCode = postCode; + } + + public string Identifier { get; private set; } + public virtual int StreetNo { get; private set; } + public string StreetName { get; private set; } + public string Suburb { get; private set; } + public string City { get; private set; } + public string PostCode { get; private set; } + } +} diff --git a/TestStack.Dossier.Tests/Stubs/Entities/Company.cs b/TestStack.Dossier.Tests/TestHelpers/Objects/Entities/Company.cs similarity index 83% rename from TestStack.Dossier.Tests/Stubs/Entities/Company.cs rename to TestStack.Dossier.Tests/TestHelpers/Objects/Entities/Company.cs index 2635100..df96a43 100644 --- a/TestStack.Dossier.Tests/Stubs/Entities/Company.cs +++ b/TestStack.Dossier.Tests/TestHelpers/Objects/Entities/Company.cs @@ -1,4 +1,4 @@ -namespace TestStack.Dossier.Tests.Stubs.Entities +namespace TestStack.Dossier.Tests.TestHelpers.Objects.Entities { public class Company { diff --git a/TestStack.Dossier.Tests/Stubs/Entities/Customer.cs b/TestStack.Dossier.Tests/TestHelpers/Objects/Entities/Customer.cs similarity index 83% rename from TestStack.Dossier.Tests/Stubs/Entities/Customer.cs rename to TestStack.Dossier.Tests/TestHelpers/Objects/Entities/Customer.cs index 0e71270..5202e8c 100644 --- a/TestStack.Dossier.Tests/Stubs/Entities/Customer.cs +++ b/TestStack.Dossier.Tests/TestHelpers/Objects/Entities/Customer.cs @@ -1,12 +1,12 @@ using System; -namespace TestStack.Dossier.Tests.Stubs.Entities +namespace TestStack.Dossier.Tests.TestHelpers.Objects.Entities { public class Customer { protected Customer() {} - public Customer(string identifier, string firstName, string lastName, int yearJoined, CustomerClass customerClass) + public Customer(string identifier, string firstName, string lastName, int yearJoined, Address postalAddress, CustomerClass customerClass) { if (string.IsNullOrEmpty(identifier)) throw new ArgumentNullException("identifier"); @@ -19,6 +19,7 @@ public Customer(string identifier, string firstName, string lastName, int yearJo FirstName = firstName; LastName = lastName; YearJoined = yearJoined; + PostalAddress = postalAddress; CustomerClass = customerClass; } @@ -33,6 +34,7 @@ public virtual int CustomerForHowManyYears(DateTime since) public virtual string FirstName { get; private set; } public virtual string LastName { get; private set; } public virtual int YearJoined { get; private set; } + public virtual Address PostalAddress { get; private set; } public virtual CustomerClass CustomerClass { get; private set; } } } diff --git a/TestStack.Dossier.Tests/Stubs/Entities/CustomerClass.cs b/TestStack.Dossier.Tests/TestHelpers/Objects/Entities/CustomerClass.cs similarity index 65% rename from TestStack.Dossier.Tests/Stubs/Entities/CustomerClass.cs rename to TestStack.Dossier.Tests/TestHelpers/Objects/Entities/CustomerClass.cs index dd79d7b..aa3a080 100644 --- a/TestStack.Dossier.Tests/Stubs/Entities/CustomerClass.cs +++ b/TestStack.Dossier.Tests/TestHelpers/Objects/Entities/CustomerClass.cs @@ -1,4 +1,4 @@ -namespace TestStack.Dossier.Tests.Stubs.Entities +namespace TestStack.Dossier.Tests.TestHelpers.Objects.Entities { public enum CustomerClass { diff --git a/TestStack.Dossier.Tests/TestHelpers/Objects/Examples/MixedAccessibilityDto.cs b/TestStack.Dossier.Tests/TestHelpers/Objects/Examples/MixedAccessibilityDto.cs new file mode 100644 index 0000000..99cb17a --- /dev/null +++ b/TestStack.Dossier.Tests/TestHelpers/Objects/Examples/MixedAccessibilityDto.cs @@ -0,0 +1,26 @@ +namespace TestStack.Dossier.Tests.TestHelpers.Objects.Examples +{ + public class MixedAccessibilityDto + { + private readonly string _setByCtorNoPropertySetter; + + public MixedAccessibilityDto(string setByCtorWithPrivateSetter, string setByCtorWithPublicSetter, string setByCtorNoPropertySetter) + { + SetByCtorWithPrivateSetter = setByCtorWithPrivateSetter; + SetByCtorWithPublicSetter = setByCtorWithPublicSetter; + _setByCtorNoPropertySetter = setByCtorNoPropertySetter; + } + + public string SetByCtorWithPrivateSetter { get; private set; } + public string SetByCtorWithPublicSetter { get; set; } + + // ReSharper disable once UnusedAutoPropertyAccessor.Local + public string NotSetByCtorWithPrivateSetter { get; private set; } + public string NotSetByCtorWithPublicSetter { get; set; } + + public string SetByCtorNoPropertySetter + { + get { return _setByCtorNoPropertySetter; } + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier.Tests/TestHelpers/Objects/ViewModels/AddressViewModel.cs b/TestStack.Dossier.Tests/TestHelpers/Objects/ViewModels/AddressViewModel.cs new file mode 100644 index 0000000..7a24c75 --- /dev/null +++ b/TestStack.Dossier.Tests/TestHelpers/Objects/ViewModels/AddressViewModel.cs @@ -0,0 +1,8 @@ +namespace TestStack.Dossier.Tests.TestHelpers.Objects.ViewModels +{ + public class AddressViewModel + { + public string Street { get; set; } + public string Suburb { get; set; } + } +} \ No newline at end of file diff --git a/TestStack.Dossier.Tests/TestHelpers/Objects/ViewModels/Grade.cs b/TestStack.Dossier.Tests/TestHelpers/Objects/ViewModels/Grade.cs new file mode 100644 index 0000000..2594136 --- /dev/null +++ b/TestStack.Dossier.Tests/TestHelpers/Objects/ViewModels/Grade.cs @@ -0,0 +1,7 @@ +namespace TestStack.Dossier.Tests.TestHelpers.Objects.ViewModels +{ + public enum Grade + { + A, B, C, D, F + } +} \ No newline at end of file diff --git a/TestStack.Dossier.Tests/Stubs/ViewModels/StudentViewModel.cs b/TestStack.Dossier.Tests/TestHelpers/Objects/ViewModels/StudentViewModel.cs similarity index 88% rename from TestStack.Dossier.Tests/Stubs/ViewModels/StudentViewModel.cs rename to TestStack.Dossier.Tests/TestHelpers/Objects/ViewModels/StudentViewModel.cs index 674a844..63e6017 100644 --- a/TestStack.Dossier.Tests/Stubs/ViewModels/StudentViewModel.cs +++ b/TestStack.Dossier.Tests/TestHelpers/Objects/ViewModels/StudentViewModel.cs @@ -1,7 +1,7 @@ using System; using System.ComponentModel.DataAnnotations; -namespace TestStack.Dossier.Tests.Stubs.ViewModels +namespace TestStack.Dossier.Tests.TestHelpers.Objects.ViewModels { public class StudentViewModel { @@ -31,5 +31,7 @@ public string FullName public DateTime EnrollmentDate { get; set; } public Grade Grade { get; set; } + + public AddressViewModel Address { get; set; } } } diff --git a/TestStack.Dossier.Tests/TestStack.Dossier.Tests.csproj b/TestStack.Dossier.Tests/TestStack.Dossier.Tests.csproj index ac4666b..a1a527f 100644 --- a/TestStack.Dossier.Tests/TestStack.Dossier.Tests.csproj +++ b/TestStack.Dossier.Tests/TestStack.Dossier.Tests.csproj @@ -1,123 +1,36 @@ - - - + + - Debug - AnyCPU - {DC49CE57-CB3F-487D-83DC-6A4E78CB908C} - Library - Properties - TestStack.Dossier.Tests - TestStack.Dossier.Tests - v4.5.1 - 512 - ..\ - - 660882d1 + netcoreapp2.0;net472 - - true + + full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false + true + - - False - ..\packages\NSubstitute.1.8.1.0\lib\net45\NSubstitute.dll - - - False - ..\packages\Shouldly.2.4.0\lib\net40\Shouldly.dll - - - - - - - ..\packages\xunit.1.9.2\lib\net20\xunit.dll - - - ..\packages\xunit.extensions.1.9.2\lib\net20\xunit.extensions.dll - + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Designer - + + - + PreserveNewest - - - - - - - - {01e4ee61-ab1a-4177-8b6c-d50205d167a9} - TestStack.Dossier - + - - + \ No newline at end of file diff --git a/TestStack.Dossier.Tests/packages.config b/TestStack.Dossier.Tests/packages.config deleted file mode 100644 index 47316f3..0000000 --- a/TestStack.Dossier.Tests/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/TestStack.Dossier.sln b/TestStack.Dossier.sln index e535bbe..ea72a89 100644 --- a/TestStack.Dossier.sln +++ b/TestStack.Dossier.sln @@ -1,19 +1,22 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.31101.0 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.13 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BC8508D1-6FCB-46B2-9C14-F41F6AD76B09}" ProjectSection(SolutionItems) = preProject + appveyor.yml = appveyor.yml BREAKING_CHANGES.md = BREAKING_CHANGES.md + CONTRIBUTING.md = CONTRIBUTING.md + GitVersionConfig.yaml = GitVersionConfig.yaml LICENSE = LICENSE logo.png = logo.png README.md = README.md EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestStack.Dossier.Tests", "TestStack.Dossier.Tests\TestStack.Dossier.Tests.csproj", "{DC49CE57-CB3F-487D-83DC-6A4E78CB908C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestStack.Dossier", "TestStack.Dossier\TestStack.Dossier.csproj", "{768AF10B-5E0C-46BB-B6CD-B202AF39A0EF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestStack.Dossier", "TestStack.Dossier\TestStack.Dossier.csproj", "{01E4EE61-AB1A-4177-8B6C-D50205D167A9}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestStack.Dossier.Tests", "TestStack.Dossier.Tests\TestStack.Dossier.Tests.csproj", "{5B38B893-1018-4F0D-9999-4DA1385EB94A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -21,16 +24,19 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {DC49CE57-CB3F-487D-83DC-6A4E78CB908C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DC49CE57-CB3F-487D-83DC-6A4E78CB908C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DC49CE57-CB3F-487D-83DC-6A4E78CB908C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DC49CE57-CB3F-487D-83DC-6A4E78CB908C}.Release|Any CPU.Build.0 = Release|Any CPU - {01E4EE61-AB1A-4177-8B6C-D50205D167A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {01E4EE61-AB1A-4177-8B6C-D50205D167A9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {01E4EE61-AB1A-4177-8B6C-D50205D167A9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {01E4EE61-AB1A-4177-8B6C-D50205D167A9}.Release|Any CPU.Build.0 = Release|Any CPU + {768AF10B-5E0C-46BB-B6CD-B202AF39A0EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {768AF10B-5E0C-46BB-B6CD-B202AF39A0EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {768AF10B-5E0C-46BB-B6CD-B202AF39A0EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {768AF10B-5E0C-46BB-B6CD-B202AF39A0EF}.Release|Any CPU.Build.0 = Release|Any CPU + {5B38B893-1018-4F0D-9999-4DA1385EB94A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5B38B893-1018-4F0D-9999-4DA1385EB94A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5B38B893-1018-4F0D-9999-4DA1385EB94A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5B38B893-1018-4F0D-9999-4DA1385EB94A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B1C35ECA-9807-42D4-935A-186845AF20A3} + EndGlobalSection EndGlobal diff --git a/TestStack.Dossier/AnonymousValueFixture.cs b/TestStack.Dossier/AnonymousValueFixture.cs index 1b9eff1..0e641ae 100644 --- a/TestStack.Dossier/AnonymousValueFixture.cs +++ b/TestStack.Dossier/AnonymousValueFixture.cs @@ -2,7 +2,8 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; -using Ploeh.AutoFixture; +using AutoFixture; +using TestStack.Dossier.DataSources.Dictionaries; using TestStack.Dossier.Suppliers; namespace TestStack.Dossier @@ -11,7 +12,7 @@ namespace TestStack.Dossier /// Allows you to create extension methods to generate anonymous values and to set up /// conventions for automatic generation of anonymous values based on property expressions. /// - public class AnonymousValueFixture + public partial class AnonymousValueFixture { static AnonymousValueFixture() { @@ -88,7 +89,7 @@ public T Get(Expression> property) .Concat(DefaultValueSuppliers) .First(s => s.CanSupplyValue(typeof(T), propertyName)); - return valueSupplier.GenerateAnonymousValue(this, propertyName); + return (T) valueSupplier.GenerateAnonymousValue(this, typeof(T), propertyName); } /// @@ -102,9 +103,21 @@ public object Get(Type type, string propertyName) var valueSupplier = LocalValueSuppliers .Concat(GlobalValueSuppliers) .Concat(DefaultValueSuppliers) - .First(s => s.CanSupplyValue(type,propertyName)); + .First(s => s.CanSupplyValue(type, propertyName)); return valueSupplier.GenerateAnonymousValue(this, type, propertyName); } + + /// + /// Gets a data source for a file dictionary, which can be built-in or a user-supplied text file. + /// + /// The name of the file dictionary, without the extension. + /// Recommended to use the FromDictionary list of constants for the built-in file dictionaries. + /// Just use a normal string for user-supplied text files. + /// + public Words Words(string dictionaryName) + { + return WordsCache.Get(dictionaryName); + } } } diff --git a/TestStack.Dossier/AssemblyInfo.cs b/TestStack.Dossier/AssemblyInfo.cs new file mode 100644 index 0000000..66feadf --- /dev/null +++ b/TestStack.Dossier/AssemblyInfo.cs @@ -0,0 +1,6 @@ +using System.Runtime.CompilerServices; + +// Handling InternalsVisibleTo in new .csproj +// https://stackoverflow.com/questions/42810705/visual-studio-2017-new-csproj-internalsvisibleto +[assembly: InternalsVisibleTo("TestStack.Dossier.Tests")] +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] \ No newline at end of file diff --git a/TestStack.Dossier/Builder.cs b/TestStack.Dossier/Builder.cs index 6e46826..d201946 100644 --- a/TestStack.Dossier/Builder.cs +++ b/TestStack.Dossier/Builder.cs @@ -1,12 +1,13 @@ -using Ploeh.AutoFixture.Kernel; +using System; +using System.Linq.Expressions; using TestStack.Dossier.Factories; using TestStack.Dossier.Lists; namespace TestStack.Dossier { /// - /// A generic Test Data Builder implementation for building objects on the fly. - /// By default + /// A generic Test Data Builder implementation for building objects on the fly + /// without needing to create a custom builder. /// /// The type of object this class generates. public class Builder : TestDataBuilder> @@ -63,5 +64,37 @@ protected override T BuildObject() { return Factory.BuildObject(this); } + + /// + /// Set a property value using a custom builder. + /// + /// The type of the property being set + /// The type of the custom builder to build the property value using + /// The property to set + /// An optional modifier to customise the builder + /// The builder so that other method calls can be chained + public virtual Builder SetUsingBuilder( + Expression> property, + Func modifier = null) + where TPropertyType : class + where TPropertyBuilder : TestDataBuilder, new() + { + return Set(property, GetChildBuilder(modifier)); + } + + /// + /// Set a property value using a . + /// + /// The type of the property being set + /// The property to set + /// An optional modifier to customise the builder + /// The builder so that other method calls can be chained + public virtual Builder SetUsingBuilder( + Expression> property, + Func, Builder> modifier = null) + where TPropertyType : class + { + return Set(property, GetChildBuilder>(modifier)); + } } } diff --git a/TestStack.Dossier/DataSources/DataSource.cs b/TestStack.Dossier/DataSources/DataSource.cs index ffecf7c..3a52770 100644 --- a/TestStack.Dossier/DataSources/DataSource.cs +++ b/TestStack.Dossier/DataSources/DataSource.cs @@ -40,6 +40,7 @@ public IList Data } return _list; } + internal set { _list = value; } } /// diff --git a/TestStack.Dossier/DataSources/Dictionaries/Cache.cs b/TestStack.Dossier/DataSources/Dictionaries/Cache.cs deleted file mode 100644 index 1fd98b4..0000000 --- a/TestStack.Dossier/DataSources/Dictionaries/Cache.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Collections.Concurrent; -using System.Collections.Generic; - -namespace TestStack.Dossier.DataSources.Dictionaries -{ - internal static class Cache - { - private static ConcurrentDictionary> _cache = new ConcurrentDictionary>(); - - internal static IList Get(string dictionary) - { - return _cache.ContainsKey(dictionary) ? _cache[dictionary] : null; - } - - internal static void Set(string key, IList items) - { - _cache[key] = items; - } - - public static bool Contains(string key) - { - return _cache.ContainsKey(key); - } - - public static void Clear() - { - _cache = new ConcurrentDictionary>(); - } - } -} diff --git a/TestStack.Dossier/DataSources/Dictionaries/CachedFileDictionaryRepository.cs b/TestStack.Dossier/DataSources/Dictionaries/CachedFileDictionaryRepository.cs index 1743bfa..2bf84bd 100644 --- a/TestStack.Dossier/DataSources/Dictionaries/CachedFileDictionaryRepository.cs +++ b/TestStack.Dossier/DataSources/Dictionaries/CachedFileDictionaryRepository.cs @@ -12,11 +12,6 @@ internal class CachedFileDictionaryRepository : IDictionaryRepository { public IList GetWordsFrom(string dictionary) { - if (Cache.Contains(dictionary)) - { - return Cache.Get(dictionary); - } - var words = new List(); var name = string.Format("{0}.txt", dictionary); @@ -27,10 +22,9 @@ public IList GetWordsFrom(string dictionary) else { var resourceName = string.Format("TestStack.Dossier.DataSources.Dictionaries.Resources.{0}", name); - words = GetWordsFromEmbeddedResource(GetType().Assembly, resourceName).ToList(); + words = GetWordsFromEmbeddedResource(GetType().GetTypeInfo().Assembly, resourceName).ToList(); } - Cache.Set(dictionary, words); return words; } diff --git a/TestStack.Dossier/DataSources/Dictionaries/FileDictionarySource.cs b/TestStack.Dossier/DataSources/Dictionaries/FileDictionarySource.cs index e931f9f..cb3983b 100644 --- a/TestStack.Dossier/DataSources/Dictionaries/FileDictionarySource.cs +++ b/TestStack.Dossier/DataSources/Dictionaries/FileDictionarySource.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using TestStack.Dossier.DataSources.Generators; namespace TestStack.Dossier.DataSources.Dictionaries @@ -6,13 +7,15 @@ namespace TestStack.Dossier.DataSources.Dictionaries /// /// The base class for data sources that load their data from dictionaries stored in files /// + [Obsolete("FileDictionarySource is deprecated, please use Words(FromDictionary) instead.")] public abstract class FileDictionarySource : DataSource { private readonly IDictionaryRepository _repository; /// protected FileDictionarySource() - : this(new RandomGenerator(), new CachedFileDictionaryRepository()) { } + : this(new RandomGenerator(), new CachedFileDictionaryRepository()) + { } /// internal FileDictionarySource(IGenerator generator, IDictionaryRepository repository) diff --git a/TestStack.Dossier/DataSources/Dictionaries/FromDictionary.cs b/TestStack.Dossier/DataSources/Dictionaries/FromDictionary.cs new file mode 100644 index 0000000..ac4d958 --- /dev/null +++ b/TestStack.Dossier/DataSources/Dictionaries/FromDictionary.cs @@ -0,0 +1,75 @@ +#pragma warning disable 1591 +namespace TestStack.Dossier.DataSources.Dictionaries +{ + /// + /// Provides strongly-typed access to all of the built-in file dictionary names. + /// + public class FromDictionary + { + public const string AddressAusCity = "AddressAusCity"; + public const string AddressAusCompany = "AddressAusCompany"; + public const string AddressAusPhone = "AddressAusPhone"; + public const string AddressAusPostCode = "AddressAusPostCode"; + public const string AddressAusState = "AddressAusState"; + public const string AddressAusStateAbbreviation = "AddressAusStateAbbreviation"; + public const string AddressAusStreet = "AddressAusStreet"; + public const string AddressAusWebsite = "AddressAusWebsite"; + public const string AddressUkCity = "AddressUKCity"; + public const string AddressUkCompany = "AddressUKCompany"; + public const string AddressUkCounty = "AddressUKCounty"; + public const string AddressUkPhone = "AddressUKPhone"; + public const string AddressUkPostCode = "AddressUKPostCode"; + public const string AddressUkStreet = "AddressUKStreet"; + public const string AddressUkWebsite = "AddressUKWebsite"; + public const string AddressUsCity = "AddressUSCity"; + public const string AddressUsCompany = "AddressUSCompany"; + public const string AddressUsPhone = "AddressUSPhone"; + public const string AddressUsSocialSecurityNumber = "AddressUSSocialSecurityNumber"; + public const string AddressUsState = "AddressUSState"; + public const string AddressUsStateAbbreviation = "AddressUSStateAbbreviation"; + public const string AddressUsStreet = "AddressUSStreet"; + public const string AddressUsWebsite = "AddressUSWebsite"; + public const string AddressUsZipCode = "AddressUSZipCode"; + public const string ColourHex = "ColourHex"; + public const string ColourName = "ColourName"; + public const string CompanyIndustry = "CompanyIndustry"; + public const string CompanyJobTitle = "CompanyJobTitle"; + public const string CompanyLocation = "CompanyLocation"; + public const string CompanyName = "CompanyName"; + public const string FinanceCreditCardNumber = "FinanceCreditCardNumber"; + public const string FinanceCreditCardType = "FinanceCreditCardType"; + public const string FinanceCurrency = "FinanceCurrency"; + public const string FinanceCurrencyCode = "FinanceCurrencyCode"; + public const string Frequency = "Frequency"; + public const string GeoContinent = "GeoContinent"; + public const string GeoCountry = "GeoCountry"; + public const string GeoCountryCode = "GeoCountryCode"; + public const string GeoLatitude = "GeoLatitude"; + public const string GeoLongitude = "GeoLongitude"; + public const string IdentifierBitcoinAddress = "IdentifierBitcoinAddress"; + public const string IdentifierIban = "IdentifierIBAN"; + public const string IdentifierIpAddressV4 = "IdentifierIPAddressV4"; + public const string IdentifierIpAddressV6 = "IdentifierIPAddressV6"; + public const string IdentifierIsbn = "IdentifierISBN"; + public const string IdentifierMacAddress = "IdentifierMacAddress"; + public const string InternetDomainCountryCodeTopLevelDomain = "InternetDomainCountryCodeTopLevelDomain"; + public const string InternetDomainName = "InternetDomainName"; + public const string InternetDomainTopLevel = "InternetDomainTopLevel"; + public const string InternetUrl = "InternetURL"; + public const string LoremIpsum = "LoremIpsum"; + public const string PersonEmailAddress = "PersonEmailAddress"; + public const string PersonLanguage = "PersonLanguage"; + public const string PersonNameFirst = "PersonNameFirst"; + public const string PersonNameFirstFemale = "PersonNameFirstFemale"; + public const string PersonNameFirstMale = "PersonNameFirstMale"; + public const string PersonNameFull = "PersonNameFull"; + public const string PersonNameLast = "PersonNameLast"; + public const string PersonNameSuffix = "PersonNameSuffix"; + public const string PersonNameTitle = "PersonNameTitle"; + public const string PersonPassword = "PersonPassword"; + public const string PersonRace = "PersonRace"; + public const string PersonUsername = "PersonUsername"; + public const string ShirtSize = "ShirtSize"; + } +} +#pragma warning restore 1591 \ No newline at end of file diff --git a/TestStack.Dossier/DataSources/Dictionaries/Words.cs b/TestStack.Dossier/DataSources/Dictionaries/Words.cs new file mode 100644 index 0000000..f15705b --- /dev/null +++ b/TestStack.Dossier/DataSources/Dictionaries/Words.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using TestStack.Dossier.DataSources.Generators; + +namespace TestStack.Dossier.DataSources.Dictionaries +{ + /// + /// The wrapper class for data sources that load words from dictionaries stored in files + /// + public class Words : DataSource + { + private readonly string _dictionaryName; + private readonly IDictionaryRepository _repository; + + /// + public Words(string dictionaryName) + : this(new RandomGenerator(), new CachedFileDictionaryRepository(), dictionaryName) + { + } + + /// + internal Words(IGenerator generator, IDictionaryRepository repository, string dictionaryName) + : base(generator) + { + _repository = repository; + _dictionaryName = dictionaryName; + } + + internal string DictionaryName { get { return _dictionaryName; } } + + /// + protected override IList InitializeDataSource() + { + return _repository.GetWordsFrom(_dictionaryName); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/DataSources/Dictionaries/WordsCache.cs b/TestStack.Dossier/DataSources/Dictionaries/WordsCache.cs new file mode 100644 index 0000000..fbcb96b --- /dev/null +++ b/TestStack.Dossier/DataSources/Dictionaries/WordsCache.cs @@ -0,0 +1,37 @@ +using System.Collections.Concurrent; + +namespace TestStack.Dossier.DataSources.Dictionaries +{ + /// + /// Just caches a file dictionary data source the first time it is accessed and returns the same instance + /// each subsequent request. The Words data source is then responsible for lazy loading its dictionary contents + /// the first time it is accessed. At that point an exception will be thrown if the dictionary does not exist. + /// + internal static class WordsCache + { + private static ConcurrentDictionary _cache = new ConcurrentDictionary(); + + /// + /// Gets the Words in the file with the specified dictionary name. + /// This method is used by . + /// + /// Name of the dictionary file. + /// + internal static Words Get(string dictionaryName) + { + if (!_cache.ContainsKey(dictionaryName)) + { + _cache[dictionaryName] = new Words(dictionaryName); + } + return _cache[dictionaryName]; + } + + /// + /// Just exposed for testing purposes. + /// + internal static void Clear() + { + _cache = new ConcurrentDictionary(); + } + } +} diff --git a/TestStack.Dossier/DataSources/Geography/GeoContinentSource.cs b/TestStack.Dossier/DataSources/Geography/GeoContinentSource.cs index 7f0b525..b535f0a 100644 --- a/TestStack.Dossier/DataSources/Geography/GeoContinentSource.cs +++ b/TestStack.Dossier/DataSources/Geography/GeoContinentSource.cs @@ -1,10 +1,12 @@ -using TestStack.Dossier.DataSources.Dictionaries; +using System; +using TestStack.Dossier.DataSources.Dictionaries; namespace TestStack.Dossier.DataSources.Geography { /// /// Dictionary of continent names /// + [Obsolete("GeoContinentSource is deprecated, please use Words(FromDictionary.GeoContinent) instead.")] public class GeoContinentSource : FileDictionarySource { } diff --git a/TestStack.Dossier/DataSources/Geography/GeoCountryCodeSource.cs b/TestStack.Dossier/DataSources/Geography/GeoCountryCodeSource.cs index 4e398b0..514748d 100644 --- a/TestStack.Dossier/DataSources/Geography/GeoCountryCodeSource.cs +++ b/TestStack.Dossier/DataSources/Geography/GeoCountryCodeSource.cs @@ -1,10 +1,12 @@ -using TestStack.Dossier.DataSources.Dictionaries; +using System; +using TestStack.Dossier.DataSources.Dictionaries; namespace TestStack.Dossier.DataSources.Geography { /// /// Dictionary of country codes /// + [Obsolete("GeoCountryCodeSource is deprecated, please use Words(FromDictionary.GeoCountryCode) instead.")] public class GeoCountryCodeSource : FileDictionarySource { } diff --git a/TestStack.Dossier/DataSources/Geography/GeoCountrySource.cs b/TestStack.Dossier/DataSources/Geography/GeoCountrySource.cs index 0f9c3e0..a598c8e 100644 --- a/TestStack.Dossier/DataSources/Geography/GeoCountrySource.cs +++ b/TestStack.Dossier/DataSources/Geography/GeoCountrySource.cs @@ -1,10 +1,12 @@ -using TestStack.Dossier.DataSources.Dictionaries; +using System; +using TestStack.Dossier.DataSources.Dictionaries; namespace TestStack.Dossier.DataSources.Geography { /// /// Dictionary of country names /// + [Obsolete("GeoCountrySource is deprecated, please use Words(FromDictionary.GeoCountry) instead.")] public class GeoCountrySource : FileDictionarySource { } diff --git a/TestStack.Dossier/DataSources/Geography/GeoLatitudeSource.cs b/TestStack.Dossier/DataSources/Geography/GeoLatitudeSource.cs index f692bfb..1a12723 100644 --- a/TestStack.Dossier/DataSources/Geography/GeoLatitudeSource.cs +++ b/TestStack.Dossier/DataSources/Geography/GeoLatitudeSource.cs @@ -1,10 +1,12 @@ -using TestStack.Dossier.DataSources.Dictionaries; +using System; +using TestStack.Dossier.DataSources.Dictionaries; namespace TestStack.Dossier.DataSources.Geography { /// /// Dictionary of latitude coordinates /// + [Obsolete("GeoLatitudeSource is deprecated, please use Words(FromDictionary.GeoLatitude) instead.")] public class GeoLatitudeSource : FileDictionarySource { } diff --git a/TestStack.Dossier/DataSources/Geography/GeoLongitudeSource.cs b/TestStack.Dossier/DataSources/Geography/GeoLongitudeSource.cs index 1396c24..10d5aef 100644 --- a/TestStack.Dossier/DataSources/Geography/GeoLongitudeSource.cs +++ b/TestStack.Dossier/DataSources/Geography/GeoLongitudeSource.cs @@ -1,10 +1,12 @@ -using TestStack.Dossier.DataSources.Dictionaries; +using System; +using TestStack.Dossier.DataSources.Dictionaries; namespace TestStack.Dossier.DataSources.Geography { /// /// Dictionary of longitude coordinates codes /// + [Obsolete("GeoLongitudeSource is deprecated, please use Words(FromDictionary.GeoLongitude) instead.")] public class GeoLongitudeSource : FileDictionarySource { } diff --git a/TestStack.Dossier/DataSources/Person/PersonEmailAddressSource.cs b/TestStack.Dossier/DataSources/Person/PersonEmailAddressSource.cs index 5f0645d..19f2d1f 100644 --- a/TestStack.Dossier/DataSources/Person/PersonEmailAddressSource.cs +++ b/TestStack.Dossier/DataSources/Person/PersonEmailAddressSource.cs @@ -1,3 +1,4 @@ +using System; using TestStack.Dossier.DataSources.Dictionaries; using TestStack.Dossier.DataSources.Generators; @@ -6,6 +7,7 @@ namespace TestStack.Dossier.DataSources.Person /// /// Dictionary of email addresses names /// + [Obsolete("PersonEmailAddressSource is deprecated, please use Words(FromDictionary.PersonEmailAddress) instead.")] public class PersonEmailAddressSource : FileDictionarySource { /// diff --git a/TestStack.Dossier/DataSources/Person/PersonLanguageSource.cs b/TestStack.Dossier/DataSources/Person/PersonLanguageSource.cs index 74ac97b..39f5358 100644 --- a/TestStack.Dossier/DataSources/Person/PersonLanguageSource.cs +++ b/TestStack.Dossier/DataSources/Person/PersonLanguageSource.cs @@ -1,10 +1,12 @@ -using TestStack.Dossier.DataSources.Dictionaries; +using System; +using TestStack.Dossier.DataSources.Dictionaries; namespace TestStack.Dossier.DataSources.Person { /// /// Dictionary of language names /// + [Obsolete("PersonLanguageSource is deprecated, please use Words(FromDictionary.PersonLanguage) instead.")] public class PersonLanguageSource : FileDictionarySource { } diff --git a/TestStack.Dossier/DataSources/Person/PersonNameFirstFemaleSource.cs b/TestStack.Dossier/DataSources/Person/PersonNameFirstFemaleSource.cs index 866ff15..6f8dbb8 100644 --- a/TestStack.Dossier/DataSources/Person/PersonNameFirstFemaleSource.cs +++ b/TestStack.Dossier/DataSources/Person/PersonNameFirstFemaleSource.cs @@ -1,3 +1,4 @@ +using System; using TestStack.Dossier.DataSources.Dictionaries; namespace TestStack.Dossier.DataSources.Person @@ -5,6 +6,7 @@ namespace TestStack.Dossier.DataSources.Person /// /// Dictionary of female first names /// + [Obsolete("PersonNameFirstFemaleSource is deprecated, please use Words(FromDictionary.PersonNameFirstFemale) instead.")] public class PersonNameFirstFemaleSource : FileDictionarySource { } diff --git a/TestStack.Dossier/DataSources/Person/PersonNameFirstMaleSource.cs b/TestStack.Dossier/DataSources/Person/PersonNameFirstMaleSource.cs index fa33c33..982fa02 100644 --- a/TestStack.Dossier/DataSources/Person/PersonNameFirstMaleSource.cs +++ b/TestStack.Dossier/DataSources/Person/PersonNameFirstMaleSource.cs @@ -1,3 +1,4 @@ +using System; using TestStack.Dossier.DataSources.Dictionaries; namespace TestStack.Dossier.DataSources.Person @@ -5,6 +6,7 @@ namespace TestStack.Dossier.DataSources.Person /// /// Dictionary of male first names /// + [Obsolete("PersonNameFirstMaleSource is deprecated, please use Words(FromDictionary.PersonNameFirstMale) instead.")] public class PersonNameFirstMaleSource : FileDictionarySource { } diff --git a/TestStack.Dossier/DataSources/Person/PersonNameFirstSource.cs b/TestStack.Dossier/DataSources/Person/PersonNameFirstSource.cs index c913cbd..776cd9a 100644 --- a/TestStack.Dossier/DataSources/Person/PersonNameFirstSource.cs +++ b/TestStack.Dossier/DataSources/Person/PersonNameFirstSource.cs @@ -1,10 +1,12 @@ -using TestStack.Dossier.DataSources.Dictionaries; +using System; +using TestStack.Dossier.DataSources.Dictionaries; namespace TestStack.Dossier.DataSources.Person { /// /// Dictionary of male and female first names /// + [Obsolete("PersonNameFirstSource is deprecated, please use Words(FromDictionary.PersonNameFirst) instead.")] public class PersonNameFirstSource : FileDictionarySource { } diff --git a/TestStack.Dossier/DataSources/Person/PersonNameFullSource.cs b/TestStack.Dossier/DataSources/Person/PersonNameFullSource.cs index a94c348..abf7c78 100644 --- a/TestStack.Dossier/DataSources/Person/PersonNameFullSource.cs +++ b/TestStack.Dossier/DataSources/Person/PersonNameFullSource.cs @@ -1,3 +1,4 @@ +using System; using TestStack.Dossier.DataSources.Dictionaries; namespace TestStack.Dossier.DataSources.Person @@ -5,6 +6,7 @@ namespace TestStack.Dossier.DataSources.Person /// /// Dictionary of male and female full names - first and last name /// + [Obsolete("PersonNameFullSource is deprecated, please use Words(FromDictionary.PersonNameFull) instead.")] public class PersonNameFullSource : FileDictionarySource { } diff --git a/TestStack.Dossier/DataSources/Person/PersonNameLastSource.cs b/TestStack.Dossier/DataSources/Person/PersonNameLastSource.cs index 286557d..f016ef1 100644 --- a/TestStack.Dossier/DataSources/Person/PersonNameLastSource.cs +++ b/TestStack.Dossier/DataSources/Person/PersonNameLastSource.cs @@ -1,3 +1,4 @@ +using System; using TestStack.Dossier.DataSources.Dictionaries; namespace TestStack.Dossier.DataSources.Person @@ -5,6 +6,7 @@ namespace TestStack.Dossier.DataSources.Person /// /// Dictionary of last names /// + [Obsolete("PersonNameLastSource is deprecated, please use Words(FromDictionary.PersonNameLast) instead.")] public class PersonNameLastSource : FileDictionarySource { } diff --git a/TestStack.Dossier/DataSources/Person/PersonNameSuffixSource.cs b/TestStack.Dossier/DataSources/Person/PersonNameSuffixSource.cs index cab816a..46bf6bd 100644 --- a/TestStack.Dossier/DataSources/Person/PersonNameSuffixSource.cs +++ b/TestStack.Dossier/DataSources/Person/PersonNameSuffixSource.cs @@ -1,3 +1,4 @@ +using System; using TestStack.Dossier.DataSources.Dictionaries; namespace TestStack.Dossier.DataSources.Person @@ -5,6 +6,7 @@ namespace TestStack.Dossier.DataSources.Person /// /// Dictionary of name suffixes /// + [Obsolete("PersonNameSuffixSource is deprecated, please use Words(FromDictionary.PersonNameSuffix) instead.")] public class PersonNameSuffixSource : FileDictionarySource { } diff --git a/TestStack.Dossier/DataSources/Person/PersonNameTitleSource.cs b/TestStack.Dossier/DataSources/Person/PersonNameTitleSource.cs index d69a6b8..b2b04bb 100644 --- a/TestStack.Dossier/DataSources/Person/PersonNameTitleSource.cs +++ b/TestStack.Dossier/DataSources/Person/PersonNameTitleSource.cs @@ -1,3 +1,4 @@ +using System; using TestStack.Dossier.DataSources.Dictionaries; namespace TestStack.Dossier.DataSources.Person @@ -5,6 +6,7 @@ namespace TestStack.Dossier.DataSources.Person /// /// Dictionary of name titles /// + [Obsolete("PersonNameTitleSource is deprecated, please use Words(FromDictionary.PersonNameTitle) instead.")] public class PersonNameTitleSource : FileDictionarySource { } diff --git a/TestStack.Dossier/DataSources/Picking/Pick.cs b/TestStack.Dossier/DataSources/Picking/Pick.cs new file mode 100644 index 0000000..bff87f9 --- /dev/null +++ b/TestStack.Dossier/DataSources/Picking/Pick.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; + +namespace TestStack.Dossier.DataSources.Picking +{ + /// + /// Pick a sequence of items from a collection of items according to different selection strategies. + /// + public class Pick + { + /// + /// Selects a random item from the list each time it is called. + /// + /// + /// The list. + /// The RandomItemSource class. + public static RandomItemSource RandomItemFrom(IList list) + { + return new RandomItemSource(list); + } + + /// + /// Selects each item sequentially from the list and starts again from the beginning when the list is exhausted. + /// + /// + /// The list. + /// + public static RepeatingSequenceSource RepeatingSequenceFrom(IList list) + { + return new RepeatingSequenceSource(list); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/DataSources/Picking/RandomItemSource.cs b/TestStack.Dossier/DataSources/Picking/RandomItemSource.cs new file mode 100644 index 0000000..bc7fc08 --- /dev/null +++ b/TestStack.Dossier/DataSources/Picking/RandomItemSource.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; + +namespace TestStack.Dossier.DataSources.Picking +{ + /// + /// Implements the random item strategy + /// + public class RandomItemSource : DataSource + { + /// + public RandomItemSource(IList list) + { + Data = list; + Generator.StartIndex = 0; + Generator.ListSize = Data.Count; + } + + /// + protected override IList InitializeDataSource() + { + // This method will never be called as the list is set in the constructor. + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/DataSources/Picking/RepeatingSequenceSource.cs b/TestStack.Dossier/DataSources/Picking/RepeatingSequenceSource.cs new file mode 100644 index 0000000..5d98dda --- /dev/null +++ b/TestStack.Dossier/DataSources/Picking/RepeatingSequenceSource.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using TestStack.Dossier.DataSources.Generators; + +namespace TestStack.Dossier.DataSources.Picking +{ + /// + /// Implements the repeatable sequence strategy + /// + public class RepeatingSequenceSource : DataSource + { + /// + public RepeatingSequenceSource(IList list) + : base(new SequentialGenerator()) + { + Data = list; + Generator.StartIndex = 0; + Generator.ListSize = Data.Count; + } + + /// + protected override IList InitializeDataSource() + { + // This method will never be called as the list is set in the constructor. + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/EquivalenceClasses/AddressAusEquivalence.cs b/TestStack.Dossier/EquivalenceClasses/AddressAusEquivalence.cs new file mode 100644 index 0000000..71fbba2 --- /dev/null +++ b/TestStack.Dossier/EquivalenceClasses/AddressAusEquivalence.cs @@ -0,0 +1,94 @@ +using TestStack.Dossier.DataSources.Dictionaries; + +// ReSharper disable once CheckNamespace +namespace TestStack.Dossier +{ + /// + /// Methods that describe equivalence classes for generating anonymous Australian address-related values. + /// + public class AddressAusEquivalence + { + private readonly AnonymousValueFixture _fixture; + + /// + /// Creates a new with the AnonymousValueFixture from the extension method. + /// + /// The + public AddressAusEquivalence(AnonymousValueFixture fixture) + { + _fixture = fixture; + } + + /// + /// Generate and return an Australian address city name. + /// + /// The generated value. + public string City() + { + return _fixture.Words(FromDictionary.AddressAusCity).Next(); + } + + /// + /// Generate and return an Australian address company name. + /// + /// The generated value. + public string Company() + { + return _fixture.Words(FromDictionary.AddressAusCompany).Next(); + } + + /// + /// Generate and return an Australian address phone number. + /// + /// The generated value. + public string Phone() + { + return _fixture.Words(FromDictionary.AddressAusPhone).Next(); + } + + /// + /// Generate and return an Australian address post code. + /// + /// The generated value. + public string PostCode() + { + return _fixture.Words(FromDictionary.AddressAusPostCode).Next(); + } + + /// + /// Generate and return an Australian address state name. + /// + /// The generated value. + public string State() + { + return _fixture.Words(FromDictionary.AddressAusState).Next(); + } + + /// + /// Generate and return an Australian address state abbreviation. + /// + /// The generated value. + public string StateAbbreviation() + { + return _fixture.Words(FromDictionary.AddressAusStateAbbreviation).Next(); + } + + /// + /// Generate and return an Australian address street name. + /// + /// The generated value. + public string Street() + { + return _fixture.Words(FromDictionary.AddressAusStreet).Next(); + } + + /// + /// Generate and return an Australian address website name. + /// + /// The generated value. + public string Website() + { + return _fixture.Words(FromDictionary.AddressAusWebsite).Next(); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/EquivalenceClasses/AddressUkEquivalence.cs b/TestStack.Dossier/EquivalenceClasses/AddressUkEquivalence.cs new file mode 100644 index 0000000..fdafe27 --- /dev/null +++ b/TestStack.Dossier/EquivalenceClasses/AddressUkEquivalence.cs @@ -0,0 +1,85 @@ +using TestStack.Dossier.DataSources.Dictionaries; + +// ReSharper disable once CheckNamespace +namespace TestStack.Dossier +{ + /// + /// Methods that describe equivalence classes for generating anonymous UK address-related values. + /// + public class AddressUkEquivalence + { + private readonly AnonymousValueFixture _fixture; + + /// + /// Creates a new with the AnonymousValueFixture from the extension method. + /// + /// The + public AddressUkEquivalence(AnonymousValueFixture fixture) + { + _fixture = fixture; + } + + /// + /// Generate and return a UK address city name. + /// + /// The generated value. + public string City() + { + return _fixture.Words(FromDictionary.AddressUkCity).Next(); + } + + /// + /// Generate and return a UK address company name. + /// + /// The generated value. + public string Company() + { + return _fixture.Words(FromDictionary.AddressUkCompany).Next(); + } + + /// + /// Generate and return a UK address county name. + /// + /// The generated value. + public string County() + { + return _fixture.Words(FromDictionary.AddressUkCounty).Next(); + } + + /// + /// Generate and return a UK address phone number. + /// + /// The generated value. + public string Phone() + { + return _fixture.Words(FromDictionary.AddressUkPhone).Next(); + } + + /// + /// Generate and return a UK address post code. + /// + /// The generated value. + public string PostCode() + { + return _fixture.Words(FromDictionary.AddressUkPostCode).Next(); + } + + /// + /// Generate and return a UK address street name. + /// + /// The generated value. + public string Street() + { + return _fixture.Words(FromDictionary.AddressUkStreet).Next(); + } + + /// + /// Generate and return a UK address website name. + /// + /// The generated value. + public string Website() + { + return _fixture.Words(FromDictionary.AddressUkWebsite).Next(); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/EquivalenceClasses/AddressUsEquivalence.cs b/TestStack.Dossier/EquivalenceClasses/AddressUsEquivalence.cs new file mode 100644 index 0000000..d6eff0a --- /dev/null +++ b/TestStack.Dossier/EquivalenceClasses/AddressUsEquivalence.cs @@ -0,0 +1,103 @@ +using TestStack.Dossier.DataSources.Dictionaries; + +// ReSharper disable once CheckNamespace +namespace TestStack.Dossier +{ + /// + /// Methods that describe equivalence classes for generating anonymous US adress-related values. + /// + public class AddressUsEquivalence + { + private readonly AnonymousValueFixture _fixture; + + /// + /// Creates a new with the AnonymousValueFixture from the extension method. + /// + /// The + public AddressUsEquivalence(AnonymousValueFixture fixture) + { + _fixture = fixture; + } + + /// + /// Generate and return a US address city name. + /// + /// The generated value. + public string City() + { + return _fixture.Words(FromDictionary.AddressUsCity).Next(); + } + + /// + /// Generate and return a US address company name. + /// + /// The generated value. + public string Company() + { + return _fixture.Words(FromDictionary.AddressUsCompany).Next(); + } + + /// + /// Generate and return a US address phone number. + /// + /// The generated value. + public string Phone() + { + return _fixture.Words(FromDictionary.AddressUsPhone).Next(); + } + + /// + /// Generate and return a US address social security number. + /// + /// The generated value. + public string SocialSecurityNumber() + { + return _fixture.Words(FromDictionary.AddressUsSocialSecurityNumber).Next(); + } + + /// + /// Generate and return a US address state name. + /// + /// The generated value. + public string State() + { + return _fixture.Words(FromDictionary.AddressUsState).Next(); + } + + /// + /// Generate and return a US address state abbreviation. + /// + /// The generated value. + public string StateAbbreviation() + { + return _fixture.Words(FromDictionary.AddressUsStateAbbreviation).Next(); + } + + /// + /// Generate and return a US address street name. + /// + /// The generated value. + public string Street() + { + return _fixture.Words(FromDictionary.AddressUsStreet).Next(); + } + + /// + /// Generate and return a US address website name. + /// + /// The generated value. + public string Website() + { + return _fixture.Words(FromDictionary.AddressUsWebsite).Next(); + } + + /// + /// Generate and return a US address zip code. + /// + /// The generated value. + public string ZipCode() + { + return _fixture.Words(FromDictionary.AddressUsZipCode).Next(); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/EquivalenceClasses/ColourEquivalence.cs b/TestStack.Dossier/EquivalenceClasses/ColourEquivalence.cs new file mode 100644 index 0000000..4ce3774 --- /dev/null +++ b/TestStack.Dossier/EquivalenceClasses/ColourEquivalence.cs @@ -0,0 +1,40 @@ +using TestStack.Dossier.DataSources.Dictionaries; + +// ReSharper disable once CheckNamespace +namespace TestStack.Dossier +{ + /// + /// Methods that describe equivalence classes for generating anonymous Colour-related values. + /// + public class ColourEquivalence + { + private readonly AnonymousValueFixture _fixture; + + /// + /// Creates a new with the AnonymousValueFixture from the extension method. + /// + /// The + public ColourEquivalence(AnonymousValueFixture fixture) + { + _fixture = fixture; + } + + /// + /// Generate and return a Colour Hex value. + /// + /// The generated value. + public string Hex() + { + return _fixture.Words(FromDictionary.ColourHex).Next(); + } + + /// + /// Generate and return a Colour name. + /// + /// The generated value. + public string Name() + { + return _fixture.Words(FromDictionary.ColourName).Next(); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/EquivalenceClasses/CompanyEquivalence.cs b/TestStack.Dossier/EquivalenceClasses/CompanyEquivalence.cs new file mode 100644 index 0000000..ad58c6c --- /dev/null +++ b/TestStack.Dossier/EquivalenceClasses/CompanyEquivalence.cs @@ -0,0 +1,58 @@ +using TestStack.Dossier.DataSources.Dictionaries; + +// ReSharper disable once CheckNamespace +namespace TestStack.Dossier +{ + /// + /// Methods that describe equivalence classes for generating anonymous Company-related values. + /// + public class CompanyEquivalence + { + private readonly AnonymousValueFixture _fixture; + + /// + /// Creates a new with the AnonymousValueFixture from the extension method. + /// + /// The + public CompanyEquivalence(AnonymousValueFixture fixture) + { + _fixture = fixture; + } + + /// + /// Generate and return a company industry name. + /// + /// The generated value. + public string Industry() + { + return _fixture.Words(FromDictionary.CompanyIndustry).Next(); + } + + /// + /// Generate and return a company job title. + /// + /// The generated value. + public string JobTitle() + { + return _fixture.Words(FromDictionary.CompanyJobTitle).Next(); + } + + /// + /// Generate and return a company location name. + /// + /// The generated value. + public string Location() + { + return _fixture.Words(FromDictionary.CompanyLocation).Next(); + } + + /// + /// Generate and return a company name. + /// + /// The generated value. + public string Name() + { + return _fixture.Words(FromDictionary.CompanyName).Next(); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/EquivalenceClasses/EnumEquivalenceClasses.cs b/TestStack.Dossier/EquivalenceClasses/EnumEquivalenceClasses.cs index a37f287..c5c5b47 100644 --- a/TestStack.Dossier/EquivalenceClasses/EnumEquivalenceClasses.cs +++ b/TestStack.Dossier/EquivalenceClasses/EnumEquivalenceClasses.cs @@ -1,6 +1,6 @@ using System; using System.Linq; -using Ploeh.AutoFixture; +using AutoFixture; namespace TestStack.Dossier.EquivalenceClasses { diff --git a/TestStack.Dossier/EquivalenceClasses/Equivalence.cs b/TestStack.Dossier/EquivalenceClasses/Equivalence.cs new file mode 100644 index 0000000..14a0002 --- /dev/null +++ b/TestStack.Dossier/EquivalenceClasses/Equivalence.cs @@ -0,0 +1,89 @@ +// ReSharper disable once CheckNamespace +namespace TestStack.Dossier +{ + /// + /// Equivalence classes for generating anonymous values. + /// + public partial class AnonymousValueFixture + { + /// + /// Equivalence classes for generating anonymous Australian address-related values. + /// + public AddressAusEquivalence AddressAus + { + get { return new AddressAusEquivalence(this); } + } + + /// + /// Equivalence classes for generating anonymous United Kingdom address-related values. + /// + public AddressUkEquivalence AddressUk + { + get { return new AddressUkEquivalence(this);} + } + + /// + /// Equivalence classes for generating anonymous United States address-related values. + /// + public AddressUsEquivalence AddressUs + { + get { return new AddressUsEquivalence(this); } + } + + /// + /// Equivalence classes for generating anonymous colour-related values. + /// + public ColourEquivalence Colour + { + get { return new ColourEquivalence(this); } + } + + /// + /// Equivalence classes for generating anonymous company-related values. + /// + public CompanyEquivalence Company + { + get { return new CompanyEquivalence(this); } + } + + /// + /// Equivalence classes for generating anonymous finance-related values. + /// + public FinanceEquivalence Finance + { + get { return new FinanceEquivalence(this); } + } + + /// + /// Equivalence classes for generating anonymous geography-related values. + /// + public GeoEquivalence Geography + { + get { return new GeoEquivalence(this); } + } + + /// + /// Equivalence classes for generating anonymous identifier-related values. + /// + public IdentifierEquivalence Identifier + { + get { return new IdentifierEquivalence(this); } + } + + /// + /// Equivalence classes for generating anonymous internet-related values. + /// + public InternetEquivalence Internet + { + get { return new InternetEquivalence(this); } + } + + /// + /// Equivalence classes for generating anonymous person-related values. + /// + public PersonEquivalence Person + { + get { return new PersonEquivalence(this); } + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/EquivalenceClasses/FinanceEquivalence.cs b/TestStack.Dossier/EquivalenceClasses/FinanceEquivalence.cs new file mode 100644 index 0000000..c98e8a0 --- /dev/null +++ b/TestStack.Dossier/EquivalenceClasses/FinanceEquivalence.cs @@ -0,0 +1,59 @@ +using TestStack.Dossier.DataSources.Dictionaries; + +// ReSharper disable once CheckNamespace +namespace TestStack.Dossier +{ + /// + /// Methods that describe equivalence classes for generating anonymous Finance-related values. + /// + public class FinanceEquivalence + { + private readonly AnonymousValueFixture _fixture; + + /// + /// Creates a new with the AnonymousValueFixture from the extension method. + /// + /// The + public FinanceEquivalence(AnonymousValueFixture fixture) + { + _fixture = fixture; + } + + /// + /// Generate and return a finance credit card number. + /// + /// The generated value. + public string CreditCardNumber() + { + return _fixture.Words(FromDictionary.FinanceCreditCardNumber).Next(); + } + + /// + /// Generate and return a finance credit card type. + /// + /// The generated value. + public string CreditCardType() + { + return _fixture.Words(FromDictionary.FinanceCreditCardType).Next(); + } + + /// + /// Generate and return a finance currency name. + /// + /// The generated value. + public string Currency() + { + return _fixture.Words(FromDictionary.FinanceCurrency).Next(); + } + + /// + /// Generate and return a finance currency code. + /// + /// The generated value. + public string CurrencyCode() + { + return _fixture.Words(FromDictionary.FinanceCurrencyCode).Next(); + } + + } +} \ No newline at end of file diff --git a/TestStack.Dossier/EquivalenceClasses/FrequencyEquivalence.cs b/TestStack.Dossier/EquivalenceClasses/FrequencyEquivalence.cs new file mode 100644 index 0000000..5b2053e --- /dev/null +++ b/TestStack.Dossier/EquivalenceClasses/FrequencyEquivalence.cs @@ -0,0 +1,21 @@ +using TestStack.Dossier.DataSources.Dictionaries; + +// ReSharper disable once CheckNamespace +namespace TestStack.Dossier +{ + /// + /// Extension methods that describe equivalence classes for generating anonymous Frequency-related values. + /// + public static class FrequencyEquivalence + { + /// + /// Generate and return a frequency. + /// + /// The fixture to generate a value for. + /// The generated value. + public static string Frequency(this AnonymousValueFixture fixture) + { + return fixture.Words(FromDictionary.Frequency).Next(); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/EquivalenceClasses/Geo/GeographyEquivalenceClassescs.cs b/TestStack.Dossier/EquivalenceClasses/Geo/GeographyEquivalenceClassescs.cs index c8c4377..dcba4ff 100644 --- a/TestStack.Dossier/EquivalenceClasses/Geo/GeographyEquivalenceClassescs.cs +++ b/TestStack.Dossier/EquivalenceClasses/Geo/GeographyEquivalenceClassescs.cs @@ -1,4 +1,4 @@ -using TestStack.Dossier.DataSources.Geography; +using System; namespace TestStack.Dossier.EquivalenceClasses.Geo { @@ -7,21 +7,15 @@ namespace TestStack.Dossier.EquivalenceClasses.Geo /// public static class GeographyEquivalenceClassescs { - private static GeoContinentSource _geoContinentSource; - private static GeoCountrySource _geoCountrySource; - private static GeoCountryCodeSource _geoCountryCodeSource; - private static GeoLatitudeSource _geoLatitudeSource; - private static GeoLongitudeSource _geoLongitudeSource; - /// /// Generate and return a continent name. /// /// The fixture to generate a continent for /// The generated continent + [Obsolete("Continent is deprecated, please use Geography.Continent instead.")] public static string Continent(this AnonymousValueFixture fixture) { - if (_geoContinentSource == null) _geoContinentSource = new GeoContinentSource(); - return _geoContinentSource.Next(); + return fixture.Geography.Continent(); } /// @@ -29,10 +23,10 @@ public static string Continent(this AnonymousValueFixture fixture) /// /// The fixture to generate a country for /// The generated country + [Obsolete("Country is deprecated, please use Geography.Country instead.")] public static string Country(this AnonymousValueFixture fixture) { - if (_geoCountrySource == null) _geoCountrySource = new GeoCountrySource(); - return _geoCountrySource.Next(); + return fixture.Geography.Country(); } /// @@ -40,22 +34,21 @@ public static string Country(this AnonymousValueFixture fixture) /// /// The fixture to generate a country code for /// The generated country code + [Obsolete("CountryCode is deprecated, please use Geography.CountryCode instead.")] public static string CountryCode(this AnonymousValueFixture fixture) { - if (_geoCountryCodeSource == null) _geoCountryCodeSource = new GeoCountryCodeSource(); - return _geoCountryCodeSource.Next(); + return fixture.Geography.CountryCode(); } - /// /// Generate and return a latitude coordinate. /// /// The fixture to generate a latitutde for /// The generated latitude + [Obsolete("Latitude is deprecated, please use Geography.Latitude instead.")] public static string Latitude(this AnonymousValueFixture fixture) { - if (_geoLatitudeSource == null) _geoLatitudeSource = new GeoLatitudeSource(); - return _geoLatitudeSource.Next(); + return fixture.Geography.Latitude(); } /// @@ -63,10 +56,10 @@ public static string Latitude(this AnonymousValueFixture fixture) /// /// The fixture to generate a longitude for /// The generated longitude + [Obsolete("Longitude is deprecated, please use Geography.Longitude instead.")] public static string Longitude(this AnonymousValueFixture fixture) { - if (_geoLongitudeSource == null) _geoLongitudeSource = new GeoLongitudeSource(); - return _geoLongitudeSource.Next(); + return fixture.Geography.Longitude(); } } } diff --git a/TestStack.Dossier/EquivalenceClasses/GeoEquivalence.cs b/TestStack.Dossier/EquivalenceClasses/GeoEquivalence.cs new file mode 100644 index 0000000..7b34a40 --- /dev/null +++ b/TestStack.Dossier/EquivalenceClasses/GeoEquivalence.cs @@ -0,0 +1,67 @@ +using TestStack.Dossier.DataSources.Dictionaries; + +// ReSharper disable once CheckNamespace +namespace TestStack.Dossier +{ + /// + /// Methods that describe equivalence classes for generating anonymous Geography-related values. + /// + public class GeoEquivalence + { + private readonly AnonymousValueFixture _fixture; + + /// + /// Creates a new with the AnonymousValueFixture from the extension method. + /// + /// The + public GeoEquivalence(AnonymousValueFixture fixture) + { + _fixture = fixture; + } + + /// + /// Generate and return a geography continent name. + /// + /// The generated value. + public string Continent() + { + return _fixture.Words(FromDictionary.GeoContinent).Next(); + } + + /// + /// Generate and return a geography country name. + /// + /// The generated value. + public string Country() + { + return _fixture.Words(FromDictionary.GeoCountry).Next(); + } + + /// + /// Generate and return a geography country code. + /// + /// The generated value. + public string CountryCode() + { + return _fixture.Words(FromDictionary.GeoCountryCode).Next(); + } + + /// + /// Generate and return a geography latitude. + /// + /// The generated value. + public string Latitude() + { + return _fixture.Words(FromDictionary.GeoLatitude).Next(); + } + + /// + /// Generate and return a geography longitude. + /// + /// The generated value. + public string Longitude() + { + return _fixture.Words(FromDictionary.GeoLongitude).Next(); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/EquivalenceClasses/IdentifierEquivalence.cs b/TestStack.Dossier/EquivalenceClasses/IdentifierEquivalence.cs new file mode 100644 index 0000000..df3bb1b --- /dev/null +++ b/TestStack.Dossier/EquivalenceClasses/IdentifierEquivalence.cs @@ -0,0 +1,76 @@ +using TestStack.Dossier.DataSources.Dictionaries; + +// ReSharper disable once CheckNamespace +namespace TestStack.Dossier +{ + /// + /// Methods that describe equivalence classes for generating anonymous Identifier-related values. + /// + public class IdentifierEquivalence + { + private readonly AnonymousValueFixture _fixture; + + /// + /// Creates a new with the AnonymousValueFixture from the extension method. + /// + /// The + public IdentifierEquivalence(AnonymousValueFixture fixture) + { + _fixture = fixture; + } + + /// + /// Generate and return an identifier bitcoing address. + /// + /// The generated value. + public string BitcoinAddress() + { + return _fixture.Words(FromDictionary.IdentifierBitcoinAddress).Next(); + } + + /// + /// Generate and return an identifier IBAN. + /// + /// The generated value. + public string Iban() + { + return _fixture.Words(FromDictionary.IdentifierIban).Next(); + } + + /// + /// Generate and return an identifier IP address v4. + /// + /// The generated value. + public string IpAddressV4() + { + return _fixture.Words(FromDictionary.IdentifierIpAddressV4).Next(); + } + + /// + /// Generate and return an identifier IP address v6. + /// + /// The generated value. + public string IpAddressV6() + { + return _fixture.Words(FromDictionary.IdentifierIpAddressV6).Next(); + } + + /// + /// Generate and return an identifier ISBN. + /// + /// The generated value. + public string Isbn() + { + return _fixture.Words(FromDictionary.IdentifierIsbn).Next(); + } + + /// + /// Generate and return an identifier MAC address. + /// + /// The generated value. + public string MacAddress() + { + return _fixture.Words(FromDictionary.IdentifierMacAddress).Next(); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/EquivalenceClasses/IntegerEquivalenceClasses.cs b/TestStack.Dossier/EquivalenceClasses/IntegerEquivalenceClasses.cs index 9c60524..32c9acf 100644 --- a/TestStack.Dossier/EquivalenceClasses/IntegerEquivalenceClasses.cs +++ b/TestStack.Dossier/EquivalenceClasses/IntegerEquivalenceClasses.cs @@ -1,5 +1,5 @@ using System.Linq; -using Ploeh.AutoFixture; +using AutoFixture; namespace TestStack.Dossier.EquivalenceClasses { diff --git a/TestStack.Dossier/EquivalenceClasses/InternetEquivalence.cs b/TestStack.Dossier/EquivalenceClasses/InternetEquivalence.cs new file mode 100644 index 0000000..21f3b97 --- /dev/null +++ b/TestStack.Dossier/EquivalenceClasses/InternetEquivalence.cs @@ -0,0 +1,58 @@ +using TestStack.Dossier.DataSources.Dictionaries; + +// ReSharper disable once CheckNamespace +namespace TestStack.Dossier +{ + /// + /// Methods that describe equivalence classes for generating anonymous Internet-related values. + /// + public class InternetEquivalence + { + private readonly AnonymousValueFixture _fixture; + + /// + /// Creates a new with the AnonymousValueFixture from the extension method. + /// + /// The + public InternetEquivalence(AnonymousValueFixture fixture) + { + _fixture = fixture; + } + + /// + /// Generate and return an internet domain country code top level domain. + /// + /// The generated value. + public string DomainCountryCodeTopLevelDomain() + { + return _fixture.Words(FromDictionary.InternetDomainCountryCodeTopLevelDomain).Next(); + } + + /// + /// Generate and return an internet domain name. + /// + /// The generated value. + public string DomainName() + { + return _fixture.Words(FromDictionary.InternetDomainName).Next(); + } + + /// + /// Generate and return a an internet domain top level name. + /// + /// The generated value. + public string DomainTopLevel() + { + return _fixture.Words(FromDictionary.InternetDomainTopLevel).Next(); + } + + /// + /// Generate and return an internet URL. + /// + /// The generated value. + public string Url() + { + return _fixture.Words(FromDictionary.InternetUrl).Next(); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/EquivalenceClasses/LoremIpsumEquivalence.cs b/TestStack.Dossier/EquivalenceClasses/LoremIpsumEquivalence.cs new file mode 100644 index 0000000..acb23b2 --- /dev/null +++ b/TestStack.Dossier/EquivalenceClasses/LoremIpsumEquivalence.cs @@ -0,0 +1,21 @@ +using TestStack.Dossier.DataSources.Dictionaries; + +// ReSharper disable once CheckNamespace +namespace TestStack.Dossier +{ + /// + /// Extension methods that describe equivalence classes for generating anonymous Lorem Ipsum values. + /// + public static class LoremIpsumEquivalence + { + /// + /// Generate and return a lorem ipsum value. + /// + /// The fixture to generate a value for. + /// The generated value. + public static string LoremIpsum(this AnonymousValueFixture fixture) + { + return fixture.Words(FromDictionary.LoremIpsum).Next(); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/EquivalenceClasses/Person/PersonEquivalenceClasses.cs b/TestStack.Dossier/EquivalenceClasses/Person/PersonEquivalenceClasses.cs index d2f30b7..75bd46b 100644 --- a/TestStack.Dossier/EquivalenceClasses/Person/PersonEquivalenceClasses.cs +++ b/TestStack.Dossier/EquivalenceClasses/Person/PersonEquivalenceClasses.cs @@ -1,33 +1,21 @@ -using TestStack.Dossier.DataSources.Generators; -using TestStack.Dossier.DataSources.Person; +using System; namespace TestStack.Dossier.EquivalenceClasses.Person { /// /// Extension methods that describe equivalence classes for generating anonymous person-related values. /// - public static class NameEquivalenceClasses + public static class PersonEquivalenceClasses { - private static PersonEmailAddressSource _personEmailAddressSource; - private static PersonEmailAddressSource _uniquePersonEmailAddressSource; - private static PersonLanguageSource _personLanguageSource; - private static PersonNameFirstFemaleSource _personNameFirstFemaleSource; - private static PersonNameFirstSource _personNameFirstSource; - private static PersonNameFullSource _personNameFullSource; - private static PersonNameLastSource _personNameLastSource; - private static PersonNameFirstMaleSource _personNameFirstMaleSource; - private static PersonNameSuffixSource _personNameSuffixSource; - private static PersonNameTitleSource _personNameTitleSource; - /// /// Generate and return an email address. /// /// The fixture to generate a email for /// The generated email + [Obsolete("EmailAddress is deprecated, please use Person.EmailAddress instead.")] public static string EmailAddress(this AnonymousValueFixture fixture) { - if (_personEmailAddressSource == null) _personEmailAddressSource = new PersonEmailAddressSource(); - return _personEmailAddressSource.Next(); + return fixture.Person.EmailAddress(); } /// @@ -35,16 +23,10 @@ public static string EmailAddress(this AnonymousValueFixture fixture) /// /// The fixture to generate a unique email for /// The generated unique email + [Obsolete("UniqueEmailAddress is deprecated, please use Person.UniqueEmailAddress instead.")] public static string UniqueEmailAddress(this AnonymousValueFixture fixture) { - if (_uniquePersonEmailAddressSource == null) - { - if (_personEmailAddressSource == null) _personEmailAddressSource = new PersonEmailAddressSource(); - var generator = new SequentialGenerator(0, _personEmailAddressSource.Data.Count, listShouldBeUnique: true); - _uniquePersonEmailAddressSource = new PersonEmailAddressSource(generator); - } - - return _uniquePersonEmailAddressSource.Next(); + return fixture.Person.UniqueEmailAddress(); } /// @@ -52,10 +34,10 @@ public static string UniqueEmailAddress(this AnonymousValueFixture fixture) /// /// The fixture to generate a language for /// The generated language + [Obsolete("Language is deprecated, please use Person.Language instead.")] public static string Language(this AnonymousValueFixture fixture) { - if (_personLanguageSource == null) _personLanguageSource = new PersonLanguageSource(); - return _personLanguageSource.Next(); + return fixture.Person.Language(); } /// @@ -63,10 +45,10 @@ public static string Language(this AnonymousValueFixture fixture) /// /// The fixture to generate a first name for /// The generated female first name + [Obsolete("FemaleFirstName is deprecated, please use Person.NameFirstFemale instead.")] public static string FemaleFirstName(this AnonymousValueFixture fixture) { - if (_personNameFirstFemaleSource == null) _personNameFirstFemaleSource = new PersonNameFirstFemaleSource(); - return _personNameFirstFemaleSource.Next(); + return fixture.Person.NameFirstFemale(); } /// @@ -74,10 +56,10 @@ public static string FemaleFirstName(this AnonymousValueFixture fixture) /// /// The fixture to generate a first name for /// The generated first name + [Obsolete("FirstName is deprecated, please use Person.NameFirst instead.")] public static string FirstName(this AnonymousValueFixture fixture) { - if (_personNameFirstSource == null) _personNameFirstSource = new PersonNameFirstSource(); - return _personNameFirstSource.Next(); + return fixture.Person.NameFirst(); } /// @@ -85,10 +67,10 @@ public static string FirstName(this AnonymousValueFixture fixture) /// /// The fixture to generate a full name for /// The generated full name + [Obsolete("FullName is deprecated, please use Person.NameFull instead.")] public static string FullName(this AnonymousValueFixture fixture) { - if (_personNameFullSource == null) _personNameFullSource = new PersonNameFullSource(); - return _personNameFullSource.Next(); + return fixture.Person.NameFull(); } /// @@ -96,10 +78,10 @@ public static string FullName(this AnonymousValueFixture fixture) /// /// The fixture to generate a last name for /// The generated last name + [Obsolete("LastName is deprecated, please use Person.NameLast instead.")] public static string LastName(this AnonymousValueFixture fixture) { - if (_personNameLastSource == null) _personNameLastSource = new PersonNameLastSource(); - return _personNameLastSource.Next(); + return fixture.Person.NameLast(); } /// @@ -107,10 +89,10 @@ public static string LastName(this AnonymousValueFixture fixture) /// /// The fixture to generate a male first name for /// The generated male first name + [Obsolete("MaleFirstName is deprecated, please use Person.NameFirstMale instead.")] public static string MaleFirstName(this AnonymousValueFixture fixture) { - if (_personNameFirstMaleSource == null) _personNameFirstMaleSource = new PersonNameFirstMaleSource(); - return _personNameFirstMaleSource.Next(); + return fixture.Person.NameFirstMale(); } /// @@ -118,10 +100,10 @@ public static string MaleFirstName(this AnonymousValueFixture fixture) /// /// The fixture to generate a suffix for /// The generated suffix + [Obsolete("Suffix is deprecated, please use Person.NameSuffix instead.")] public static string Suffix(this AnonymousValueFixture fixture) { - if (_personNameSuffixSource == null) _personNameSuffixSource = new PersonNameSuffixSource(); - return _personNameSuffixSource.Next(); + return fixture.Person.NameSuffix(); } /// @@ -129,12 +111,10 @@ public static string Suffix(this AnonymousValueFixture fixture) /// /// The fixture to generate a title for /// The generated title + [Obsolete("Title is deprecated, please use Person.Title instead.")] public static string Title(this AnonymousValueFixture fixture) { - if (_personNameTitleSource == null) _personNameTitleSource = new PersonNameTitleSource(); - return _personNameTitleSource.Next(); + return fixture.Person.NameTitle(); } - } - } diff --git a/TestStack.Dossier/EquivalenceClasses/PersonEquivalence.cs b/TestStack.Dossier/EquivalenceClasses/PersonEquivalence.cs new file mode 100644 index 0000000..772bd0d --- /dev/null +++ b/TestStack.Dossier/EquivalenceClasses/PersonEquivalence.cs @@ -0,0 +1,130 @@ +using TestStack.Dossier.DataSources.Dictionaries; + +// ReSharper disable once CheckNamespace +namespace TestStack.Dossier +{ + /// + /// Methods that describe equivalence classes for generating anonymous Person-related values. + /// + public class PersonEquivalence + { + private readonly AnonymousValueFixture _fixture; + + /// + /// Creates a new with the AnonymousValueFixture from the extension method. + /// + /// The + public PersonEquivalence(AnonymousValueFixture fixture) + { + _fixture = fixture; + } + + /// + /// Generate and return a person email address. + /// + /// The generated value. + public string EmailAddress() + { + return _fixture.Words(FromDictionary.PersonEmailAddress).Next(); + } + + /// + /// Generate and return a person language. + /// + /// The generated value. + public string Language() + { + return _fixture.Words(FromDictionary.PersonLanguage).Next(); + } + + /// + /// Generate and return a person first name. + /// + /// The generated value. + public string NameFirst() + { + return _fixture.Words(FromDictionary.PersonNameFirst).Next(); + } + + /// + /// Generate and return a person female first name. + /// + /// The generated value. + public string NameFirstFemale() + { + return _fixture.Words(FromDictionary.PersonNameFirstFemale).Next(); + } + + /// + /// Generate and return a person male first name. + /// + /// The generated value. + public string NameFirstMale() + { + return _fixture.Words(FromDictionary.PersonNameFirstMale).Next(); + } + + /// + /// Generate and return a person full name. + /// + /// The generated value. + public string NameFull() + { + return _fixture.Words(FromDictionary.PersonNameFull).Next(); + } + + /// + /// Generate and return a person last name. + /// + /// The generated value. + public string NameLast() + { + return _fixture.Words(FromDictionary.PersonNameLast).Next(); + } + + /// + /// Generate and return a person name suffix. + /// + /// The generated value. + public string NameSuffix() + { + return _fixture.Words(FromDictionary.PersonNameSuffix).Next(); + } + + /// + /// Generate and return a person name title. + /// + /// The generated value. + public string NameTitle() + { + return _fixture.Words(FromDictionary.PersonNameTitle).Next(); + } + + /// + /// Generate and return a person password. + /// + /// The generated value. + public string Password() + { + return _fixture.Words(FromDictionary.PersonPassword).Next(); + } + + /// + /// Generate and return a person race. + /// + /// The generated value. + public string Race() + { + return _fixture.Words(FromDictionary.PersonRace).Next(); + } + + /// + /// Generate and return a person user name. + /// + /// The generated value. + public string Username() + { + return _fixture.Words(FromDictionary.PersonUsername).Next(); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/EquivalenceClasses/PersonEquivalenceExtensions.cs b/TestStack.Dossier/EquivalenceClasses/PersonEquivalenceExtensions.cs new file mode 100644 index 0000000..8245a6e --- /dev/null +++ b/TestStack.Dossier/EquivalenceClasses/PersonEquivalenceExtensions.cs @@ -0,0 +1,38 @@ +using TestStack.Dossier.DataSources.Dictionaries; +using TestStack.Dossier.DataSources.Generators; + +// ReSharper disable once CheckNamespace +namespace TestStack.Dossier +{ + /// + /// Extension methods that describe equivalence classes for generating anonymous Person-related values. + /// + public static class PersonEquivalenceExtensions + { + private static Words _uniquePersonEmailAddressSource; + private static readonly AnonymousValueFixture Fixture = new AnonymousValueFixture(); + + /// + /// Generate and return a unique email address (within the fixture). + /// + /// The fixture to generate a unique email for + /// The generated unique email + public static string UniqueEmailAddress(this PersonEquivalence personEquivalence) + { + if (_uniquePersonEmailAddressSource == null) + { + InitializeUniqueEmailAddressSource(); + } + + return _uniquePersonEmailAddressSource.Next(); + } + + internal static void InitializeUniqueEmailAddressSource() + { + var recordCount = Fixture.Words(FromDictionary.PersonEmailAddress).Data.Count; + var generator = new SequentialGenerator(0, recordCount, listShouldBeUnique: true); + _uniquePersonEmailAddressSource = new Words(generator, new CachedFileDictionaryRepository(), + FromDictionary.PersonEmailAddress); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/EquivalenceClasses/ShirtSizeEquivalence.cs b/TestStack.Dossier/EquivalenceClasses/ShirtSizeEquivalence.cs new file mode 100644 index 0000000..eadf468 --- /dev/null +++ b/TestStack.Dossier/EquivalenceClasses/ShirtSizeEquivalence.cs @@ -0,0 +1,21 @@ +using TestStack.Dossier.DataSources.Dictionaries; + +// ReSharper disable once CheckNamespace +namespace TestStack.Dossier +{ + /// + /// Extension methods that describe equivalence classes for generating anonymous Shirt Size-related values. + /// + public static class ShirtSizeEquivalence + { + /// + /// Generate and return a shirt size. + /// + /// The fixture to generate a value for. + /// The generated value. + public static string ShirtSize(this AnonymousValueFixture fixture) + { + return fixture.Words(FromDictionary.ShirtSize).Next(); + } + } +} diff --git a/TestStack.Dossier/EquivalenceClasses/StringEquivalenceClasses.cs b/TestStack.Dossier/EquivalenceClasses/StringEquivalenceClasses.cs index f694f9e..4ad3ae9 100644 --- a/TestStack.Dossier/EquivalenceClasses/StringEquivalenceClasses.cs +++ b/TestStack.Dossier/EquivalenceClasses/StringEquivalenceClasses.cs @@ -1,6 +1,6 @@ using System.Text; -using Ploeh.AutoFixture; -using Ploeh.AutoFixture.Kernel; +using AutoFixture; +using AutoFixture.Kernel; namespace TestStack.Dossier.EquivalenceClasses { @@ -48,7 +48,8 @@ public object Resolve(object request) /// The generated string public static string StringStartingWith(this AnonymousValueFixture fixture, string prefix) { - return fixture.Fixture.Create(prefix); + //return fixture.Fixture.Create(prefix); + return string.Format("{0}{1}", prefix, fixture.Fixture.Create()); } /// diff --git a/TestStack.Dossier/Factories/AllPropertiesFactory.cs b/TestStack.Dossier/Factories/AllPropertiesFactory.cs index 34bbc6d..1696811 100644 --- a/TestStack.Dossier/Factories/AllPropertiesFactory.cs +++ b/TestStack.Dossier/Factories/AllPropertiesFactory.cs @@ -1,18 +1,19 @@ -using Ploeh.AutoFixture; +using AutoFixture; namespace TestStack.Dossier.Factories { /// - /// Creates an instance of an object by setting all public and private properties. + /// Builds the object using the constructor with the most arguments using values stored in the builder that match + /// the constructor parameter name case insensitively and then sets all public and private property setters with + /// values from the builder. + /// If there is no value specified in the builder for a ctor argument / property then the builder will supply an anonymous value. /// - public class AllPropertiesFactory : IFactory + public class AllPropertiesFactory : CallConstructorFactory { /// - public TObject BuildObject(TestDataBuilder builder) - where TObject : class - where TBuilder : TestDataBuilder, new() + public override TObject BuildObject(TestDataBuilder builder) { - var model = builder.Any.Fixture.Create(); + var model = base.BuildObject(builder); var properties = Reflector.GetSettablePropertiesFor(); foreach (var property in properties) diff --git a/TestStack.Dossier/Factories/AutoFixtureFactory.cs b/TestStack.Dossier/Factories/AutoFixtureFactory.cs index 831c65b..588817d 100644 --- a/TestStack.Dossier/Factories/AutoFixtureFactory.cs +++ b/TestStack.Dossier/Factories/AutoFixtureFactory.cs @@ -1,9 +1,9 @@ -using Ploeh.AutoFixture; +using AutoFixture; namespace TestStack.Dossier.Factories { /// - /// Creates an instance of an object with AutoFixture. + /// Creates an instance of an object with AutoFixture - any values set in your builder will NOT be used to construct the object. /// public class AutoFixtureFactory : IFactory { diff --git a/TestStack.Dossier/Factories/CallConstructorFactory.cs b/TestStack.Dossier/Factories/CallConstructorFactory.cs new file mode 100644 index 0000000..b4a7232 --- /dev/null +++ b/TestStack.Dossier/Factories/CallConstructorFactory.cs @@ -0,0 +1,31 @@ +using System; +using System.Linq; + +namespace TestStack.Dossier.Factories +{ + /// + /// Builds the object using the constructor with the most arguments using values stored in the builder that match + /// the constructor parameter name case insensitively. + /// If there is no value specified in the builder for an argument then the builder will supply an anonymous value. + /// + public class CallConstructorFactory : IFactory + { + /// + public virtual TObject BuildObject(TestDataBuilder builder) + where TObject : class + where TBuilder : TestDataBuilder, new() + { + var longestConstructor = Reflector.GetLongestConstructor(); + + if (longestConstructor == null) + throw new InvalidOperationException("Could not find callable constructor for class " + typeof(TObject).Name); + + var parameterValues = longestConstructor + .GetParameters() + .Select(x => Reflector.GetPropertyValueFromTestDataBuilder(x.Name, x.ParameterType, typeof(TObject), typeof(TBuilder), builder)) + .ToArray(); + + return (TObject) longestConstructor.Invoke(parameterValues); + } + } +} \ No newline at end of file diff --git a/TestStack.Dossier/Factories/ConstructorFactory.cs b/TestStack.Dossier/Factories/ConstructorFactory.cs deleted file mode 100644 index 391aa2c..0000000 --- a/TestStack.Dossier/Factories/ConstructorFactory.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; -using Ploeh.AutoFixture; - -namespace TestStack.Dossier.Factories -{ - /// - /// Builds the object using the constructor with the most arguments. - /// - public class ConstructorFactory : IFactory - { - /// - public virtual TObject BuildObject(TestDataBuilder builder) - where TObject : class - where TBuilder : TestDataBuilder, new() - { - var longestConstructor = typeof(TObject) - .GetConstructors() - .OrderByDescending(x => x.GetParameters().Length) - .FirstOrDefault(); - - if (longestConstructor == null) throw new ObjectCreationException(); - - var parameterValues = longestConstructor - .GetParameters() - .Select(x => CallGetWithType(x.Name, x.ParameterType, typeof(TObject), typeof(TBuilder), builder)); - - return (TObject)longestConstructor.Invoke(parameterValues.ToArray()); - } - - private static object CallGetWithType(string propertyName, Type propertyType, Type objectType, Type builderType, object builder) - { - // Make a Func - var expressionDelegateType = typeof(Func<,>).MakeGenericType(objectType, propertyType); - var tObjParameterType = Expression.Parameter(objectType); - - var closedGenericGetMethod = builderType - .GetMethods() - .First(IsGenericGetMethod()) - .MakeGenericMethod(propertyType); - var valueStoredInBuilder = closedGenericGetMethod.Invoke(builder, new object[] - { - Expression.Lambda( - expressionDelegateType, - Expression.Property(tObjParameterType, propertyName), - tObjParameterType) - }); - - return valueStoredInBuilder; - } - - private static Func IsGenericGetMethod() - { - return method => method.Name == "Get" && method.ContainsGenericParameters && method.GetGenericArguments().Length == 1; - } - } -} \ No newline at end of file diff --git a/TestStack.Dossier/Factories/PublicPropertiesFactory.cs b/TestStack.Dossier/Factories/PublicPropertySettersFactory.cs similarity index 65% rename from TestStack.Dossier/Factories/PublicPropertiesFactory.cs rename to TestStack.Dossier/Factories/PublicPropertySettersFactory.cs index 4af57f3..aa015a9 100644 --- a/TestStack.Dossier/Factories/PublicPropertiesFactory.cs +++ b/TestStack.Dossier/Factories/PublicPropertySettersFactory.cs @@ -3,9 +3,12 @@ namespace TestStack.Dossier.Factories { /// - /// Creates an instance of an object by setting all public properties but not private properties. + /// Builds the object using the constructor with the most arguments using values stored in the builder that match + /// the constructor parameter name case insensitively and then sets all public property setters with values from + /// the builder. + /// If there is no value specified in the builder for a ctor argument / property then the builder will supply an anonymous value. /// - public class PublicPropertiesFactory : ConstructorFactory + public class PublicPropertySettersFactory : CallConstructorFactory { /// public override TObject BuildObject(TestDataBuilder builder) diff --git a/TestStack.Dossier/IAnonymousValueSupplier.cs b/TestStack.Dossier/IAnonymousValueSupplier.cs index 9eda5af..85fe113 100644 --- a/TestStack.Dossier/IAnonymousValueSupplier.cs +++ b/TestStack.Dossier/IAnonymousValueSupplier.cs @@ -15,16 +15,6 @@ public interface IAnonymousValueSupplier /// Whether or not this supplier can supply an anonymous value bool CanSupplyValue(Type type, string propertyName); - /// - /// Return an anonymous value for the given property and fixture. - /// - /// The type that the property is enclosed in - /// The type of the target property - the required anonymous value is of this type - /// Anonymous value fixture - /// The name of the property to return an anonymous value for - /// The anonymous value - TValue GenerateAnonymousValue(AnonymousValueFixture any, string propertyName); - /// /// Return an anonymous value for the given property and fixture. /// diff --git a/TestStack.Dossier/ITestDataBuilder.cs b/TestStack.Dossier/ITestDataBuilder.cs new file mode 100644 index 0000000..4dd8591 --- /dev/null +++ b/TestStack.Dossier/ITestDataBuilder.cs @@ -0,0 +1,15 @@ +namespace TestStack.Dossier +{ + /// + /// Base class definining infrastructure for a class that generates objects of type {TObject}. + /// + /// The type of object this class generates + public interface ITestDataBuilder where TObject : class + { + /// + /// Build the object. + /// + /// The built object + TObject Build(); + } +} diff --git a/TestStack.Dossier/Lists/EnsureAllMethodsVirtual.cs b/TestStack.Dossier/Lists/EnsureAllMethodsVirtual.cs index d2ad98e..88bd34b 100644 --- a/TestStack.Dossier/Lists/EnsureAllMethodsVirtual.cs +++ b/TestStack.Dossier/Lists/EnsureAllMethodsVirtual.cs @@ -13,7 +13,7 @@ public void MethodsInspected() public void NonProxyableMemberNotification(Type type, MemberInfo memberInfo) { - if (new[]{"get_Any", "set_Any", "Build", "AsProxy", "Get", "GetOrDefault", "Set", "Has", "get_ListBuilder", "set_ListBuilder", "BuildUsing", "SetFactory"}.Contains(memberInfo.Name)) + if (new[]{"get_Any", "set_Any", "Build", "AsProxy", "Get", "GetOrDefault", "Has", "get_ListBuilder", "set_ListBuilder", "BuildUsing", "SetFactory"}.Contains(memberInfo.Name)) return; throw new InvalidOperationException(string.Format("Tried to build a list with a builder who has non-virtual method. Please make {0} on type {1} virtual.", memberInfo.Name, type.Name)); } diff --git a/TestStack.Dossier/Lists/ListBuilder.cs b/TestStack.Dossier/Lists/ListBuilder.cs index 370a800..a5d7c11 100644 --- a/TestStack.Dossier/Lists/ListBuilder.cs +++ b/TestStack.Dossier/Lists/ListBuilder.cs @@ -14,16 +14,16 @@ public class ListBuilder where TBuilder : TestDataBuilder, new() where TObject : class { - private int _start = 0; - private int _count = 0; + private int _start; + private int _count; private readonly List _list; internal ListBuilder(int size) { + _list = new List(); BuilderProxy = (TBuilder) ListBuilderGenerator.Generator .CreateClassProxy(typeof (TBuilder), new ProxyGenerationOptions(new EnsureAllMethodsVirtual()), new ListBuilderInterceptor(this)); BuilderProxy.ListBuilder = this; - _list = new List(); var fixture = new AnonymousValueFixture(); for (var i = 0; i < size; i++) _list.Add(new TBuilder {Any = fixture}); @@ -115,6 +115,15 @@ public IList BuildList() return _list.Select(b => b.Build()).ToArray(); } + /// + /// Return the list of builder objects. + /// + /// The list of builder objects + public IEnumerable GetBuilders() + { + return _list.AsReadOnly(); + } + /// /// Builds the list of objects with implicit conversion operator. /// diff --git a/TestStack.Dossier/PathExpressionVisitor.cs b/TestStack.Dossier/PathExpressionVisitor.cs new file mode 100644 index 0000000..5e7ba19 --- /dev/null +++ b/TestStack.Dossier/PathExpressionVisitor.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Linq.Expressions; + +namespace TestStack.Dossier +{ + internal class PathExpressionVisitor : ExpressionVisitor + { + internal readonly List Path = new List(); + + protected override Expression VisitMember(MemberExpression node) + { + Path.Add(node.Member.Name); + return base.VisitMember(node); + } + } + +} diff --git a/TestStack.Dossier/Properties/AssemblyInfo.cs b/TestStack.Dossier/Properties/AssemblyInfo.cs deleted file mode 100644 index 35a1828..0000000 --- a/TestStack.Dossier/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("TestStack.Dossier")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("TestStack.Dossier")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -[assembly: InternalsVisibleTo("TestStack.Dossier.Tests")] -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("24a139fb-b390-4f14-9be6-cf9fb354bb5d")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] 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/Reflector.cs b/TestStack.Dossier/Reflector.cs index 5e3f51c..d01c98b 100644 --- a/TestStack.Dossier/Reflector.cs +++ b/TestStack.Dossier/Reflector.cs @@ -1,14 +1,17 @@ using System; +using System.Linq; using System.Linq.Expressions; using System.Reflection; namespace TestStack.Dossier { + // todo: Cache reflection information once per type for decent performance when building a lot of objects internal static class Reflector { public static string GetPropertyNameFor(Expression> property) { var memExp = property.Body as MemberExpression; + if (memExp == null) throw new ArgumentException( string.Format( @@ -19,12 +22,49 @@ public static string GetPropertyNameFor(Expression() + { + return typeof (T).GetProperties(BindingFlags.Public | BindingFlags.Instance); + } + + public static ConstructorInfo GetLongestConstructor() + { + return typeof (T) + .GetConstructors() + .OrderByDescending(x => x.GetParameters().Length) + .FirstOrDefault(); + } + + public static object GetPropertyValueFromTestDataBuilder(string propertyName, Type propertyType, Type objectType, Type builderType, object builder) + { + var expressionDelegateType = typeof(Func<,>).MakeGenericType(objectType, propertyType); + var tObjParameterType = Expression.Parameter(objectType); + + var closedGenericGetMethod = builderType + .GetMethods() + .First(IsGenericGetMethod()) + .MakeGenericMethod(propertyType); + + var valueStoredInBuilder = closedGenericGetMethod.Invoke(builder, new object[] + { + Expression.Lambda( + expressionDelegateType, + Expression.Property(tObjParameterType, propertyName), + tObjParameterType) + }); + + return valueStoredInBuilder; } - public static PropertyInfo[] GetSettablePropertiesFor() + private static Func IsGenericGetMethod() { - return typeof (TObject).GetProperties(BindingFlags.Public | BindingFlags.Instance); + return method => method.Name == "Get" && method.ContainsGenericParameters && method.GetGenericArguments().Length == 1; } } } diff --git a/TestStack.Dossier/Suppliers/DefaultEmailValueSupplier.cs b/TestStack.Dossier/Suppliers/DefaultEmailValueSupplier.cs index 754faba..62c1577 100644 --- a/TestStack.Dossier/Suppliers/DefaultEmailValueSupplier.cs +++ b/TestStack.Dossier/Suppliers/DefaultEmailValueSupplier.cs @@ -1,5 +1,5 @@ using System; -using TestStack.Dossier.EquivalenceClasses.Person; +using TestStack.Dossier.EquivalenceClasses; namespace TestStack.Dossier.Suppliers { @@ -14,16 +14,10 @@ public bool CanSupplyValue(Type type, string propertyName) return type == typeof(string) && propertyName.ToLower().Contains("email"); } - /// - public TValue GenerateAnonymousValue(AnonymousValueFixture any, string propertyName) - { - return (TValue) (object) any.EmailAddress(); - } - /// public object GenerateAnonymousValue(AnonymousValueFixture any, Type type, string propertyName) { - return any.EmailAddress(); + return any.Person.EmailAddress(); } } } diff --git a/TestStack.Dossier/Suppliers/DefaultFirstNameValueSupplier.cs b/TestStack.Dossier/Suppliers/DefaultFirstNameValueSupplier.cs index bbd2e59..7d596ee 100644 --- a/TestStack.Dossier/Suppliers/DefaultFirstNameValueSupplier.cs +++ b/TestStack.Dossier/Suppliers/DefaultFirstNameValueSupplier.cs @@ -1,5 +1,5 @@ using System; -using TestStack.Dossier.EquivalenceClasses.Person; +using TestStack.Dossier.EquivalenceClasses; namespace TestStack.Dossier.Suppliers { @@ -14,16 +14,10 @@ public bool CanSupplyValue(Type type, string propertyName) return type == typeof(string) && propertyName.ToLower() == "firstname"; } - /// - public TValue GenerateAnonymousValue(AnonymousValueFixture any, string propertyName) - { - return (TValue) (object) any.FirstName(); - } - /// public object GenerateAnonymousValue(AnonymousValueFixture any, Type type, string propertyName) { - return any.FirstName(); + return any.Person.NameFirst(); } } } diff --git a/TestStack.Dossier/Suppliers/DefaultLastNameValueSupplier.cs b/TestStack.Dossier/Suppliers/DefaultLastNameValueSupplier.cs index e0fc9c7..9cfe877 100644 --- a/TestStack.Dossier/Suppliers/DefaultLastNameValueSupplier.cs +++ b/TestStack.Dossier/Suppliers/DefaultLastNameValueSupplier.cs @@ -1,5 +1,5 @@ using System; -using TestStack.Dossier.EquivalenceClasses.Person; +using TestStack.Dossier.EquivalenceClasses; namespace TestStack.Dossier.Suppliers { @@ -15,16 +15,10 @@ public bool CanSupplyValue(Type type, string propertyName) (propertyName.ToLower() == "lastname" || propertyName.ToLower() == "surname"); } - /// - public TValue GenerateAnonymousValue(AnonymousValueFixture any, string propertyName) - { - return (TValue)(object)any.LastName(); - } - /// public object GenerateAnonymousValue(AnonymousValueFixture any, Type type, string propertyName) { - return any.LastName(); + return any.Person.NameLast(); } } } diff --git a/TestStack.Dossier/Suppliers/DefaultStringValueSupplier.cs b/TestStack.Dossier/Suppliers/DefaultStringValueSupplier.cs index ed5b40f..0402e00 100644 --- a/TestStack.Dossier/Suppliers/DefaultStringValueSupplier.cs +++ b/TestStack.Dossier/Suppliers/DefaultStringValueSupplier.cs @@ -14,12 +14,6 @@ public bool CanSupplyValue(Type type, string propertyName) return type == typeof(string); } - /// - public TValue GenerateAnonymousValue(AnonymousValueFixture any, string propertyName) - { - return (TValue) (object) any.StringStartingWith(propertyName); - } - /// public object GenerateAnonymousValue(AnonymousValueFixture any, Type type, string propertyName) { diff --git a/TestStack.Dossier/Suppliers/DefaultValueSupplier.cs b/TestStack.Dossier/Suppliers/DefaultValueSupplier.cs index 6bd6099..bfbea1c 100644 --- a/TestStack.Dossier/Suppliers/DefaultValueSupplier.cs +++ b/TestStack.Dossier/Suppliers/DefaultValueSupplier.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; namespace TestStack.Dossier.Suppliers { @@ -13,17 +14,11 @@ public bool CanSupplyValue(Type type, string propertyName) return true; } - /// - public TValue GenerateAnonymousValue(AnonymousValueFixture any, string propertyName) - { - return default(TValue); - } - /// public object GenerateAnonymousValue(AnonymousValueFixture any, Type type, string propertyName) { // See stackoverflow: http://stackoverflow.com/questions/325426/programmatic-equivalent-of-defaulttype - if (type.IsValueType) + if (type.GetTypeInfo().IsValueType) { return Activator.CreateInstance(type); } diff --git a/TestStack.Dossier/Suppliers/DefaultValueTypeValueSupplier.cs b/TestStack.Dossier/Suppliers/DefaultValueTypeValueSupplier.cs index bf1cd68..ae7ba85 100644 --- a/TestStack.Dossier/Suppliers/DefaultValueTypeValueSupplier.cs +++ b/TestStack.Dossier/Suppliers/DefaultValueTypeValueSupplier.cs @@ -1,7 +1,8 @@ using System; using System.Linq; -using Ploeh.AutoFixture; -using Ploeh.AutoFixture.Kernel; +using System.Reflection; +using AutoFixture; +using AutoFixture.Kernel; namespace TestStack.Dossier.Suppliers { @@ -13,20 +14,13 @@ public class DefaultValueTypeValueSupplier : IAnonymousValueSupplier /// public bool CanSupplyValue(Type type, string propertyName) { - return type.IsValueType; + return type.GetTypeInfo().IsValueType; } - /// - public TValue GenerateAnonymousValue(AnonymousValueFixture any, string propertyName) - { - return any.Fixture.Create(); - } - - /// How to create weakly-typed CreateAnonymous with AutoFixture - /// http://autofixture.codeplex.com/workitem/4229 /// public object GenerateAnonymousValue(AnonymousValueFixture any, Type type, string propertyName) { + // http://autofixture.codeplex.com/workitem/4229 var context = new SpecimenContext(any.Fixture); var specimen = context.Resolve(type); return specimen; diff --git a/TestStack.Dossier/TestDataBuilder.cs b/TestStack.Dossier/TestDataBuilder.cs index 3615844..224f300 100644 --- a/TestStack.Dossier/TestDataBuilder.cs +++ b/TestStack.Dossier/TestDataBuilder.cs @@ -11,11 +11,11 @@ namespace TestStack.Dossier /// /// The type of object this class generates /// The type for this class, yes this is a recursive type definition - public abstract class TestDataBuilder + public abstract class TestDataBuilder : ITestDataBuilder where TObject : class where TBuilder : TestDataBuilder, new() { - private readonly Dictionary _properties = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + private readonly Dictionary> _properties = new Dictionary>(); private ProxyBuilder _proxyBuilder; /// @@ -76,14 +76,14 @@ public static implicit operator List(TestDataBuilder /// The built object protected virtual TObject BuildObject() { - return BuildUsing(); + return BuildUsing(); } /// - /// + /// Builds the object from this builder using an . /// - /// - /// + /// The factory to use to build the object + /// The built object protected TObject BuildUsing() where TFactory : IFactory, new() { @@ -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 value to record - public TBuilder Set(Expression> property, TValue value) + /// 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 TBuilder Set(Expression> property, TValue v /// 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); } /// diff --git a/TestStack.Dossier/TestStack.Dossier.csproj b/TestStack.Dossier/TestStack.Dossier.csproj index f00abcf..5fc48a2 100644 --- a/TestStack.Dossier/TestStack.Dossier.csproj +++ b/TestStack.Dossier/TestStack.Dossier.csproj @@ -1,118 +1,97 @@ - - - + + - Debug - AnyCPU - {01E4EE61-AB1A-4177-8B6C-D50205D167A9} - Library - Properties - TestStack.Dossier + netstandard2.0 TestStack.Dossier - v4.0 - 512 - ..\ + TestStack.Dossier + Robert Moore, Michael Whelan, TestStack + + TestStack.Dossier provides you with the code infrastructure to easily and quickly generate test fixture data for your automated tests in a terse, readable and maintainable way using the Test Data Builder, anonymous value and equivalence class patterns. Formerly called NTestDataBuilder. + + false + testing data-generation test-fixture nbuilder nsubstitute autofixture mocking equivalence-class test-data-builder anonymous-value ntestdatabuilder + https://github.com/TestStack/TestStack.Dossier - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - bin\Debug\TestStack.Dossier.xml - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - bin\Release\TestStack.Dossier.xml + + + bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml + true + + + + + + + + - - ..\packages\Castle.Core.3.3.1\lib\net40-client\Castle.Core.dll - - - False - ..\packages\NSubstitute.1.8.1.0\lib\net40\NSubstitute.dll - - - ..\packages\AutoFixture.3.20.0\lib\net40\Ploeh.AutoFixture.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -149,6 +128,8 @@ + + @@ -177,12 +158,17 @@ - - + + + + + + + + + + 4.0.0-alpha.230 + + + \ No newline at end of file diff --git a/TestStack.Dossier/TestStack.Dossier.nuspec b/TestStack.Dossier/TestStack.Dossier.nuspec deleted file mode 100644 index b45f643..0000000 --- a/TestStack.Dossier/TestStack.Dossier.nuspec +++ /dev/null @@ -1,45 +0,0 @@ - - - - - TestStack.Dossier - - - 1.0.0 - - - Robert Moore, Michael Whelan, TestStack - - - TestStack.Dossier provides you with the code infrastructure to easily and quickly generate test fixture data for your automated tests in a terse, readable and maintainable way using the Test Data Builder, anonymous value and equivalence class patterns. - - Formerly called NTestDataBuilder. - - - https://github.com/TestStack/TestStack.Dossier - - - https://github.com/TestStack/TestStack.Dossier/blob/master/LICENSE - - - https://raw.github.com/TestStack/TestStack.Dossier/master/logo.png - - - testing data-generation test-fixture nbuilder nsubstitute autofixture mocking equivalence-class test-data-builder anonymous-value ntestdatabuilder - - - en-US - - - - - - - - - - - - - - diff --git a/TestStack.Dossier/packages.config b/TestStack.Dossier/packages.config deleted file mode 100644 index d6889a8..0000000 --- a/TestStack.Dossier/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..5a5ab94 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,65 @@ +version: 1.0.{build} +configuration: Release +image: +- Visual Studio 2017 +environment: + GitHubOrganisation: TestStack + GitHubToken: + secure: cBxvAtTgSlWVblTXtx8QKygh2HQeYZ9i0plMjJzCTNInGCm1XyG+nrSs18qUtC8W +before_build: +- ps: >- + dotnet restore + + dotnet tool install -g GitVersion.Tool --version 4.0.1-beta1-58 + + dotnet gitversion /output buildserver + + npm install github-release-notes -g +build_script: +- ps: dotnet build --source "**/*.csproj" --configuration Release --verbosity minimal -p:VersionPrefix="$Env:GitVersion_NuGetVersion" -p:FileVersion="$Env:GitVersion_AssemblySemFileVer" -p:InformationalVersion="$Env:GitVersion_InformationalVersion" +after_build: +- ps: >- + dotnet pack $Env:APPVEYOR_PROJECT_NAME/$Env:APPVEYOR_PROJECT_NAME.csproj --configuration Release /p:PackageVersion="$Env:GitVersion_NuGetVersion" --no-build --output "$Env:APPVEYOR_BUILD_FOLDER" --include-symbols + + $currentCommitIsTagged = git tag -l --points-at HEAD + + $HTTP_Request = [System.Net.WebRequest]::Create("https://api.github.com/repos/$env:GitHubOrganisation/$env:APPVEYOR_PROJECT_NAME/releases/tags/$Env:GitVersion_NuGetVersion") + + $HTTP_Request.UserAgent = "Powershell" + + try { + + $HTTP_Request.GetResponse() + + } catch [Net.WebException] { + + [System.Net.HttpWebResponse] $resp = [System.Net.HttpWebResponse] $_.Exception.Response + $noExistingGitHubRelease = $resp.StatusCode -eq 404 + + if ($currentCommitIsTagged -And $noExistingGitHubRelease) { + + $env:SHOULD_DEPLOY = 'true' + + } + + } +test: + assemblies: + only: + - '**\*.*Tests.dll' +artifacts: +- path: '*.nupkg' +deploy: +- provider: NuGet + api_key: + secure: VwHQFq0vD5vJNiUtsZMgUYdw2tVfXJfWh++eHC2LyEMvQzWiESWy2yBwQajzYAjo + on: + SHOULD_DEPLOY: true +after_deploy: +- ps: >- + gren release --token=$env:GitHubToken --username=$env:GitHubOrganisation --repo=$env:APPVEYOR_PROJECT_NAME +notifications: +- provider: GitHubPullRequest + on_build_success: true + on_build_failure: true + on_build_status_changed: false