├── src ├── DataProviders.Csv.Test │ ├── CsvFiles │ │ ├── Simple.csv │ │ ├── SimpleFail.csv │ │ ├── SimpleEmpty.csv │ │ └── Complex.csv │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── CsvDataProviderTest.cs │ ├── Asserts │ │ └── MyAssert.cs │ └── DataProviders.Csv.Test.csproj ├── DataProviders.Csv │ ├── packages.config │ ├── CsvDataProviderConfiguration.cs │ ├── CherrySeed.DataProviders.Csv.nuspec │ ├── CsvDataProvider.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── CsvFile.cs │ └── DataProviders.Csv.csproj ├── DataProviders.Gherkin │ ├── packages.config │ ├── GherkinDataProviderConfiguration.cs │ ├── CherrySeed.DataProviders.Gherkin.nuspec │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── GherkinDataProvider.cs │ └── DataProviders.Gherkin.csproj ├── DataProviders.SpecFlow │ ├── packages.config │ ├── App.config │ ├── CherrySeedConfigurationExtensions.cs │ ├── CherrySeedExtensions.cs │ ├── CherrySeed.DataProviders.SpecFlow.nuspec │ ├── SpecFlowDataProvider.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── DataProviders.SpecFlow.csproj ├── Repositories.Ef │ ├── packages.config │ ├── App.config │ ├── CherrySeed.Repositories.Ef.nuspec │ ├── EfRepository.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── Repositories.Ef.csproj ├── Repositories.Ef.Test │ ├── packages.config │ ├── App.config │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── EfRepositoryTest.cs │ └── Repositories.Ef.Test.csproj ├── CherrySeed │ ├── DefaultValues │ │ ├── IDefaultValueProvider.cs │ │ └── FuncDefaultValueProvider.cs │ ├── PrimaryKeyIdGeneration │ │ ├── IPrimaryKeyIdGenerator.cs │ │ ├── IMainPrimaryKeyIdGeneration.cs │ │ ├── DatabasePrimaryKeyIdGeneration.cs │ │ ├── ApplicationPrimaryKeyIdGeneration.cs │ │ └── ApplicationGeneration │ │ │ ├── GuidPrimaryKeyIdGenerator.cs │ │ │ ├── IntegerPrimaryKeyIdGenerator.cs │ │ │ └── StringPrimaryKeyIdGenerator.cs │ ├── EntityDataProvider │ │ ├── IDataProvider.cs │ │ └── EntityData.cs │ ├── IdMappings │ │ ├── IdMappingDescription.cs │ │ └── IdMappingProvider.cs │ ├── Repositories │ │ └── IRepository.cs │ ├── TypeTransformations │ │ ├── ITypeTransformation.cs │ │ ├── GuidTransformation.cs │ │ ├── BooleanTransformation.cs │ │ ├── DoubleTransformation.cs │ │ ├── IntegerTransformation.cs │ │ ├── DecimalTransformation.cs │ │ ├── DateTimeTransformation.cs │ │ ├── TypeTransformationBase.cs │ │ ├── EnumTransformation.cs │ │ ├── StringTransformation.cs │ │ └── TypeTransformationProvider.cs │ ├── ObjectTransformation │ │ ├── PropertyHandlers │ │ │ ├── IPropertyHandler.cs │ │ │ ├── PrimaryKeyHandler.cs │ │ │ ├── PropertyHandler.cs │ │ │ ├── ForeignKeyHandler.cs │ │ │ └── CopyPropertyValueHandler.cs │ │ ├── ObjectListTransformation.cs │ │ ├── PropertyTransformationException.cs │ │ └── ObjectTransformation.cs │ ├── EntityMetadata.cs │ ├── EntitySettings │ │ ├── IdGenerationSetting.cs │ │ ├── ReferenceSetting.cs │ │ ├── DefaultValueSetting.cs │ │ ├── EntitySetting.cs │ │ └── PrimaryKeySetting.cs │ ├── Utils │ │ ├── DictionaryExtensions.cs │ │ └── ReflectionUtil.cs │ ├── Configuration │ │ ├── CherrySeedConfiguration.cs │ │ ├── Exceptions │ │ │ └── ConfigurationException.cs │ │ ├── SeederConfigurationValidator.cs │ │ ├── SeederConfiguration.cs │ │ └── ISeederConfigurationBuilder.cs │ ├── CherrySeed.nuspec │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── CherrySeeder.cs │ └── CherrySeed.csproj ├── DataProviders.SpecFlow.Test │ ├── Entities │ │ ├── Country.cs │ │ └── Project.cs │ ├── packages.config │ ├── App.config │ ├── RealisticEnvironment │ │ ├── Features │ │ │ ├── Project.feature │ │ │ └── Project.feature.cs │ │ └── StepDefinitions │ │ │ ├── ProjectSteps.cs │ │ │ └── CherrySeedSupport.cs │ ├── Common │ │ └── CherrySeedConfigurationExtensions.cs │ ├── IntegrationTests │ │ ├── ProjectObjectMother.cs │ │ ├── EntityAsserts.cs │ │ └── SpecFlowExtensionsTests.cs │ └── Properties │ │ └── AssemblyInfo.cs ├── DataProviders.Gherkin.Test │ ├── Testfeature.feature │ ├── GherkinDataProviderTest.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── DataProviders.Gherkin.Test.csproj ├── CherrySeed.Test │ ├── Infrastructure │ │ ├── CultureUtil.cs │ │ ├── SetupAssemblyInitializer.cs │ │ ├── Extensions.cs │ │ ├── CherrySeedDriver.cs │ │ └── EntityDataBuilder.cs │ ├── Mocks │ │ ├── SequentialGuidPrimaryKeyIdGenerator.cs │ │ ├── DefaultValueProviderMock.cs │ │ ├── DictionaryDataProvider.cs │ │ ├── SequentialStringPrimaryKeyIdGenerator.cs │ │ └── CustomTypeTransformation.cs │ ├── App.config │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── IntegrationTests │ │ ├── ConfigurationValidationTests.cs │ │ ├── ProgressActionTests.cs │ │ ├── PropertyTransformationTests │ │ │ ├── EnumPropertyTransformationTests.cs │ │ │ ├── NullablePropertyTransformationTests.cs │ │ │ └── NullableEnumPropertyTransformationTests.cs │ │ ├── CustomTypeTransformationTests.cs │ │ ├── DefaultValuePropertyTests.cs │ │ ├── EntitySeedingOrderTests.cs │ │ └── EntityNameMatchingTests.cs │ ├── Models │ │ └── EntityWithSimpleProperties.cs │ └── Asserts │ │ └── EntityAsserts.cs └── CherrySeed.Test.Base │ ├── Repositories │ ├── EmptyRepository.cs │ └── AssertRepository.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── Asserts │ └── AssertHelper.cs │ └── CherrySeed.Test.Base.csproj ├── CherrySeed-icon-small.png ├── CherrySeed-Icon-With-Name-small.png ├── resources └── logos │ ├── logo-withName-small.png │ └── logo-withoutName-small.png ├── LICENSE ├── README.md └── .gitignore /src/DataProviders.Csv.Test/CsvFiles/Simple.csv: -------------------------------------------------------------------------------- 1 | Field1;Field2;Field3 2 | 1;2;3 3 | 4;5;6 -------------------------------------------------------------------------------- /src/DataProviders.Csv.Test/CsvFiles/SimpleFail.csv: -------------------------------------------------------------------------------- 1 | Field1;Field2;Field3 2 | 1;2 3 | 4;5;6 -------------------------------------------------------------------------------- /src/DataProviders.Csv.Test/CsvFiles/SimpleEmpty.csv: -------------------------------------------------------------------------------- 1 | Field1;Field2;Field3 2 | ;2; 3 | 4;5;6 -------------------------------------------------------------------------------- /CherrySeed-icon-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/altmann/CherrySeed/HEAD/CherrySeed-icon-small.png -------------------------------------------------------------------------------- /CherrySeed-Icon-With-Name-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/altmann/CherrySeed/HEAD/CherrySeed-Icon-With-Name-small.png -------------------------------------------------------------------------------- /resources/logos/logo-withName-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/altmann/CherrySeed/HEAD/resources/logos/logo-withName-small.png -------------------------------------------------------------------------------- /resources/logos/logo-withoutName-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/altmann/CherrySeed/HEAD/resources/logos/logo-withoutName-small.png -------------------------------------------------------------------------------- /src/DataProviders.Csv.Test/CsvFiles/Complex.csv: -------------------------------------------------------------------------------- 1 | Name;Birthdate;Year;DecimalField 2 | Michael Altmann;2016-06-06;2017;12.12 3 | Simone Altmann;2012-02-02;2011;33.44 -------------------------------------------------------------------------------- /src/DataProviders.Csv/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/DataProviders.Gherkin/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/Repositories.Ef/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/Repositories.Ef.Test/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/CherrySeed/DefaultValues/IDefaultValueProvider.cs: -------------------------------------------------------------------------------- 1 | namespace CherrySeed.DefaultValues 2 | { 3 | public interface IDefaultValueProvider 4 | { 5 | object GetDefaultValue(); 6 | } 7 | } -------------------------------------------------------------------------------- /src/CherrySeed/PrimaryKeyIdGeneration/IPrimaryKeyIdGenerator.cs: -------------------------------------------------------------------------------- 1 | namespace CherrySeed.PrimaryKeyIdGeneration 2 | { 3 | public interface IPrimaryKeyIdGenerator 4 | { 5 | object Generate(); 6 | } 7 | } -------------------------------------------------------------------------------- /src/CherrySeed/EntityDataProvider/IDataProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace CherrySeed.EntityDataProvider 4 | { 5 | public interface IDataProvider 6 | { 7 | List GetEntityDataList(); 8 | } 9 | } -------------------------------------------------------------------------------- /src/CherrySeed/IdMappings/IdMappingDescription.cs: -------------------------------------------------------------------------------- 1 | namespace CherrySeed.IdMappings 2 | { 3 | class IdMappingDescription 4 | { 5 | public string ProviderId { get; set; } 6 | public object RepositoryId { get; set; } 7 | } 8 | } -------------------------------------------------------------------------------- /src/CherrySeed/PrimaryKeyIdGeneration/IMainPrimaryKeyIdGeneration.cs: -------------------------------------------------------------------------------- 1 | namespace CherrySeed.PrimaryKeyIdGeneration 2 | { 3 | public interface IMainPrimaryKeyIdGeneration 4 | { 5 | IPrimaryKeyIdGenerator Generator { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow.Test/Entities/Country.cs: -------------------------------------------------------------------------------- 1 | namespace CherrySeed.DataProviders.SpecFlow.Test.Entities 2 | { 3 | public class Country 4 | { 5 | public int Id { get; set; } 6 | public string Name { get; set; } 7 | } 8 | } -------------------------------------------------------------------------------- /src/DataProviders.Gherkin.Test/Testfeature.feature: -------------------------------------------------------------------------------- 1 | Feature: Testfeature 2 | 3 | Scenario: Adding testdata 4 | Given the following data of entity 'Person' 5 | | Id | Name | Jahr | 6 | | 1 | Michael | 2016-01-01 | 7 | | 2 | Baba | 2016-01-01 | -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow.Test/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/CherrySeed/PrimaryKeyIdGeneration/DatabasePrimaryKeyIdGeneration.cs: -------------------------------------------------------------------------------- 1 | namespace CherrySeed.PrimaryKeyIdGeneration 2 | { 3 | public class DatabasePrimaryKeyIdGeneration : IMainPrimaryKeyIdGeneration 4 | { 5 | public IPrimaryKeyIdGenerator Generator { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /src/CherrySeed/PrimaryKeyIdGeneration/ApplicationPrimaryKeyIdGeneration.cs: -------------------------------------------------------------------------------- 1 | namespace CherrySeed.PrimaryKeyIdGeneration 2 | { 3 | public class ApplicationPrimaryKeyIdGeneration : IMainPrimaryKeyIdGeneration 4 | { 5 | public IPrimaryKeyIdGenerator Generator { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow.Test/Entities/Project.cs: -------------------------------------------------------------------------------- 1 | namespace CherrySeed.DataProviders.SpecFlow.Test.Entities 2 | { 3 | public class Project 4 | { 5 | public int Id { get; set; } 6 | public string Name { get; set; } 7 | public int CountryId { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/CherrySeed/Repositories/IRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CherrySeed.Repositories 4 | { 5 | public interface IRepository 6 | { 7 | void SaveEntity(object obj); 8 | void RemoveEntities(Type type); 9 | object LoadEntity(Type type, object id); 10 | } 11 | } -------------------------------------------------------------------------------- /src/CherrySeed/TypeTransformations/ITypeTransformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CherrySeed.TypeTransformations 4 | { 5 | public interface ITypeTransformation 6 | { 7 | object Transform(Type type, string str); 8 | object TransformNullable(Type type, string str); 9 | } 10 | } -------------------------------------------------------------------------------- /src/CherrySeed/ObjectTransformation/PropertyHandlers/IPropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using CherrySeed.EntitySettings; 2 | 3 | namespace CherrySeed.ObjectTransformation.PropertyHandlers 4 | { 5 | interface IPropertyHandler 6 | { 7 | void Handle(object obj, string propertyName, string propertyValue, EntitySetting entitySetting); 8 | } 9 | } -------------------------------------------------------------------------------- /src/CherrySeed/TypeTransformations/GuidTransformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CherrySeed.TypeTransformations 4 | { 5 | class GuidTransformation : TypeTransformationBase 6 | { 7 | public override object Transform(Type type, string str) 8 | { 9 | return Guid.Parse(str); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/CherrySeed/TypeTransformations/BooleanTransformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CherrySeed.TypeTransformations 4 | { 5 | class BooleanTransformation : TypeTransformationBase 6 | { 7 | public override object Transform(Type type, string str) 8 | { 9 | return bool.Parse(str); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/CherrySeed/TypeTransformations/DoubleTransformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CherrySeed.TypeTransformations 4 | { 5 | class DoubleTransformation : TypeTransformationBase 6 | { 7 | public override object Transform(Type type, string str) 8 | { 9 | return double.Parse(str); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/CherrySeed/TypeTransformations/IntegerTransformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CherrySeed.TypeTransformations 4 | { 5 | class IntegerTransformation : TypeTransformationBase 6 | { 7 | public override object Transform(Type type, string str) 8 | { 9 | return int.Parse(str); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/CherrySeed/TypeTransformations/DecimalTransformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CherrySeed.TypeTransformations 4 | { 5 | class DecimalTransformation : TypeTransformationBase 6 | { 7 | public override object Transform(Type type, string str) 8 | { 9 | return decimal.Parse(str); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/CherrySeed/TypeTransformations/DateTimeTransformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CherrySeed.TypeTransformations 4 | { 5 | class DateTimeTransformation : TypeTransformationBase 6 | { 7 | public override object Transform(Type type, string str) 8 | { 9 | return DateTime.Parse(str); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/CherrySeed/PrimaryKeyIdGeneration/ApplicationGeneration/GuidPrimaryKeyIdGenerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CherrySeed.PrimaryKeyIdGeneration.ApplicationGeneration 4 | { 5 | class GuidPrimaryKeyIdGenerator : IPrimaryKeyIdGenerator 6 | { 7 | public object Generate() 8 | { 9 | return Guid.NewGuid(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/CherrySeed.Test/Infrastructure/CultureUtil.cs: -------------------------------------------------------------------------------- 1 | namespace CherrySeed.Test.Infrastructure 2 | { 3 | public class CultureUtil 4 | { 5 | public static void SetGermanCulture() 6 | { 7 | System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("de-DE"); 8 | System.Threading.Thread.CurrentThread.CurrentCulture = ci; 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/DataProviders.Gherkin/GherkinDataProviderConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace CherrySeed.DataProviders.Gherkin 4 | { 5 | public class GherkinDataProviderConfiguration 6 | { 7 | public GherkinDataProviderConfiguration() 8 | { 9 | FilePaths = new List(); 10 | } 11 | 12 | public List FilePaths { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/CherrySeed.Test/Infrastructure/SetupAssemblyInitializer.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | 3 | namespace CherrySeed.Test.Infrastructure 4 | { 5 | [TestClass] 6 | public class SetupAssemblyInitializer 7 | { 8 | [AssemblyInitialize] 9 | public static void AssemblyInit(TestContext context) 10 | { 11 | CultureUtil.SetGermanCulture(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow.Test/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/CherrySeed/EntityDataProvider/EntityData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace CherrySeed.EntityDataProvider 4 | { 5 | public class EntityData 6 | { 7 | public EntityData() 8 | { 9 | Objects = new List>(); 10 | } 11 | 12 | public string EntityName { get; set; } 13 | public List> Objects { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/CherrySeed/EntityMetadata.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using CherrySeed.EntitySettings; 4 | 5 | namespace CherrySeed 6 | { 7 | class EntityMetadata 8 | { 9 | public Type EntityType { get; set; } 10 | public List> ObjectsAsDict { get; set; } 11 | public List Objects { get; set; } 12 | public EntitySetting EntitySetting { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/CherrySeed.Test/Mocks/SequentialGuidPrimaryKeyIdGenerator.cs: -------------------------------------------------------------------------------- 1 | using CherrySeed.PrimaryKeyIdGeneration; 2 | using CherrySeed.Test.Infrastructure; 3 | 4 | namespace CherrySeed.Test.Mocks 5 | { 6 | public class SequentialGuidPrimaryKeyIdGenerator : IPrimaryKeyIdGenerator 7 | { 8 | private int _id = 0; 9 | 10 | public object Generate() 11 | { 12 | _id++; 13 | return _id.ToGuid(); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow.Test/RealisticEnvironment/Features/Project.feature: -------------------------------------------------------------------------------- 1 | Feature: Project 2 | 3 | Scenario: Seeding countries and projects 4 | Given the following countries exist 5 | | Id | Name | 6 | | N | North | 7 | | S | South | 8 | | L | London | 9 | And the following projects exist 10 | | Id | Name | CountryId | 11 | | P1 | Increase budget | N | 12 | | P2 | Move to USA | S | 13 | | P3 | Decrease tools | S | -------------------------------------------------------------------------------- /src/CherrySeed.Test/Mocks/DefaultValueProviderMock.cs: -------------------------------------------------------------------------------- 1 | using CherrySeed.DefaultValues; 2 | 3 | namespace CherrySeed.Test.Mocks 4 | { 5 | public class DefaultValueProviderMock : IDefaultValueProvider 6 | { 7 | private readonly T _value; 8 | 9 | public DefaultValueProviderMock(T value) 10 | { 11 | _value = value; 12 | } 13 | 14 | public object GetDefaultValue() 15 | { 16 | return _value; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/CherrySeed/TypeTransformations/TypeTransformationBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CherrySeed.TypeTransformations 4 | { 5 | abstract class TypeTransformationBase : ITypeTransformation 6 | { 7 | public abstract object Transform(Type type, string str); 8 | 9 | public object TransformNullable(Type type, string str) 10 | { 11 | if (string.IsNullOrEmpty(str)) 12 | return null; 13 | 14 | return Transform(type, str); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow/CherrySeedConfigurationExtensions.cs: -------------------------------------------------------------------------------- 1 | using CherrySeed.Configuration; 2 | 3 | namespace CherrySeed.DataProviders.SpecFlow 4 | { 5 | public static class CherrySeedConfigurationExtensions 6 | { 7 | public static void WithSpecFlowConfiguration(this ISeederConfigurationBuilder configurationBuilder) 8 | { 9 | configurationBuilder.WithDataProvider(new SpecFlowDataProvider()); 10 | configurationBuilder.DisableClearBeforeSeeding(); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/CherrySeed/TypeTransformations/EnumTransformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CherrySeed.Utils; 3 | 4 | namespace CherrySeed.TypeTransformations 5 | { 6 | class EnumTransformation : TypeTransformationBase 7 | { 8 | public override object Transform(Type type, string str) 9 | { 10 | var enumType = ReflectionUtil.IsNullableValueType(type) 11 | ? Nullable.GetUnderlyingType(type) 12 | : type; 13 | 14 | return Enum.Parse(enumType, str); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/CherrySeed/EntitySettings/IdGenerationSetting.cs: -------------------------------------------------------------------------------- 1 | using CherrySeed.PrimaryKeyIdGeneration; 2 | 3 | namespace CherrySeed.EntitySettings 4 | { 5 | public class IdGenerationSetting 6 | { 7 | public IMainPrimaryKeyIdGeneration Generator { get; set; } 8 | public bool IsGeneratorEnabled => Generator != null; 9 | public bool IsDatabaseGenerationEnabled => Generator is DatabasePrimaryKeyIdGeneration; 10 | public bool IsApplicationGenerationEnabled => Generator is ApplicationPrimaryKeyIdGeneration; 11 | } 12 | } -------------------------------------------------------------------------------- /src/CherrySeed/DefaultValues/FuncDefaultValueProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CherrySeed.DefaultValues 4 | { 5 | class FuncDefaultValueProvider : IDefaultValueProvider 6 | { 7 | private readonly Func _defaultValueFunc; 8 | 9 | public FuncDefaultValueProvider(Func defaultValueFunc) 10 | { 11 | _defaultValueFunc = defaultValueFunc; 12 | } 13 | 14 | public object GetDefaultValue() 15 | { 16 | return _defaultValueFunc(); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/CherrySeed.Test.Base/Repositories/EmptyRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CherrySeed.Repositories; 3 | 4 | namespace CherrySeed.Test.Base.Repositories 5 | { 6 | public class EmptyRepository : IRepository 7 | { 8 | public void SaveEntity(object obj) 9 | { 10 | 11 | } 12 | 13 | public void RemoveEntities(Type type) 14 | { 15 | 16 | } 17 | 18 | public object LoadEntity(Type type, object id) 19 | { 20 | return null; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/CherrySeed/Utils/DictionaryExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace CherrySeed.Utils 4 | { 5 | public static class DictionaryExtensions 6 | { 7 | public static void AddOrReplace(this Dictionary dictionary, TKey key, TValue value) 8 | { 9 | if (dictionary.ContainsKey(key)) 10 | { 11 | dictionary[key] = value; 12 | } 13 | else 14 | { 15 | dictionary.Add(key, value); 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/CherrySeed.Test/Mocks/DictionaryDataProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CherrySeed.EntityDataProvider; 3 | 4 | namespace CherrySeed.Test.Mocks 5 | { 6 | public class DictionaryDataProvider : IDataProvider 7 | { 8 | private readonly List _entityData; 9 | 10 | public DictionaryDataProvider(List entityData) 11 | { 12 | _entityData = entityData; 13 | } 14 | 15 | public List GetEntityDataList() 16 | { 17 | return _entityData; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/CherrySeed.Test/Mocks/SequentialStringPrimaryKeyIdGenerator.cs: -------------------------------------------------------------------------------- 1 | using CherrySeed.PrimaryKeyIdGeneration; 2 | 3 | namespace CherrySeed.Test.Mocks 4 | { 5 | public class SequentialStringPrimaryKeyIdGenerator : IPrimaryKeyIdGenerator 6 | { 7 | private readonly string _prefix; 8 | private int _id = 0; 9 | 10 | public SequentialStringPrimaryKeyIdGenerator(string prefix) 11 | { 12 | _prefix = prefix; 13 | } 14 | 15 | public object Generate() 16 | { 17 | _id++; 18 | return _prefix + _id; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/CherrySeed/Configuration/CherrySeedConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CherrySeed.Configuration 4 | { 5 | public class CherrySeedConfiguration 6 | { 7 | private readonly Action _configurationExpression; 8 | 9 | public CherrySeedConfiguration(Action configurationExpression) 10 | { 11 | _configurationExpression = configurationExpression; 12 | } 13 | 14 | public ICherrySeeder CreateSeeder() 15 | { 16 | return new CherrySeeder(_configurationExpression); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/DataProviders.Csv/CsvDataProviderConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | 4 | namespace CherrySeed.DataProviders.Csv 5 | { 6 | public class CsvDataProviderConfiguration 7 | { 8 | public CsvDataProviderConfiguration() 9 | { 10 | Delimiter = ";"; 11 | CsvFilePaths = new List(); 12 | Encoding = Encoding.UTF8; 13 | } 14 | 15 | public string FolderPath { get; set; } 16 | public List CsvFilePaths { get; set; } 17 | public string Delimiter { get; set; } 18 | public Encoding Encoding { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /src/CherrySeed/PrimaryKeyIdGeneration/ApplicationGeneration/IntegerPrimaryKeyIdGenerator.cs: -------------------------------------------------------------------------------- 1 | namespace CherrySeed.PrimaryKeyIdGeneration.ApplicationGeneration 2 | { 3 | class IntegerPrimaryKeyIdGenerator : IPrimaryKeyIdGenerator 4 | { 5 | private int _id; 6 | private readonly int _steps; 7 | 8 | public IntegerPrimaryKeyIdGenerator(int startId, int steps) 9 | { 10 | _id = startId; 11 | _steps = steps; 12 | } 13 | 14 | public object Generate() 15 | { 16 | var result = _id; 17 | 18 | _id = _id + _steps; 19 | 20 | return result; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/CherrySeed.Test/Mocks/CustomTypeTransformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CherrySeed.TypeTransformations; 3 | 4 | namespace CherrySeed.Test.Mocks 5 | { 6 | public class CustomTypeTransformation : ITypeTransformation 7 | { 8 | private readonly T _newValue; 9 | 10 | public CustomTypeTransformation(T newValue) 11 | { 12 | _newValue = newValue; 13 | } 14 | 15 | public object Transform(Type type, string str) 16 | { 17 | return _newValue; 18 | } 19 | 20 | public object TransformNullable(Type type, string str) 21 | { 22 | return _newValue; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow.Test/Common/CherrySeedConfigurationExtensions.cs: -------------------------------------------------------------------------------- 1 | using CherrySeed.Configuration; 2 | using CherrySeed.DataProviders.SpecFlow.Test.Entities; 3 | 4 | namespace CherrySeed.DataProviders.SpecFlow.Test.Common 5 | { 6 | public static class CherrySeedConfigurationExtensions 7 | { 8 | public static void WithCountryAndProjectEntities(this ISeederConfigurationBuilder cfg) 9 | { 10 | cfg.ForEntity() 11 | .WithPrimaryKey(e => e.Id); 12 | 13 | cfg.ForEntity() 14 | .WithPrimaryKey(e => e.Id) 15 | .WithReference(e => e.CountryId, typeof(Country)); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/CherrySeed/EntitySettings/ReferenceSetting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using CherrySeed.Utils; 4 | 5 | namespace CherrySeed.EntitySettings 6 | { 7 | public class ReferenceSetting 8 | { 9 | public string ReferenceName { get; set; } 10 | public Type ReferenceType { get; set; } 11 | } 12 | 13 | public class ReferenceSetting : ReferenceSetting 14 | { 15 | public ReferenceSetting(Expression> referenceMember, 16 | Type referenceType) 17 | { 18 | ReferenceName = ReflectionUtil.GetMemberName(referenceMember); 19 | ReferenceType = referenceType; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow.Test/IntegrationTests/ProjectObjectMother.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TechTalk.SpecFlow; 3 | 4 | namespace CherrySeed.DataProviders.SpecFlow.Test.IntegrationTests 5 | { 6 | public class ObjectMother 7 | { 8 | public static Table CreateCountryTable(Action addDataFunc) 9 | { 10 | var table = new Table("Id", "Name"); 11 | addDataFunc(table); 12 | return table; 13 | } 14 | 15 | public static Table CreateProjectTable(Action
addDataFunc) 16 | { 17 | var table = new Table("Id", "Name", "CountryId"); 18 | addDataFunc(table); 19 | return table; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/CherrySeed.Test/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/CherrySeed/Configuration/Exceptions/ConfigurationException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CherrySeed.Configuration.Exceptions 4 | { 5 | public class ConfigurationException : Exception 6 | { 7 | public ConfigurationException(string message, Exception innerException) 8 | : base(message, innerException) 9 | { } 10 | } 11 | 12 | public class MissingConfigurationException : ConfigurationException 13 | { 14 | public MissingConfigurationException(string configurationKey) 15 | : base(string.Format("Configuration '{0}' is missing. Set with class CherrySeedConfiguration the required settings.", configurationKey), null) 16 | { 17 | 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/CherrySeed/EntitySettings/DefaultValueSetting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using CherrySeed.DefaultValues; 4 | using CherrySeed.Utils; 5 | 6 | namespace CherrySeed.EntitySettings 7 | { 8 | public class DefaultValueSetting 9 | { 10 | public string PropertyName { get; set; } 11 | public IDefaultValueProvider Provider { get; set; } 12 | } 13 | 14 | public class DefaultValueSetting : DefaultValueSetting 15 | { 16 | public DefaultValueSetting(Expression> fieldExpression, IDefaultValueProvider provider) 17 | { 18 | PropertyName = ReflectionUtil.GetMemberName(fieldExpression); 19 | Provider = provider; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/CherrySeed/CherrySeed.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $id$ 5 | $version$ 6 | $id$ 7 | $author$ 8 | $author$ 9 | https://github.com/altmann/CherrySeed 10 | 11 | https://raw.githubusercontent.com/altmann/CherrySeed/master/resources/logos/logo-withoutName-small.png 12 | false 13 | $description$ 14 | 15 | 16 | CherrySeed seed seeder dataseed database testdata 17 | 18 | -------------------------------------------------------------------------------- /src/CherrySeed/PrimaryKeyIdGeneration/ApplicationGeneration/StringPrimaryKeyIdGenerator.cs: -------------------------------------------------------------------------------- 1 | namespace CherrySeed.PrimaryKeyIdGeneration.ApplicationGeneration 2 | { 3 | class StringPrimaryKeyIdGenerator : IPrimaryKeyIdGenerator 4 | { 5 | private readonly string _prefix; 6 | private readonly IntegerPrimaryKeyIdGenerator _primaryKeyIdGenerator; 7 | 8 | public StringPrimaryKeyIdGenerator(string prefix, int startId, int steps) 9 | { 10 | _prefix = prefix; 11 | _primaryKeyIdGenerator = new IntegerPrimaryKeyIdGenerator(startId, steps); 12 | } 13 | 14 | public object Generate() 15 | { 16 | return $"{_prefix}{_primaryKeyIdGenerator.Generate()}"; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/CherrySeed/EntitySettings/EntitySetting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using CherrySeed.Repositories; 4 | 5 | namespace CherrySeed.EntitySettings 6 | { 7 | public class EntitySetting 8 | { 9 | public Type EntityType { get; set; } 10 | public PrimaryKeySetting PrimaryKey { get; set; } 11 | public List References { get; set; } 12 | public IRepository Repository { get; set; } 13 | public int Order { get; set; } 14 | public IdGenerationSetting IdGeneration { get; set; } 15 | public List EntityNames { get; set; } 16 | public Action AfterSave { get; set; } 17 | public List DefaultValueSettings { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow/CherrySeedExtensions.cs: -------------------------------------------------------------------------------- 1 | using CherrySeed.Configuration.Exceptions; 2 | using TechTalk.SpecFlow; 3 | 4 | namespace CherrySeed.DataProviders.SpecFlow 5 | { 6 | public static class CherrySeedExtensions 7 | { 8 | public static void Seed(this ICherrySeeder seeder, string entityName, Table table) 9 | { 10 | var cherrySeeder = seeder as CherrySeeder; 11 | var dataProvider = cherrySeeder.DataProvider as SpecFlowDataProvider; 12 | 13 | if (dataProvider == null) 14 | { 15 | throw new ConfigurationException("CherrySeed has an uncorrect SpecFlow configuration. Call method WithSpecFlowConfiguration() in the CherrySeed configuration section.", null); 16 | } 17 | 18 | dataProvider.ClearAndAdd(entityName, table); 19 | seeder.Seed(); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow.Test/IntegrationTests/EntityAsserts.cs: -------------------------------------------------------------------------------- 1 | using CherrySeed.DataProviders.SpecFlow.Test.Entities; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | 4 | namespace CherrySeed.DataProviders.SpecFlow.Test.IntegrationTests 5 | { 6 | public static class EntityAsserts 7 | { 8 | public static void AssertCountry(Country actual, Country expected) 9 | { 10 | Assert.IsNotNull(actual); 11 | Assert.AreEqual(expected.Id, actual.Id); 12 | Assert.AreEqual(expected.Name, actual.Name); 13 | } 14 | 15 | public static void AssertProject(Project actual, Project expected) 16 | { 17 | Assert.IsNotNull(actual); 18 | Assert.AreEqual(expected.Id, actual.Id); 19 | Assert.AreEqual(expected.Name, actual.Name); 20 | Assert.AreEqual(expected.CountryId, actual.CountryId); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Repositories.Ef/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/CherrySeed/TypeTransformations/StringTransformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CherrySeed.TypeTransformations 4 | { 5 | class StringTransformation : ITypeTransformation 6 | { 7 | private readonly string _emptyStringMarker; 8 | 9 | public StringTransformation(string emptyStringMarker) 10 | { 11 | _emptyStringMarker = emptyStringMarker; 12 | } 13 | 14 | public object Transform(Type type, string str) 15 | { 16 | if(string.IsNullOrEmpty(str)) 17 | return null; 18 | 19 | if (str == _emptyStringMarker) 20 | return ""; 21 | 22 | return str; 23 | } 24 | 25 | public object TransformNullable(Type type, string str) 26 | { 27 | // Not implemented because Nullable of string is not possible 28 | throw new NotImplementedException(); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/CherrySeed/ObjectTransformation/ObjectListTransformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using CherrySeed.EntitySettings; 5 | 6 | namespace CherrySeed.ObjectTransformation 7 | { 8 | class ObjectListTransformation 9 | { 10 | private readonly ObjectTransformation _objectTransformation; 11 | 12 | public ObjectListTransformation(ObjectTransformation objectTransformation) 13 | { 14 | _objectTransformation = objectTransformation; 15 | } 16 | 17 | public List Transform(Type type, List> inputObjects, EntitySetting entitySetting) 18 | { 19 | var inputObjectList = inputObjects 20 | .Select(inputObject => _objectTransformation.Transform(inputObject, type, entitySetting)) 21 | .ToList(); 22 | 23 | return inputObjectList; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/DataProviders.Csv/CherrySeed.DataProviders.Csv.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $id$ 5 | $version$ 6 | $id$ 7 | $author$ 8 | $author$ 9 | https://github.com/altmann/CherrySeed/wiki/CSV-Data-Provider 10 | https://raw.githubusercontent.com/altmann/CherrySeed/master/resources/logos/logo-withoutName-small.png 11 | 12 | 13 | 14 | 15 | 16 | false 17 | $description$ 18 | 19 | 20 | CherrySeed seed seeder dataseed database testdata csv 21 | 22 | -------------------------------------------------------------------------------- /src/DataProviders.Gherkin/CherrySeed.DataProviders.Gherkin.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $id$ 5 | $version$ 6 | $id$ 7 | $author$ 8 | $author$ 9 | https://github.com/altmann/CherrySeed/wiki/Gherkin-Data-Provider 10 | 11 | https://raw.githubusercontent.com/altmann/CherrySeed/master/resources/logos/logo-withoutName-small.png 12 | 13 | 14 | 15 | 16 | false 17 | $description$ 18 | 19 | 20 | CherrySeed seed seeder dataseed database testdata gherkin specflow 21 | 22 | -------------------------------------------------------------------------------- /src/Repositories.Ef/CherrySeed.Repositories.Ef.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $id$ 5 | $version$ 6 | $id$ 7 | $author$ 8 | $author$ 9 | https://github.com/altmann/CherrySeed/wiki/Entity-Framework-Repository 10 | 11 | https://raw.githubusercontent.com/altmann/CherrySeed/master/resources/logos/logo-withoutName-small.png 12 | 13 | 14 | 15 | 16 | false 17 | $description$ 18 | 19 | 20 | CherrySeed seed seeder dataseed database testdata entityframework 21 | 22 | -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow/CherrySeed.DataProviders.SpecFlow.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $id$ 5 | $version$ 6 | $id$ 7 | $author$ 8 | $author$ 9 | https://github.com/altmann/CherrySeed/wiki/SpecFlow-Data-Provider 10 | 11 | https://raw.githubusercontent.com/altmann/CherrySeed/master/resources/logos/logo-withoutName-small.png 12 | 13 | 14 | 15 | 16 | false 17 | $description$ 18 | 19 | 20 | CherrySeed seed seeder dataseed database testdata gherkin specflow 21 | 22 | -------------------------------------------------------------------------------- /src/DataProviders.Gherkin.Test/GherkinDataProviderTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CherrySeed.Configuration; 3 | using CherrySeed.DataProviders.Gherkin; 4 | using CherrySeed.Test.Base.Repositories; 5 | using Microsoft.VisualStudio.TestTools.UnitTesting; 6 | 7 | namespace DataProviders.Gherkin.Test 8 | { 9 | [TestClass] 10 | public class GherkinDataProviderTest 11 | { 12 | [TestMethod] 13 | public void DefaultTest() 14 | { 15 | var config = new CherrySeedConfiguration(cfg => 16 | { 17 | cfg.WithDataProvider(new GherkinDataProvider(new GherkinDataProviderConfiguration 18 | { 19 | FilePaths = new List { @"Testfeature.feature" } 20 | })); 21 | 22 | cfg.WithRepository(new EmptyRepository()); 23 | }); 24 | 25 | var seeder = config.CreateSeeder(); 26 | seeder.Seed(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/CherrySeed/Configuration/SeederConfigurationValidator.cs: -------------------------------------------------------------------------------- 1 | using CherrySeed.Configuration.Exceptions; 2 | 3 | namespace CherrySeed.Configuration 4 | { 5 | public class SeederConfigurationValidator 6 | { 7 | public void IsValid(SeederConfiguration configuration) 8 | { 9 | IsDataProviderValid(configuration); 10 | IsRepositoryValid(configuration); 11 | } 12 | 13 | private static void IsRepositoryValid(SeederConfiguration configuration) 14 | { 15 | if (configuration.DefaultRepository == null) 16 | { 17 | throw new MissingConfigurationException("Repository"); 18 | } 19 | } 20 | 21 | private static void IsDataProviderValid(SeederConfiguration configuration) 22 | { 23 | if (configuration.DataProvider == null) 24 | { 25 | throw new MissingConfigurationException("DataProvider"); 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/CherrySeed.Test/Infrastructure/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using CherrySeed.EntityDataProvider; 5 | using CherrySeed.EntitySettings; 6 | using CherrySeed.Test.Mocks; 7 | 8 | namespace CherrySeed.Test.Infrastructure 9 | { 10 | public static class Extensions 11 | { 12 | public static EntitySetting GetSetting(this List entitySettings) 13 | { 14 | var entityType = typeof (T); 15 | return entitySettings.First(es => es.EntityType == entityType); 16 | } 17 | 18 | public static Guid ToGuid(this int value) 19 | { 20 | byte[] bytes = new byte[16]; 21 | BitConverter.GetBytes(value).CopyTo(bytes, 0); 22 | return new Guid(bytes); 23 | } 24 | 25 | public static IDataProvider ToDictionaryDataProvider(this List entityDataList) 26 | { 27 | return new DictionaryDataProvider(entityDataList); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/CherrySeed/Configuration/SeederConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using CherrySeed.EntityDataProvider; 4 | using CherrySeed.EntitySettings; 5 | using CherrySeed.Repositories; 6 | using CherrySeed.TypeTransformations; 7 | 8 | namespace CherrySeed.Configuration 9 | { 10 | public class SeederConfiguration 11 | { 12 | public List EntitySettings { get; set; } 13 | public List DefaultPrimaryKeyNames { get; set; } 14 | public IRepository DefaultRepository { get; set; } 15 | public IdGenerationSetting DefaultIdGeneration { get; set; } 16 | public bool IsClearBeforeSeedingEnabled { get; set; } 17 | public Action, object> BeforeSaveAction { get; set; } 18 | public Action, object> AfterSaveAction { get; set; } 19 | public IDataProvider DataProvider { get; set; } 20 | public Dictionary TypeTransformations { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /src/CherrySeed.Test/Infrastructure/CherrySeedDriver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using CherrySeed.Configuration; 4 | using CherrySeed.EntityDataProvider; 5 | using CherrySeed.Repositories; 6 | using CherrySeed.Test.Mocks; 7 | 8 | namespace CherrySeed.Test.Infrastructure 9 | { 10 | public class CherrySeedDriver 11 | { 12 | private ICherrySeeder _cherrySeeder; 13 | 14 | public void InitAndSeed(IDataProvider dataProvider, IRepository repository, 15 | Action entitySettings) 16 | { 17 | var config = new CherrySeedConfiguration(cfg => 18 | { 19 | cfg.WithDataProvider(dataProvider); 20 | cfg.WithRepository(repository); 21 | 22 | entitySettings(cfg); 23 | }); 24 | 25 | _cherrySeeder = config.CreateSeeder(); 26 | _cherrySeeder.Seed(); 27 | } 28 | 29 | public void Clear() 30 | { 31 | _cherrySeeder.Clear(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow.Test/RealisticEnvironment/StepDefinitions/ProjectSteps.cs: -------------------------------------------------------------------------------- 1 | using TechTalk.SpecFlow; 2 | 3 | namespace CherrySeed.DataProviders.SpecFlow.Test.RealisticEnvironment.StepDefinitions 4 | { 5 | [Binding] 6 | public class ProjectSteps 7 | { 8 | private readonly ICherrySeeder _cherrySeeder; 9 | 10 | public ProjectSteps(ICherrySeeder cherrySeeder) 11 | { 12 | _cherrySeeder = cherrySeeder; 13 | } 14 | 15 | [Given(@"the following countries exist")] 16 | public void GivenTheFollowingEntriesOfCountryExist(Table table) 17 | { 18 | _cherrySeeder.Seed("Country", table); 19 | } 20 | 21 | [Given(@"the following projects exist")] 22 | public void GivenTheFollowingEntriesOfProjectExist(Table table) 23 | { 24 | _cherrySeeder.Seed("Project", table); 25 | } 26 | 27 | [BeforeScenario(Order = 2)] 28 | public void ClearData() 29 | { 30 | _cherrySeeder.Clear(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Repositories.Ef.Test/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/CherrySeed/EntitySettings/PrimaryKeySetting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using CherrySeed.Utils; 5 | 6 | namespace CherrySeed.EntitySettings 7 | { 8 | public class PrimaryKeySetting 9 | { 10 | //public List PrimaryKeyNames { get; set; } 11 | public string PrimaryKeyName { get; set; } 12 | 13 | public PrimaryKeySetting() 14 | { 15 | 16 | } 17 | 18 | //public PrimaryKeySetting(List primaryKeyNames) 19 | //{ 20 | // PrimaryKeyNames = primaryKeyNames; 21 | //} 22 | 23 | public PrimaryKeySetting(string primaryKeyName) 24 | { 25 | //PrimaryKeyNames = new List { primaryKeyName }; 26 | PrimaryKeyName = primaryKeyName; 27 | } 28 | } 29 | 30 | public class PrimaryKeySetting : PrimaryKeySetting 31 | { 32 | public PrimaryKeySetting(Expression> primaryKeyMember) 33 | : base(ReflectionUtil.GetMemberName(primaryKeyMember)) 34 | { } 35 | } 36 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Michael Altmann 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the "Software"), 5 | to deal in the Software without restriction, including without limitation the 6 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | sell copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow.Test/RealisticEnvironment/StepDefinitions/CherrySeedSupport.cs: -------------------------------------------------------------------------------- 1 | using BoDi; 2 | using CherrySeed.Configuration; 3 | using CherrySeed.DataProviders.SpecFlow.Test.Common; 4 | using CherrySeed.Test.Base.Repositories; 5 | using TechTalk.SpecFlow; 6 | 7 | namespace CherrySeed.DataProviders.SpecFlow.Test.RealisticEnvironment.StepDefinitions 8 | { 9 | [Binding] 10 | public class CherrySeedSupport 11 | { 12 | private readonly IObjectContainer _objectContainer; 13 | 14 | public CherrySeedSupport(IObjectContainer objectContainer) 15 | { 16 | _objectContainer = objectContainer; 17 | } 18 | 19 | [BeforeScenario(Order = 1)] 20 | public void InitializeCherrySeedDriver() 21 | { 22 | var cherrySeedConfig = new CherrySeedConfiguration(cfg => 23 | { 24 | cfg.WithSpecFlowConfiguration(); 25 | cfg.WithRepository(new EmptyRepository()); 26 | cfg.WithCountryAndProjectEntities(); 27 | }); 28 | var seeder = cherrySeedConfig.CreateSeeder(); 29 | _objectContainer.RegisterInstanceAs(seeder); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/CherrySeed/ObjectTransformation/PropertyTransformationException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CherrySeed.ObjectTransformation 4 | { 5 | public class PropertyTransformationException : Exception 6 | { 7 | public PropertyTransformationException(Type type, string propertyName, object propertyValue, Exception innerException) 8 | : base($"Transformation of Property '{propertyName}' of type '{type}' to value '{propertyValue}' failed", innerException) 9 | { } 10 | } 11 | 12 | public class PrimaryKeyException : Exception 13 | { 14 | public PrimaryKeyException(Type type, string propertyName, object propertyValue, Exception innerException) 15 | : base($"Setting primary key (property name = '{propertyName}') of type '{type}' to value '{propertyValue}' failed", innerException) 16 | { } 17 | } 18 | 19 | public class ForeignKeyException : Exception 20 | { 21 | public ForeignKeyException(Type type, string propertyName, object propertyValue, Exception innerException) 22 | : base($"Setting foreign key (property name = '{propertyName}') of type '{type}' to value '{propertyValue}' failed", innerException) 23 | { } 24 | } 25 | } -------------------------------------------------------------------------------- /src/CherrySeed/IdMappings/IdMappingProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace CherrySeed.IdMappings 6 | { 7 | class IdMappingProvider 8 | { 9 | private readonly Dictionary> _idMappingDict; 10 | 11 | public IdMappingProvider() 12 | { 13 | _idMappingDict = new Dictionary>(); 14 | } 15 | 16 | public void SetIdMapping(Type objectType, string providerId, object repositoryId) 17 | { 18 | var idMapping = new IdMappingDescription {ProviderId = providerId, RepositoryId = repositoryId}; 19 | 20 | if (_idMappingDict.ContainsKey(objectType)) 21 | { 22 | _idMappingDict[objectType].Add(idMapping); 23 | } 24 | else 25 | { 26 | _idMappingDict.Add(objectType, new List 27 | { 28 | idMapping 29 | }); 30 | } 31 | } 32 | 33 | public object GetRepositoryId(Type objectType, string providerId) 34 | { 35 | return _idMappingDict[objectType].Where(idMapping => idMapping.ProviderId == providerId).Select(idMapping => idMapping.RepositoryId).First(); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/CherrySeed/TypeTransformations/TypeTransformationProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using CherrySeed.Utils; 4 | 5 | namespace CherrySeed.TypeTransformations 6 | { 7 | class TypeTransformationProvider 8 | { 9 | private readonly Dictionary _simpleTypeTransformations; 10 | 11 | public TypeTransformationProvider(Dictionary simpleTypeTransformations) 12 | { 13 | _simpleTypeTransformations = simpleTypeTransformations; 14 | } 15 | 16 | public ITypeTransformation GetSimpleTransformation(Type type) 17 | { 18 | var relevantType = GetRelevantType(type); 19 | var lookupType = relevantType.IsEnum 20 | ? typeof(Enum) 21 | : relevantType; 22 | 23 | if (!_simpleTypeTransformations.ContainsKey(lookupType)) 24 | { 25 | throw new NotSupportedException($"Transformation of type '{type}' is currently not supported"); 26 | } 27 | 28 | return _simpleTypeTransformations[lookupType]; 29 | } 30 | 31 | private Type GetRelevantType(Type type) 32 | { 33 | if (ReflectionUtil.IsNullableValueType(type)) 34 | return type.GetGenericArguments()[0]; 35 | 36 | return type; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow/SpecFlowDataProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using CherrySeed.EntityDataProvider; 4 | using TechTalk.SpecFlow; 5 | 6 | namespace CherrySeed.DataProviders.SpecFlow 7 | { 8 | class SpecFlowDataProvider : IDataProvider 9 | { 10 | private List _entityDataList; 11 | 12 | public SpecFlowDataProvider() 13 | { 14 | _entityDataList = new List(); 15 | } 16 | 17 | public void ClearAndAdd(string entityName, Table table) 18 | { 19 | _entityDataList = TransformTableToEntityData(entityName, table); 20 | } 21 | 22 | private List TransformTableToEntityData(string entityName, Table table) 23 | { 24 | return new List 25 | { 26 | new EntityData 27 | { 28 | EntityName = entityName, 29 | Objects = table.Rows 30 | .Select(r => r.ToDictionary( 31 | instance => instance.Key, 32 | instance => instance.Value) 33 | ).ToList() 34 | } 35 | }; 36 | } 37 | 38 | public List GetEntityDataList() 39 | { 40 | return _entityDataList; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/Repositories.Ef/EfRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Entity; 3 | 4 | namespace CherrySeed.Repositories.Ef 5 | { 6 | public class EfRepository : IRepository 7 | { 8 | private readonly Func _createDbContextFunc; 9 | 10 | public EfRepository(Func createDbContextFunc) 11 | { 12 | _createDbContextFunc = createDbContextFunc; 13 | } 14 | 15 | public void SaveEntity(object obj) 16 | { 17 | using (var dbContext = _createDbContextFunc()) 18 | { 19 | dbContext.Entry(obj).State = EntityState.Added; 20 | dbContext.SaveChanges(); 21 | } 22 | } 23 | 24 | public void RemoveEntities(Type type) 25 | { 26 | using (var dbContext = _createDbContextFunc()) 27 | { 28 | dbContext.Set(type).Load(); 29 | 30 | foreach (var obj in dbContext.Set(type)) 31 | { 32 | dbContext.Entry(obj).State = EntityState.Deleted; 33 | } 34 | 35 | dbContext.SaveChanges(); 36 | } 37 | } 38 | 39 | public object LoadEntity(Type type, object id) 40 | { 41 | using (var dbContext = _createDbContextFunc()) 42 | { 43 | return dbContext.Set(type).Find(id); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/CherrySeed/Configuration/ISeederConfigurationBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using CherrySeed.EntityDataProvider; 4 | using CherrySeed.EntitySettings; 5 | using CherrySeed.PrimaryKeyIdGeneration; 6 | using CherrySeed.Repositories; 7 | using CherrySeed.TypeTransformations; 8 | 9 | namespace CherrySeed.Configuration 10 | { 11 | public interface ISeederConfigurationBuilder 12 | { 13 | IEntitySettingBuilder ForEntity(); 14 | void WithDataProvider(IDataProvider dataProvider); 15 | void AddTypeTransformation(Type type, ITypeTransformation transformation); 16 | void WithDefaultPrimaryKeyNames(params string[] primaryKeyNames); 17 | void WithRepository(IRepository repository); 18 | void DisableClearBeforeSeeding(); 19 | void BeforeSave(Action, object> beforeSaveAction); 20 | void AfterSave(Action, object> afterSaveAction); 21 | void DisablePrimaryKeyIdGeneration(); 22 | void WithPrimaryKeyIdGenerationInApplicationAsInteger(int startId = 1, int steps = 1); 23 | void WithPrimaryKeyIdGenerationInApplicationAsGuid(); 24 | void WithPrimaryKeyIdGenerationInApplicationAsString(string prefix = "", int startId = 1, int steps = 1); 25 | void WithCustomPrimaryKeyIdGenerationInApplication(IPrimaryKeyIdGenerator generator); 26 | void WithEmptyStringMarker(string marker); 27 | } 28 | } -------------------------------------------------------------------------------- /src/DataProviders.Csv/CsvDataProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using CherrySeed.EntityDataProvider; 6 | 7 | namespace CherrySeed.DataProviders.Csv 8 | { 9 | public class CsvDataProvider : IDataProvider 10 | { 11 | private readonly CsvDataProviderConfiguration _configuration; 12 | 13 | public CsvDataProvider(CsvDataProviderConfiguration configuration) 14 | { 15 | _configuration = configuration; 16 | } 17 | 18 | public List GetEntityDataList() 19 | { 20 | var csvFilePaths = GetCsvFilePaths(); 21 | 22 | return csvFilePaths 23 | .Select(csvFilePath => new CsvFile(csvFilePath, _configuration.Delimiter, _configuration.Encoding).ReadFile()) 24 | .ToList(); 25 | } 26 | 27 | private IEnumerable GetCsvFilePaths() 28 | { 29 | if (_configuration.FolderPath != null) 30 | { 31 | return Directory.GetFiles(_configuration.FolderPath, "*.csv").ToList(); 32 | } 33 | 34 | foreach (var csvFilePath in _configuration.CsvFilePaths) 35 | { 36 | if(!File.Exists(csvFilePath)) 37 | throw new InvalidOperationException($"File not found {csvFilePath}"); 38 | } 39 | 40 | return _configuration.CsvFilePaths; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/CherrySeed.Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CherrySeed.Test")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CherrySeed.Test")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("2ee25dc0-d03c-4433-97e3-0704139c63f9")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/CherrySeed/ObjectTransformation/PropertyHandlers/PrimaryKeyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CherrySeed.EntitySettings; 3 | using CherrySeed.Utils; 4 | 5 | namespace CherrySeed.ObjectTransformation.PropertyHandlers 6 | { 7 | class PrimaryKeyHandler : IPropertyHandler 8 | { 9 | public static bool CanHandle(string propertyName, EntitySetting entitySetting) 10 | { 11 | var isPrimaryKey = propertyName == entitySetting.PrimaryKey.PrimaryKeyName; 12 | 13 | // property should be primary key 14 | if (!isPrimaryKey) 15 | return false; 16 | 17 | // generator should be enabled 18 | if (!entitySetting.IdGeneration.IsGeneratorEnabled) 19 | return false; 20 | 21 | // database generator should be disabled 22 | if (entitySetting.IdGeneration.IsDatabaseGenerationEnabled) 23 | return false; 24 | 25 | return true; 26 | } 27 | 28 | public void Handle(object obj, string propertyName, string propertyValue, EntitySetting entitySetting) 29 | { 30 | object primaryKeyId = null; 31 | 32 | try 33 | { 34 | primaryKeyId = entitySetting.IdGeneration.Generator.Generator.Generate(); 35 | ReflectionUtil.SetProperty(obj, propertyName, primaryKeyId); 36 | } 37 | catch (Exception ex) 38 | { 39 | throw new PrimaryKeyException(obj.GetType(), propertyName, primaryKeyId, ex); 40 | } 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/CherrySeed.Test.Base/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CherrySeed.Test.Base")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CherrySeed.Test.Base")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("b2a5444d-82b9-410d-bb85-39951972ebb6")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/Repositories.Ef.Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Repositories.Ef.Test")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Repositories.Ef.Test")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("582e1ba4-bf43-4174-9315-3556ee3059e2")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/DataProviders.Csv.Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DataProviders.Csv.Test")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DataProviders.Csv.Test")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0fa87c7f-ba21-46e0-914e-a0712479731a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/DataProviders.Gherkin.Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DataProviders.Gherkin.Test")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DataProviders.Gherkin.Test")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("54e0f0aa-2273-49b6-a91a-9c9a4e2400b2")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/CherrySeed/ObjectTransformation/PropertyHandlers/PropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using CherrySeed.EntitySettings; 4 | using CherrySeed.IdMappings; 5 | using CherrySeed.TypeTransformations; 6 | 7 | namespace CherrySeed.ObjectTransformation.PropertyHandlers 8 | { 9 | class PropertyHandler 10 | { 11 | private readonly Dictionary, IPropertyHandler> _strategyDictionary; 12 | 13 | public PropertyHandler(IdMappingProvider idMappingProvider, TypeTransformationProvider typeTransformationProvider) 14 | { 15 | _strategyDictionary = new Dictionary, IPropertyHandler> 16 | { 17 | { PrimaryKeyHandler.CanHandle, new PrimaryKeyHandler() }, 18 | { ForeignKeyHandler.CanHandle, new ForeignKeyHandler(idMappingProvider) }, 19 | { CopyPropertyValueHandler.CanHandle, new CopyPropertyValueHandler(typeTransformationProvider) } 20 | }; 21 | } 22 | 23 | public void SetProperty(object obj, string propertyName, string propertyValue, EntitySetting entitySetting) 24 | { 25 | foreach (var propertyHandlerPair in _strategyDictionary) 26 | { 27 | var x = propertyHandlerPair.Key(propertyName, entitySetting); 28 | 29 | if (x) 30 | { 31 | propertyHandlerPair.Value.Handle(obj, propertyName, propertyValue, entitySetting); 32 | return; 33 | } 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow.Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DataProviders.SpecFlow.Test")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DataProviders.SpecFlow.Test")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8b359543-174e-4f52-92fc-02478ee7a05d")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/CherrySeed/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CherrySeed")] 9 | [assembly: AssemblyDescription("Seeding data from any source to any destination")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Michael Altmann")] 12 | [assembly: AssemblyProduct("CherrySeed")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f40a4d24-2e1d-4c23-9c06-e22c11c43a3c")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.0.0")] 36 | [assembly: AssemblyFileVersion("1.1.0.0")] 37 | -------------------------------------------------------------------------------- /src/DataProviders.Csv/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CherrySeed.DataProviders.Csv")] 9 | [assembly: AssemblyDescription("CSV Data Provider for CherrySeed")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Michael Altmann")] 12 | [assembly: AssemblyProduct("CherrySeed.DataProviders.Csv")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("d918620a-a15d-4ae2-a416-5a55bb189cd4")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.1.0")] 36 | [assembly: AssemblyFileVersion("1.0.1.0")] 37 | -------------------------------------------------------------------------------- /src/Repositories.Ef/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CherrySeed.Repositories.Ef")] 9 | [assembly: AssemblyDescription("Entity Framework Repository for CherrySeed")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Michael Altmann")] 12 | [assembly: AssemblyProduct("CherrySeed.Repositories.Ef")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("bb9996ec-f815-4aa3-b83a-17bafa66d690")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.1.0")] 36 | [assembly: AssemblyFileVersion("1.0.1.0")] 37 | -------------------------------------------------------------------------------- /src/DataProviders.Gherkin/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CherrySeed.DataProviders.Gherkin")] 9 | [assembly: AssemblyDescription("Gherkin Data Provider for CherrySeed")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Michael Altmann")] 12 | [assembly: AssemblyProduct("CherrySeed.DataProviders.Gherkin")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("40ba2b6d-3897-481b-aff1-77bdb454a533")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CherrySeed.DataProviders.SpecFlow")] 9 | [assembly: AssemblyDescription("SpecFlow Data Provider for CherrySeed")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Michael Altmann")] 12 | [assembly: AssemblyProduct("CherrySeed.DataProviders.SpecFlow")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("b4f2b2ad-c49d-46dd-b3ab-ad25225326a3")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/CherrySeed.Test/Infrastructure/EntityDataBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CherrySeed.EntityDataProvider; 3 | 4 | namespace CherrySeed.Test.Infrastructure 5 | { 6 | public class EntityDataBuilder 7 | { 8 | private readonly string _entityName; 9 | private readonly string[] _propertyNames; 10 | private readonly List _entities; 11 | 12 | public EntityDataBuilder(string entityName, params string[] propertyNames) 13 | { 14 | _entityName = entityName; 15 | _propertyNames = propertyNames; 16 | _entities = new List(); 17 | } 18 | 19 | public EntityDataBuilder WithEntity(params string[] data) 20 | { 21 | _entities.Add(data); 22 | return this; 23 | } 24 | 25 | public EntityData Build() 26 | { 27 | return new EntityData 28 | { 29 | EntityName = _entityName, 30 | Objects = CreateObjectDictionaryList() 31 | }; 32 | } 33 | 34 | private List> CreateObjectDictionaryList() 35 | { 36 | var result = new List>(); 37 | 38 | foreach (var entityStringArray in _entities) 39 | { 40 | var objectDict = new Dictionary(); 41 | 42 | for (int i = 0; i < _propertyNames.Length; i++) 43 | { 44 | objectDict.Add(_propertyNames[i], entityStringArray[i]); 45 | } 46 | 47 | result.Add(objectDict); 48 | } 49 | 50 | return result; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /src/CherrySeed/ObjectTransformation/ObjectTransformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using CherrySeed.EntitySettings; 4 | using CherrySeed.ObjectTransformation.PropertyHandlers; 5 | using CherrySeed.Utils; 6 | 7 | namespace CherrySeed.ObjectTransformation 8 | { 9 | class ObjectTransformation 10 | { 11 | private readonly PropertyHandler _propertyHandler; 12 | 13 | public ObjectTransformation(PropertyHandler propertyHandler) 14 | { 15 | _propertyHandler = propertyHandler; 16 | } 17 | 18 | public object Transform(Dictionary inputDictionary, Type outputType, EntitySetting entitySetting) 19 | { 20 | var outputObject = Activator.CreateInstance(outputType); 21 | 22 | // Set default values 23 | foreach (var defaultValueSetting in entitySetting.DefaultValueSettings) 24 | { 25 | var propertyName = defaultValueSetting.PropertyName; 26 | var defaultValueProvider = defaultValueSetting.Provider; 27 | var defaultValue = defaultValueProvider.GetDefaultValue(); 28 | 29 | ReflectionUtil.SetProperty(outputObject, propertyName, defaultValue); 30 | } 31 | 32 | // Set values from data provider 33 | foreach (var inputKeyValuePair in inputDictionary) 34 | { 35 | var propertyName = inputKeyValuePair.Key; 36 | var propertyValue = inputKeyValuePair.Value; 37 | 38 | _propertyHandler.SetProperty(outputObject, propertyName, propertyValue, entitySetting); 39 | } 40 | 41 | return outputObject; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/CherrySeed.Test.Base/Asserts/AssertHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | 4 | namespace CherrySeed.Test.Base.Asserts 5 | { 6 | public static class AssertHelper 7 | { 8 | public static void AssertIf(Type shouldEntityType, int shouldCount, int actualCount, object obj, Action action) 9 | { 10 | if (!(obj.GetType() == shouldEntityType)) 11 | { 12 | return; 13 | } 14 | 15 | if (shouldCount != actualCount) 16 | { 17 | return; 18 | } 19 | 20 | action(); 21 | } 22 | 23 | public static void AssertExceptionWithMessage(Exception actualException, Type expectedException, 24 | string expectedMessage) 25 | { 26 | Assert.AreEqual(expectedException, actualException.GetType(), "Asset: Expected exception is not actual exception"); 27 | Assert.IsTrue(actualException.Message.Contains(expectedMessage), "Asset: Expected exception message is not actual exception message"); 28 | } 29 | 30 | public static void AssertException(Exception actualException, Type expectedException) 31 | { 32 | Assert.AreEqual(expectedException, actualException.GetType(), "Asset: Expected exception is not actual exception"); 33 | } 34 | 35 | public static void TryCatch(Action tryAction, Action catchAction) 36 | { 37 | try 38 | { 39 | tryAction(); 40 | Assert.Fail("Expected exception was not thrown."); 41 | } 42 | catch (Exception ex) 43 | { 44 | catchAction(ex); 45 | } 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /src/CherrySeed.Test/IntegrationTests/ConfigurationValidationTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using CherrySeed.Configuration; 4 | using CherrySeed.Configuration.Exceptions; 5 | using CherrySeed.EntityDataProvider; 6 | using CherrySeed.Test.Base.Asserts; 7 | using CherrySeed.Test.Base.Repositories; 8 | using CherrySeed.Test.Mocks; 9 | using Microsoft.VisualStudio.TestTools.UnitTesting; 10 | 11 | namespace CherrySeed.Test.IntegrationTests 12 | { 13 | [TestClass] 14 | public class ConfigurationValidationTests 15 | { 16 | [TestMethod] 17 | public void DataProviderNotSet_MissingConfigurationException() 18 | { 19 | AssertHelper.TryCatch(tryAction: () => 20 | { 21 | var config = new CherrySeedConfiguration(cfg => 22 | { 23 | cfg.WithRepository(new EmptyRepository()); 24 | }); 25 | 26 | config.CreateSeeder(); 27 | }, catchAction: ex => 28 | { 29 | AssertHelper.AssertExceptionWithMessage(ex, typeof(MissingConfigurationException), "DataProvider"); 30 | }); 31 | } 32 | 33 | [TestMethod] 34 | public void RepositoryNotSet_MissingConfigurationException() 35 | { 36 | AssertHelper.TryCatch(tryAction: () => 37 | { 38 | var config = new CherrySeedConfiguration(cfg => 39 | { 40 | cfg.WithDataProvider(new DictionaryDataProvider(new List())); 41 | }); 42 | 43 | config.CreateSeeder(); 44 | }, catchAction: ex => 45 | { 46 | AssertHelper.AssertExceptionWithMessage(ex, typeof(MissingConfigurationException), "Repository"); 47 | }); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CherrySeed 2 | 3 | # What is CherrySeed? 4 | CherrySeed is a simple .NET library built to solve a common problem - creating and seeding test data into the database. This type of code is boring to write and bringing relations under control is hard, so why not use a library for that? 5 | 6 | # Why use CherrySeed? 7 | - Bring relations between entities under control with an easy-to-use API 8 | - High separation of concerns 9 | - Data providers (defining test data via csv, json, xml, etc.) 10 | - Repository (storing test data via O/R mapping framework of your choice) 11 | - Some ready-to-use data providers and repositories 12 | - High extensibility 13 | - Custom data providers 14 | - Custom repositories 15 | - Custom type transformations 16 | - Extension points 17 | - Many types are supported out of the box (integer, string, enum, nullable types, etc.) 18 | 19 | # How do I use CherrySeed? 20 | 21 | var config = new CherrySeedConfiguration(cfg => 22 | { 23 | // set data provider 24 | cfg.WithDataProvider(new CsvDataProvider()); 25 | 26 | // set repository 27 | cfg.WithGlobalRepository(new EfRepository()); 28 | 29 | // set entity specific settings 30 | cfg.ForEntity() 31 | .WithPrimaryKey(e => e.Identification); 32 | }); 33 | 34 | var cherrySeeder = config.CreateSeeder(); 35 | cherrySeeder.Seed(); 36 | 37 | More see in [Getting Started](https://github.com/altmann/CherrySeed/wiki/Getting-Started). 38 | 39 | # Resources 40 | - [Install via NuGet](https://www.nuget.org/packages?q=CherrySeed) 41 | - [Documentation](https://github.com/altmann/CherrySeed/wiki/Getting-Started) 42 | 43 | # Copyright 44 | 45 | Copyright (c) Michael Altmann. See [LICENSE](https://raw.githubusercontent.com/altmann/CherrySeed/master/LICENSE) for details. 46 | -------------------------------------------------------------------------------- /src/CherrySeed/ObjectTransformation/PropertyHandlers/ForeignKeyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using CherrySeed.EntitySettings; 4 | using CherrySeed.IdMappings; 5 | using CherrySeed.Utils; 6 | 7 | namespace CherrySeed.ObjectTransformation.PropertyHandlers 8 | { 9 | class ForeignKeyHandler : IPropertyHandler 10 | { 11 | private readonly IdMappingProvider _idMappingProvider; 12 | 13 | public ForeignKeyHandler(IdMappingProvider idMappingProvider) 14 | { 15 | _idMappingProvider = idMappingProvider; 16 | } 17 | 18 | public static bool CanHandle(string propertyName, EntitySetting entitySetting) 19 | { 20 | return entitySetting.References.Select(rd => rd.ReferenceName).Contains(propertyName); 21 | } 22 | 23 | public void Handle(object obj, string propertyName, string propertyValue, EntitySetting entitySetting) 24 | { 25 | try 26 | { 27 | var propertyType = ReflectionUtil.GetPropertyType(obj.GetType(), propertyName); 28 | 29 | var referenceSetting = entitySetting.References.First(rd => rd.ReferenceName == propertyName); 30 | var foreignKeyId = _idMappingProvider.GetRepositoryId(referenceSetting.ReferenceType, propertyValue); 31 | 32 | if (ReflectionUtil.IsReferenceType(propertyType)) 33 | { 34 | var referenceModel = entitySetting.Repository.LoadEntity(propertyType, foreignKeyId); 35 | ReflectionUtil.SetProperty(obj, propertyName, referenceModel); 36 | } 37 | else 38 | { 39 | ReflectionUtil.SetProperty(obj, propertyName, foreignKeyId); 40 | } 41 | } 42 | catch (Exception ex) 43 | { 44 | throw new ForeignKeyException(obj.GetType(), propertyName, propertyValue, ex); 45 | } 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /src/DataProviders.Csv/CsvFile.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Text; 4 | using CherrySeed.EntityDataProvider; 5 | using CsvHelper; 6 | using CsvHelper.Configuration; 7 | 8 | namespace CherrySeed.DataProviders.Csv 9 | { 10 | class CsvFile 11 | { 12 | private readonly string _filePath; 13 | private readonly string _delimiter; 14 | private readonly Encoding _encoding; 15 | 16 | public CsvFile(string filePath, string delimiter, Encoding encoding) 17 | { 18 | _filePath = filePath; 19 | _delimiter = delimiter; 20 | _encoding = encoding; 21 | } 22 | 23 | public string FileName => Path.GetFileNameWithoutExtension(_filePath); 24 | 25 | public EntityData ReadFile() 26 | { 27 | return new EntityData 28 | { 29 | EntityName = FileName, 30 | Objects = ReadDataFromFile() 31 | }; 32 | } 33 | 34 | private List> ReadDataFromFile() 35 | { 36 | var textReader = File.OpenText(_filePath); 37 | var csvReader = new CsvReader(textReader, new CsvConfiguration 38 | { 39 | Delimiter = _delimiter, 40 | Encoding = _encoding 41 | }); 42 | 43 | var entityDicts = new List>(); 44 | while (csvReader.Read()) 45 | { 46 | var fieldNames = csvReader.FieldHeaders; 47 | 48 | // read one row 49 | var entityDict = new Dictionary(); 50 | 51 | foreach (var fieldName in fieldNames) 52 | { 53 | var fieldValue = csvReader.GetField(fieldName); 54 | entityDict.Add(fieldName, fieldValue); 55 | } 56 | 57 | entityDicts.Add(entityDict); 58 | } 59 | 60 | return entityDicts; 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /src/CherrySeed/ObjectTransformation/PropertyHandlers/CopyPropertyValueHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CherrySeed.EntitySettings; 3 | using CherrySeed.TypeTransformations; 4 | using CherrySeed.Utils; 5 | 6 | namespace CherrySeed.ObjectTransformation.PropertyHandlers 7 | { 8 | class CopyPropertyValueHandler : IPropertyHandler 9 | { 10 | private readonly TypeTransformationProvider _typeTransformationProvider; 11 | 12 | public CopyPropertyValueHandler(TypeTransformationProvider typeTransformationProvider) 13 | { 14 | _typeTransformationProvider = typeTransformationProvider; 15 | } 16 | 17 | public static bool CanHandle(string propertyName, EntitySetting entitySetting) 18 | { 19 | var isPrimaryKey = propertyName == entitySetting.PrimaryKey.PrimaryKeyName; 20 | 21 | if (isPrimaryKey && entitySetting.IdGeneration.IsGeneratorEnabled) 22 | return false; 23 | 24 | if (isPrimaryKey && entitySetting.IdGeneration.IsDatabaseGenerationEnabled) 25 | return false; 26 | 27 | return true; 28 | } 29 | 30 | public void Handle(object obj, string propertyName, string propertyValue, EntitySetting entitySetting) 31 | { 32 | try 33 | { 34 | var propertyType = ReflectionUtil.GetPropertyType(obj.GetType(), propertyName); 35 | var simpleTransformation = _typeTransformationProvider.GetSimpleTransformation(propertyType); 36 | 37 | var typedPropertyValue = ReflectionUtil.IsNullableValueType(propertyType) 38 | ? simpleTransformation.TransformNullable(propertyType, propertyValue) 39 | : simpleTransformation.Transform(propertyType, propertyValue); 40 | 41 | ReflectionUtil.SetProperty(obj, propertyName, typedPropertyValue); 42 | } 43 | catch (Exception ex) 44 | { 45 | throw new PropertyTransformationException(obj.GetType(), propertyName, propertyValue, ex); 46 | } 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /src/DataProviders.Csv.Test/CsvDataProviderTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CherrySeed.DataProviders.Csv; 3 | using DataProviders.Csv.Test.Asserts; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | 6 | namespace DataProviders.Csv.Test 7 | { 8 | [TestClass] 9 | public class CsvDataProviderTest 10 | { 11 | [TestMethod] 12 | public void ReadCsvsFromDictionary() 13 | { 14 | var csvDataProvider = new CsvDataProvider(new CsvDataProviderConfiguration 15 | { 16 | FolderPath = "./CsvFiles" 17 | }); 18 | var entityDataList = csvDataProvider.GetEntityDataList(); 19 | 20 | Assert.IsNotNull(entityDataList); 21 | 22 | var entityDataComplex = entityDataList[0]; 23 | MyAssert.AssertComplex(entityDataComplex); 24 | 25 | var entityDataSimple = entityDataList[1]; 26 | MyAssert.AssertSimple(entityDataSimple); 27 | } 28 | 29 | [TestMethod] 30 | public void ReadSimpleCsvFile() 31 | { 32 | var csvDataProvider = new CsvDataProvider(new CsvDataProviderConfiguration 33 | { 34 | CsvFilePaths = new List { "./CsvFiles/Simple.csv" } 35 | }); 36 | var entityDataList = csvDataProvider.GetEntityDataList(); 37 | 38 | Assert.IsNotNull(entityDataList); 39 | 40 | var entityDataSimple = entityDataList[0]; 41 | MyAssert.AssertSimple(entityDataSimple); 42 | } 43 | 44 | [TestMethod] 45 | public void ReadSimpleEmptyCsvFile() 46 | { 47 | var csvDataProvider = new CsvDataProvider(new CsvDataProviderConfiguration 48 | { 49 | CsvFilePaths = new List { "./CsvFiles/SimpleEmpty.csv" } 50 | }); 51 | var entityDataList = csvDataProvider.GetEntityDataList(); 52 | 53 | Assert.IsNotNull(entityDataList); 54 | 55 | var entityDataSimple = entityDataList[0]; 56 | MyAssert.AssertSimpleEmpty(entityDataSimple); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/CherrySeed.Test/IntegrationTests/ProgressActionTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using CherrySeed.EntityDataProvider; 5 | using CherrySeed.Test.Asserts; 6 | using CherrySeed.Test.Base.Repositories; 7 | using CherrySeed.Test.Infrastructure; 8 | using CherrySeed.Test.Models; 9 | using Microsoft.VisualStudio.TestTools.UnitTesting; 10 | 11 | namespace CherrySeed.Test.IntegrationTests 12 | { 13 | [TestClass] 14 | public class ProgressActionTests 15 | { 16 | private CherrySeedDriver _cherrySeedDriver; 17 | 18 | [TestInitialize] 19 | public void Setup() 20 | { 21 | _cherrySeedDriver = new CherrySeedDriver(); 22 | } 23 | 24 | [TestMethod] 25 | public void SetGlobalAndEntitySpecificActions() 26 | { 27 | // Arrange 28 | var entityData = new List 29 | { 30 | new EntityDataBuilder("CherrySeed.Test.Models.EntityWithSimpleProperties", 31 | "MyInteger", "MyString") 32 | .WithEntity("1", "MyString 1") 33 | .Build() 34 | }; 35 | 36 | var globalBeforeSaveCallCounter = 0; 37 | var globalAfterSaveCallCounter = 0; 38 | var entityAfterSaveCallCounter = 0; 39 | 40 | // Act 41 | var repository = new InMemoryRepository(); 42 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 43 | { 44 | cfg.BeforeSave((dictionary, o) => 45 | { 46 | globalBeforeSaveCallCounter++; 47 | }); 48 | 49 | cfg.AfterSave(((dictionary, o) => 50 | { 51 | globalAfterSaveCallCounter++; 52 | })); 53 | 54 | cfg.ForEntity() 55 | .AfterSave((o => 56 | { 57 | entityAfterSaveCallCounter++; 58 | })); 59 | }); 60 | 61 | // Assert 62 | Assert.AreEqual(1, globalBeforeSaveCallCounter); 63 | Assert.AreEqual(1, globalAfterSaveCallCounter); 64 | Assert.AreEqual(1, entityAfterSaveCallCounter); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /src/DataProviders.Gherkin/GherkinDataProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using CherrySeed.EntityDataProvider; 4 | using Gherkin; 5 | using Gherkin.Ast; 6 | 7 | namespace CherrySeed.DataProviders.Gherkin 8 | { 9 | public class GherkinDataProvider : IDataProvider 10 | { 11 | private readonly GherkinDataProviderConfiguration _config; 12 | 13 | public GherkinDataProvider(GherkinDataProviderConfiguration config) 14 | { 15 | _config = config; 16 | } 17 | 18 | public List GetEntityDataList() 19 | { 20 | var entities = new List(); 21 | 22 | foreach (var filePath in _config.FilePaths) 23 | { 24 | var parser = new Parser(); 25 | var gherkinDocument = parser.Parse(filePath); 26 | 27 | foreach (var scenarioDefinition in gherkinDocument.Feature.Children) 28 | { 29 | foreach (var step in scenarioDefinition.Steps) 30 | { 31 | var entityName = step.Text.Split('\'')[1]; 32 | var dataTable = step.Argument as DataTable; 33 | var entityDicts = new List>(); 34 | 35 | foreach (var row in dataTable.Rows.Skip(1)) 36 | { 37 | var entityDict = TransformEntity(row, dataTable); 38 | entityDicts.Add(entityDict); 39 | } 40 | 41 | entities.Add(new EntityData 42 | { 43 | EntityName = entityName, 44 | Objects = entityDicts 45 | }); 46 | } 47 | } 48 | } 49 | 50 | return entities; 51 | } 52 | 53 | private static Dictionary TransformEntity(TableRow row, DataTable dataTable) 54 | { 55 | var entityDict = new Dictionary(); 56 | 57 | for (var i = 0; i < row.Cells.Count(); i++) 58 | { 59 | var cell = row.Cells.ToList()[i]; 60 | entityDict.Add(dataTable.Rows.First().Cells.ToList()[i].Value, cell.Value); 61 | } 62 | return entityDict; 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /src/DataProviders.Csv.Test/Asserts/MyAssert.cs: -------------------------------------------------------------------------------- 1 | using CherrySeed.EntityDataProvider; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | 4 | namespace DataProviders.Csv.Test.Asserts 5 | { 6 | public static class MyAssert 7 | { 8 | public static void AssertSimple(EntityData entityData) 9 | { 10 | Assert.AreEqual("Simple", entityData.EntityName); 11 | Assert.AreEqual(2, entityData.Objects.Count); 12 | 13 | Assert.AreEqual(3, entityData.Objects[0].Count); 14 | Assert.AreEqual("1", entityData.Objects[0]["Field1"]); 15 | Assert.AreEqual("2", entityData.Objects[0]["Field2"]); 16 | Assert.AreEqual("3", entityData.Objects[0]["Field3"]); 17 | 18 | Assert.AreEqual(3, entityData.Objects[1].Count); 19 | Assert.AreEqual("4", entityData.Objects[1]["Field1"]); 20 | Assert.AreEqual("5", entityData.Objects[1]["Field2"]); 21 | Assert.AreEqual("6", entityData.Objects[1]["Field3"]); 22 | } 23 | 24 | public static void AssertSimpleEmpty(EntityData entityData) 25 | { 26 | Assert.AreEqual("SimpleEmpty", entityData.EntityName); 27 | Assert.AreEqual("", entityData.Objects[0]["Field1"]); 28 | Assert.AreEqual("2", entityData.Objects[0]["Field2"]); 29 | Assert.AreEqual("", entityData.Objects[0]["Field3"]); 30 | Assert.AreEqual("4", entityData.Objects[1]["Field1"]); 31 | Assert.AreEqual("5", entityData.Objects[1]["Field2"]); 32 | Assert.AreEqual("6", entityData.Objects[1]["Field3"]); 33 | } 34 | 35 | public static void AssertComplex(EntityData entityData) 36 | { 37 | Assert.AreEqual("Complex", entityData.EntityName); 38 | 39 | Assert.AreEqual(4, entityData.Objects[0].Count); 40 | Assert.AreEqual("Michael Altmann", entityData.Objects[0]["Name"]); 41 | Assert.AreEqual("2016-06-06", entityData.Objects[0]["Birthdate"]); 42 | Assert.AreEqual("2017", entityData.Objects[0]["Year"]); 43 | Assert.AreEqual("12.12", entityData.Objects[0]["DecimalField"]); 44 | 45 | Assert.AreEqual(4, entityData.Objects[1].Count); 46 | Assert.AreEqual("Simone Altmann", entityData.Objects[1]["Name"]); 47 | Assert.AreEqual("2012-02-02", entityData.Objects[1]["Birthdate"]); 48 | Assert.AreEqual("2011", entityData.Objects[1]["Year"]); 49 | Assert.AreEqual("33.44", entityData.Objects[1]["DecimalField"]); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/DataProviders.Gherkin/DataProviders.Gherkin.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {40BA2B6D-3897-481B-AFF1-77BDB454A533} 8 | Library 9 | Properties 10 | CherrySeed.DataProviders.Gherkin 11 | CherrySeed.DataProviders.Gherkin 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\packages\Gherkin.4.0.0\lib\net45\Gherkin.dll 35 | True 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | {f40a4d24-2e1d-4c23-9c06-e22c11c43a3c} 50 | CherrySeed 51 | 52 | 53 | 54 | 61 | -------------------------------------------------------------------------------- /src/DataProviders.Csv/DataProviders.Csv.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {D918620A-A15D-4AE2-A416-5A55BB189CD4} 8 | Library 9 | Properties 10 | CherrySeed.DataProviders.Csv 11 | CherrySeed.DataProviders.Csv 12 | v4.0 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | ..\packages\CsvHelper.2.16.0.0\lib\net40\CsvHelper.dll 36 | True 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | {f40a4d24-2e1d-4c23-9c06-e22c11c43a3c} 53 | CherrySeed 54 | 55 | 56 | 57 | 64 | -------------------------------------------------------------------------------- /src/CherrySeed.Test.Base/CherrySeed.Test.Base.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {B2A5444D-82B9-410D-BB85-39951972EBB6} 8 | Library 9 | Properties 10 | CherrySeed.Test.Base 11 | CherrySeed.Test.Base 12 | v4.5.2 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | false 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | false 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | {f40a4d24-2e1d-4c23-9c06-e22c11c43a3c} 54 | CherrySeed 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /src/CherrySeed.Test/IntegrationTests/PropertyTransformationTests/EnumPropertyTransformationTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using CherrySeed.EntityDataProvider; 4 | using CherrySeed.Test.Asserts; 5 | using CherrySeed.Test.Base.Repositories; 6 | using CherrySeed.Test.Infrastructure; 7 | using CherrySeed.Test.Models; 8 | using Microsoft.VisualStudio.TestTools.UnitTesting; 9 | 10 | namespace CherrySeed.Test.IntegrationTests.PropertyTransformationTests 11 | { 12 | [TestClass] 13 | public class EnumPropertyTransformationTests 14 | { 15 | private CherrySeedDriver _cherrySeedDriver; 16 | 17 | [TestInitialize] 18 | public void Setup() 19 | { 20 | _cherrySeedDriver = new CherrySeedDriver(); 21 | } 22 | 23 | [TestMethod] 24 | public void TransformEnumTypes() 25 | { 26 | // Arrange 27 | var entityData = new List 28 | { 29 | new EntityDataBuilder("CherrySeed.Test.Models.EntityWithEnumProperty", 30 | "EnumProperty1", "EnumProperty2") 31 | .WithEntity("EnumValue1", "EnumValue2") 32 | .Build() 33 | }; 34 | 35 | // Act 36 | var repository = new InMemoryRepository(); 37 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 38 | { 39 | cfg.ForEntity(); 40 | }); 41 | 42 | // Assert 43 | Assert.AreEqual(1, repository.CountSeededObjects()); 44 | Assert.AreEqual(1, repository.CountSeededObjects()); 45 | EntityAsserts.AssertEntityWithEnumProperty(repository.GetEntities().First(), new EntityWithEnumProperty 46 | { 47 | EnumProperty1 = TestEnum.EnumValue1, 48 | EnumProperty2 = TestEnum.EnumValue2 49 | }); 50 | } 51 | 52 | [TestMethod] 53 | public void TransformEnumTypesWithNumber() 54 | { 55 | // Arrange 56 | var entityData = new List 57 | { 58 | new EntityDataBuilder("CherrySeed.Test.Models.EntityWithEnumProperty", 59 | "EnumProperty1", "EnumProperty2") 60 | .WithEntity("1", "0") 61 | .Build() 62 | }; 63 | 64 | // Act 65 | var repository = new InMemoryRepository(); 66 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 67 | { 68 | cfg.ForEntity(); 69 | }); 70 | 71 | // Assert 72 | Assert.AreEqual(1, repository.CountSeededObjects()); 73 | Assert.AreEqual(1, repository.CountSeededObjects()); 74 | EntityAsserts.AssertEntityWithEnumProperty(repository.GetEntities().First(), new EntityWithEnumProperty 75 | { 76 | EnumProperty1 = TestEnum.EnumValue2, 77 | EnumProperty2 = TestEnum.EnumValue1 78 | }); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/CherrySeed.Test/Models/EntityWithSimpleProperties.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CherrySeed.Test.Models 4 | { 5 | public class EntityWithSimpleProperties 6 | { 7 | public string MyString { get; set; } 8 | public bool MyBool { get; set; } 9 | public DateTime MyDateTime { get; set; } 10 | public int MyInteger { get; set; } 11 | public double MyDouble { get; set; } 12 | public decimal MyDecimal { get; set; } 13 | } 14 | 15 | public class EntityWithNullableProperties 16 | { 17 | public string MyString { get; set; } 18 | public bool? MyBool { get; set; } 19 | public DateTime? MyDateTime { get; set; } 20 | public int? MyInteger { get; set; } 21 | public double? MyDouble { get; set; } 22 | public decimal? MyDecimal { get; set; } 23 | } 24 | 25 | public enum TestEnum 26 | { 27 | EnumValue1, 28 | EnumValue2 29 | } 30 | 31 | public class EntityWithEnumProperty 32 | { 33 | public TestEnum EnumProperty1 { get; set; } 34 | public TestEnum EnumProperty2 { get; set; } 35 | } 36 | 37 | public class EntityWithNullableEnumProperty 38 | { 39 | public TestEnum? EnumProperty1 { get; set; } 40 | public TestEnum? EnumProperty2 { get; set; } 41 | } 42 | 43 | public class EntityWithNotSupportedTypeProperty 44 | { 45 | public uint UintProperty { get; set; } 46 | } 47 | 48 | /// 49 | /// /// 50 | /// 51 | 52 | public class EntityWithConformIntPk 53 | { 54 | public int Id { get; set; } 55 | } 56 | 57 | public class EntityWithConformIntPk2 58 | { 59 | public int ID { get; set; } 60 | } 61 | 62 | public class EntityWithConformIntPk3 63 | { 64 | public int EntityWithConformIntPk3Id { get; set; } 65 | } 66 | 67 | public class EntityWithConformIntPk4 68 | { 69 | public int EntityWithConformIntPk4ID { get; set; } 70 | } 71 | 72 | public class EntityWithConformStringPk 73 | { 74 | public string Id { get; set; } 75 | } 76 | 77 | public class EntityWithConformGuidPk 78 | { 79 | public Guid Id { get; set; } 80 | } 81 | 82 | public class EntityWithUnconformIntPk 83 | { 84 | public int CustomId { get; set; } 85 | } 86 | 87 | public class EntityWithTReference 88 | { 89 | public T ReferenceId { get; set; } 90 | } 91 | 92 | public class EntityWithIntReference : EntityWithTReference 93 | { } 94 | 95 | public class EntityWithGuidReference : EntityWithTReference 96 | { } 97 | 98 | public class EntityWithStringReference : EntityWithTReference 99 | { } 100 | 101 | public class EntityWithTReferenceModel 102 | { 103 | public T ReferenceModel { get; set; } 104 | } 105 | 106 | public class EntityWithStringReferenceModel : EntityWithTReferenceModel 107 | { } 108 | 109 | public class EntityWithGuidReferenceModel : EntityWithTReferenceModel 110 | { } 111 | 112 | public class EntityWithIntReferenceModel : EntityWithTReferenceModel 113 | { } 114 | } -------------------------------------------------------------------------------- /src/Repositories.Ef.Test/EfRepositoryTest.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Entity; 2 | using System.Linq; 3 | using CherrySeed.Repositories.Ef; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | 6 | namespace Repositories.Ef.Test 7 | { 8 | public class Simple 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | } 13 | 14 | public class TestDbContext : DbContext 15 | { 16 | public TestDbContext() 17 | : base("name=TestDbContext") 18 | { 19 | Database.SetInitializer(new DropCreateDatabaseAlways()); 20 | } 21 | 22 | public DbSet Simple { get; set; } 23 | } 24 | 25 | [TestClass] 26 | public class EfRepositoryTest 27 | { 28 | [TestMethod] 29 | public void ClearEntries() 30 | { 31 | using (var dbContext = new TestDbContext()) 32 | { 33 | dbContext.Simple.Add(new Simple() { Name = "Michael"}); 34 | dbContext.SaveChanges(); 35 | 36 | var count = dbContext.Simple.Count(); 37 | Assert.IsTrue(count > 0); 38 | } 39 | 40 | var repository = new EfRepository(() => new TestDbContext()); 41 | 42 | repository.RemoveEntities(typeof(Simple)); 43 | 44 | using (var dbContext = new TestDbContext()) 45 | { 46 | var count = dbContext.Simple.Count(); 47 | Assert.AreEqual(0, count); 48 | } 49 | } 50 | 51 | [TestMethod] 52 | public void CreateEntry() 53 | { 54 | using (var dbContext = new TestDbContext()) 55 | { 56 | dbContext.Simple.RemoveRange(dbContext.Simple.ToList()); 57 | dbContext.SaveChanges(); 58 | 59 | var count = dbContext.Simple.Count(); 60 | Assert.AreEqual(0, count); 61 | } 62 | 63 | var repository = new EfRepository(() => new TestDbContext()); 64 | 65 | repository.SaveEntity(new Simple { Name = "Michael"}); 66 | 67 | using (var dbContext = new TestDbContext()) 68 | { 69 | var count = dbContext.Simple.Count(); 70 | Assert.AreEqual(1, count); 71 | } 72 | } 73 | 74 | [TestMethod] 75 | public void LoadEntry() 76 | { 77 | Simple simple; 78 | using (var dbContext = new TestDbContext()) 79 | { 80 | dbContext.Simple.RemoveRange(dbContext.Simple.ToList()); 81 | dbContext.SaveChanges(); 82 | 83 | var count = dbContext.Simple.Count(); 84 | Assert.AreEqual(0, count); 85 | 86 | simple = new Simple {Name = "Michael"}; 87 | dbContext.Simple.Add(simple); 88 | dbContext.SaveChanges(); 89 | } 90 | 91 | var repository = new EfRepository(() => new TestDbContext()); 92 | 93 | var result = repository.LoadEntity(typeof(Simple), simple.Id); 94 | 95 | var simpleResult = (Simple) result; 96 | 97 | Assert.AreEqual("Michael", simpleResult.Name); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/CherrySeed.Test/IntegrationTests/CustomTypeTransformationTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using CherrySeed.EntityDataProvider; 4 | using CherrySeed.Test.Asserts; 5 | using CherrySeed.Test.Base.Repositories; 6 | using CherrySeed.Test.Infrastructure; 7 | using CherrySeed.Test.Mocks; 8 | using CherrySeed.Test.Models; 9 | using Microsoft.VisualStudio.TestTools.UnitTesting; 10 | 11 | namespace CherrySeed.Test.IntegrationTests 12 | { 13 | [TestClass] 14 | public class CustomTypeTransformationTests 15 | { 16 | private CherrySeedDriver _cherrySeedDriver; 17 | 18 | [TestInitialize] 19 | public void Setup() 20 | { 21 | _cherrySeedDriver = new CherrySeedDriver(); 22 | } 23 | 24 | [TestMethod] 25 | public void TransformPropertyWithOverridenTypeTransformation() 26 | { 27 | // Arrange 28 | var entityData = new List 29 | { 30 | new EntityDataBuilder("CherrySeed.Test.Models.EntityWithSimpleProperties", 31 | "MyString") 32 | .WithEntity("This is a sample text") 33 | .Build() 34 | }; 35 | 36 | // Act 37 | var repository = new InMemoryRepository(); 38 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 39 | { 40 | cfg.AddTypeTransformation(typeof(string), new CustomTypeTransformation("New sample text")); 41 | cfg.ForEntity(); 42 | }); 43 | 44 | // Assert 45 | Assert.AreEqual(1, repository.CountSeededObjects()); 46 | Assert.AreEqual(1, repository.CountSeededObjects()); 47 | EntityAsserts.AssertEntityWithSimpleProperties(repository.GetEntities().First(), new EntityWithSimpleProperties 48 | { 49 | MyString = "New sample text" 50 | }); 51 | } 52 | 53 | [TestMethod] 54 | public void TransformPropertyWithNotSupportedTypeTransformation() 55 | { 56 | // Arrange 57 | var entityData = new List 58 | { 59 | new EntityDataBuilder("CherrySeed.Test.Models.EntityWithNotSupportedTypeProperty", 60 | "UintProperty") 61 | .WithEntity("12345") 62 | .Build() 63 | }; 64 | 65 | // Act 66 | var repository = new InMemoryRepository(); 67 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 68 | { 69 | cfg.AddTypeTransformation(typeof(uint), new CustomTypeTransformation(123)); 70 | cfg.ForEntity(); 71 | }); 72 | 73 | // Assert 74 | Assert.AreEqual(1, repository.CountSeededObjects()); 75 | Assert.AreEqual(1, repository.CountSeededObjects()); 76 | EntityAsserts.AssertEntityWithNotSupportedProperty(repository.GetEntities().First(), new EntityWithNotSupportedTypeProperty 77 | { 78 | UintProperty = 123 79 | }); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/CherrySeed/Utils/ReflectionUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Reflection; 4 | 5 | namespace CherrySeed.Utils 6 | { 7 | class ReflectionUtil 8 | { 9 | public static object GetPropertyValue(object obj, string propertyName) 10 | { 11 | return obj.GetType().GetProperty(propertyName).GetValue(obj, null); 12 | } 13 | 14 | public static bool ExistProperty(Type type, string propertyName) 15 | { 16 | return type.GetProperty(propertyName) != null; 17 | } 18 | 19 | public static void SetProperty(object obj, string propertyName, object propertyValue) 20 | { 21 | var type = obj.GetType(); 22 | var prop = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance); 23 | 24 | if (prop == null || !prop.CanWrite) 25 | { 26 | throw new NullReferenceException("Property is missing"); 27 | } 28 | 29 | try 30 | { 31 | prop.SetValue(obj, propertyValue, null); 32 | } 33 | catch (Exception ex) 34 | { 35 | throw new InvalidOperationException("Set property failed", ex); 36 | } 37 | } 38 | 39 | public static bool IsNullableValueType(Type type) 40 | { 41 | return Nullable.GetUnderlyingType(type) != null; 42 | } 43 | 44 | public static Type GetPropertyType(Type type, string propertyName) 45 | { 46 | var prop = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance); 47 | 48 | if (prop == null) 49 | { 50 | throw new NullReferenceException("Property is missing"); 51 | } 52 | 53 | return prop.PropertyType; 54 | } 55 | 56 | public static string GetMemberName(LambdaExpression memberSelector) 57 | { 58 | var currentExpression = memberSelector.Body; 59 | 60 | while (true) 61 | { 62 | switch (currentExpression.NodeType) 63 | { 64 | case ExpressionType.Parameter: 65 | return ((ParameterExpression)currentExpression).Name; 66 | case ExpressionType.MemberAccess: 67 | return ((MemberExpression)currentExpression).Member.Name; 68 | case ExpressionType.Call: 69 | return ((MethodCallExpression)currentExpression).Method.Name; 70 | case ExpressionType.Convert: 71 | case ExpressionType.ConvertChecked: 72 | currentExpression = ((UnaryExpression)currentExpression).Operand; 73 | break; 74 | case ExpressionType.Invoke: 75 | currentExpression = ((InvocationExpression)currentExpression).Expression; 76 | break; 77 | case ExpressionType.ArrayLength: 78 | return "Length"; 79 | default: 80 | throw new Exception("not a proper member selector"); 81 | } 82 | } 83 | } 84 | 85 | public static bool IsReferenceType(Type type) 86 | { 87 | return type != typeof (string) && type.IsClass; 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /src/Repositories.Ef/Repositories.Ef.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {BB9996EC-F815-4AA3-B83A-17BAFA66D690} 8 | Library 9 | Properties 10 | CherrySeed.Repositories.Ef 11 | CherrySeed.Repositories.Ef 12 | v4.0 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | ..\packages\EntityFramework.6.0.0\lib\net40\EntityFramework.dll 36 | True 37 | 38 | 39 | ..\packages\EntityFramework.6.0.0\lib\net40\EntityFramework.SqlServer.dll 40 | True 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | {f40a4d24-2e1d-4c23-9c06-e22c11c43a3c} 52 | CherrySeed 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 68 | -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow/DataProviders.SpecFlow.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {B4F2B2AD-C49D-46DD-B3AB-AD25225326A3} 8 | Library 9 | Properties 10 | CherrySeed.DataProviders.SpecFlow 11 | CherrySeed.DataProviders.SpecFlow 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | ..\packages\SpecFlow.2.1.0\lib\net45\TechTalk.SpecFlow.dll 43 | True 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | {f40a4d24-2e1d-4c23-9c06-e22c11c43a3c} 55 | CherrySeed 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 71 | -------------------------------------------------------------------------------- /src/CherrySeed.Test.Base/Repositories/AssertRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | using CherrySeed.Repositories; 6 | 7 | namespace CherrySeed.Test.Base.Repositories 8 | { 9 | public class EntityInfo 10 | { 11 | public DateTime SeedingDateTime { get; set; } 12 | public DateTime ClearingDateTime { get; set; } 13 | public List Entities { get; set; } 14 | 15 | public EntityInfo() 16 | { 17 | Entities = new List(); 18 | SeedingDateTime = DateTime.Now; 19 | } 20 | } 21 | 22 | public class InMemoryRepository : IRepository 23 | { 24 | private readonly Dictionary _entities; 25 | private readonly Func _loadEntityFunc; 26 | 27 | public InMemoryRepository() 28 | { 29 | _entities = new Dictionary(); 30 | } 31 | 32 | public InMemoryRepository(Func loadEntityFunc) 33 | : this() 34 | { 35 | _loadEntityFunc = loadEntityFunc; 36 | } 37 | 38 | public List GetEntities() 39 | { 40 | return _entities.Keys.SelectMany(GetEntities).ToList(); 41 | } 42 | 43 | public List GetEntities() 44 | { 45 | var entityType = typeof (T); 46 | return GetEntities(entityType).OfType().ToList(); 47 | } 48 | 49 | private List GetEntities(Type entityType) 50 | { 51 | return _entities[entityType].Entities.ToList(); 52 | } 53 | 54 | public DateTime GetSeedingDateTime() 55 | { 56 | var entityType = typeof (T); 57 | return _entities[entityType].SeedingDateTime; 58 | } 59 | 60 | public DateTime GetClearingDateTime() 61 | { 62 | var entityType = typeof(T); 63 | return _entities[entityType].ClearingDateTime; 64 | } 65 | 66 | public void SaveEntity(object obj) 67 | { 68 | var type = obj.GetType(); 69 | 70 | if (_entities.ContainsKey(type)) 71 | _entities[type].Entities.Add(obj); 72 | else 73 | { 74 | _entities.Add(type, new EntityInfo 75 | { 76 | Entities = new List {obj} 77 | }); 78 | } 79 | } 80 | 81 | public void RemoveEntities(Type type) 82 | { 83 | if (_entities.ContainsKey(type)) 84 | { 85 | _entities[type].ClearingDateTime = DateTime.Now; 86 | _entities[type].Entities.Clear(); 87 | Thread.Sleep(100); 88 | } 89 | } 90 | 91 | public object LoadEntity(Type type, object id) 92 | { 93 | return _entities[type].Entities.First(o => _loadEntityFunc(o, id)); 94 | } 95 | 96 | public int CountSeededObjects() 97 | { 98 | var entityType = typeof (T); 99 | 100 | if (_entities.ContainsKey(entityType)) 101 | return _entities[entityType].Entities.Count; 102 | 103 | return 0; 104 | } 105 | 106 | public int CountSeededObjects() 107 | { 108 | return _entities.Values.Select(e => e.Entities.Count).Sum(); 109 | } 110 | } 111 | } -------------------------------------------------------------------------------- /src/CherrySeed.Test/IntegrationTests/PropertyTransformationTests/NullablePropertyTransformationTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using CherrySeed.EntityDataProvider; 5 | using CherrySeed.Test.Asserts; 6 | using CherrySeed.Test.Base.Repositories; 7 | using CherrySeed.Test.Infrastructure; 8 | using CherrySeed.Test.Models; 9 | using Microsoft.VisualStudio.TestTools.UnitTesting; 10 | 11 | namespace CherrySeed.Test.IntegrationTests.PropertyTransformationTests 12 | { 13 | [TestClass] 14 | public class NullablePropertyTransformationTests 15 | { 16 | private CherrySeedDriver _cherrySeedDriver; 17 | 18 | [TestInitialize] 19 | public void Setup() 20 | { 21 | _cherrySeedDriver = new CherrySeedDriver(); 22 | } 23 | 24 | [TestMethod] 25 | public void TransformNullablePropertyTypes() 26 | { 27 | // Arrange 28 | var entityData = new List 29 | { 30 | new EntityDataBuilder("CherrySeed.Test.Models.EntityWithNullableProperties", 31 | "MyInteger", "MyString", "MyBool", "MyDateTime", "MyDouble", "MyDecimal") 32 | .WithEntity("1", "MyString 1", "true", "2016/05/03", "123,12", "12,33") 33 | .Build() 34 | }; 35 | 36 | // Act 37 | var repository = new InMemoryRepository(); 38 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 39 | { 40 | cfg.ForEntity(); 41 | }); 42 | 43 | // Assert 44 | Assert.AreEqual(1, repository.CountSeededObjects()); 45 | Assert.AreEqual(1, repository.CountSeededObjects()); 46 | EntityAsserts.AssertEntityWithNullableProperties(repository.GetEntities().First(), new EntityWithNullableProperties 47 | { 48 | MyInteger = 1, 49 | MyString = "MyString 1", 50 | MyBool = true, 51 | MyDateTime = new DateTime(2016, 5, 3), 52 | MyDouble = 123.12, 53 | MyDecimal = 12.33m 54 | }); 55 | } 56 | 57 | [TestMethod] 58 | public void TransformNullablePropertyTypesWithNull() 59 | { 60 | // Arrange 61 | var entityData = new List 62 | { 63 | new EntityDataBuilder("CherrySeed.Test.Models.EntityWithNullableProperties", 64 | "MyInteger", "MyString", "MyBool", "MyDateTime", "MyDouble", "MyDecimal") 65 | .WithEntity("", "", "", "", "", "") 66 | .Build() 67 | }; 68 | 69 | // Act 70 | var repository = new InMemoryRepository(); 71 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 72 | { 73 | cfg.ForEntity(); 74 | }); 75 | 76 | // Assert 77 | Assert.AreEqual(1, repository.CountSeededObjects()); 78 | Assert.AreEqual(1, repository.CountSeededObjects()); 79 | EntityAsserts.AssertEntityWithNullableProperties(repository.GetEntities().First(), new EntityWithNullableProperties 80 | { 81 | MyInteger = null, 82 | MyString = null, 83 | MyBool = null, 84 | MyDateTime = null, 85 | MyDouble = null, 86 | MyDecimal = null 87 | }); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/CherrySeed.Test/IntegrationTests/DefaultValuePropertyTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using CherrySeed.EntityDataProvider; 5 | using CherrySeed.Test.Asserts; 6 | using CherrySeed.Test.Base.Repositories; 7 | using CherrySeed.Test.Infrastructure; 8 | using CherrySeed.Test.Models; 9 | using Microsoft.VisualStudio.TestTools.UnitTesting; 10 | 11 | namespace CherrySeed.Test.IntegrationTests 12 | { 13 | [TestClass] 14 | public class DefaultValuePropertyTests 15 | { 16 | private CherrySeedDriver _cherrySeedDriver; 17 | 18 | [TestInitialize] 19 | public void Setup() 20 | { 21 | _cherrySeedDriver = new CherrySeedDriver(); 22 | } 23 | 24 | [TestMethod] 25 | public void EntityPropertiesWithDefaultValues() 26 | { 27 | // Arrange 28 | var entityData = new List 29 | { 30 | new EntityDataBuilder("CherrySeed.Test.Models.EntityWithSimpleProperties") 31 | .WithEntity() 32 | .Build() 33 | }; 34 | 35 | // Act 36 | var repository = new InMemoryRepository(); 37 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 38 | { 39 | cfg.ForEntity() 40 | .WithFieldWithDefaultValue(e => e.MyBool, () => true) 41 | .WithFieldWithDefaultValue(e => e.MyDateTime, () => new DateTime(2016, 10, 15)) 42 | .WithFieldWithDefaultValue(e => e.MyDecimal, () => 12.12m) 43 | .WithFieldWithDefaultValue(e => e.MyDouble, () => 123.123) 44 | .WithFieldWithDefaultValue(e => e.MyInteger, () => 9988) 45 | .WithFieldWithDefaultValue(e => e.MyString, () => "My default string"); 46 | }); 47 | 48 | // Assert 49 | Assert.AreEqual(1, repository.CountSeededObjects()); 50 | Assert.AreEqual(1, repository.CountSeededObjects()); 51 | EntityAsserts.AssertEntityWithSimpleProperties(repository.GetEntities().First(), new EntityWithSimpleProperties 52 | { 53 | MyInteger = 9988, 54 | MyString = "My default string", 55 | MyBool = true, 56 | MyDateTime = new DateTime(2016, 10, 15), 57 | MyDouble = 123.123, 58 | MyDecimal = 12.12m 59 | }); 60 | } 61 | 62 | [TestMethod] 63 | public void EntityPropertiesWithDefaultValues_OverrideDefaultValuesInDataProvider() 64 | { 65 | // Arrange 66 | var entityData = new List 67 | { 68 | new EntityDataBuilder("CherrySeed.Test.Models.EntityWithSimpleProperties", "MyBool", "MyString") 69 | .WithEntity("false", "My string from data provider") 70 | .Build() 71 | }; 72 | 73 | // Act 74 | var repository = new InMemoryRepository(); 75 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 76 | { 77 | cfg.ForEntity() 78 | .WithFieldWithDefaultValue(e => e.MyBool, () => true) 79 | .WithFieldWithDefaultValue(e => e.MyDateTime, () => new DateTime(2016, 10, 15)) 80 | .WithFieldWithDefaultValue(e => e.MyDecimal, () => 12.12m) 81 | .WithFieldWithDefaultValue(e => e.MyDouble, () => 123.123) 82 | .WithFieldWithDefaultValue(e => e.MyInteger, () => 9988) 83 | .WithFieldWithDefaultValue(e => e.MyString, () => "My default string"); 84 | }); 85 | 86 | // Assert 87 | Assert.AreEqual(1, repository.CountSeededObjects()); 88 | Assert.AreEqual(1, repository.CountSeededObjects()); 89 | EntityAsserts.AssertEntityWithSimpleProperties(repository.GetEntities().First(), new EntityWithSimpleProperties 90 | { 91 | MyInteger = 9988, 92 | MyString = "My string from data provider", 93 | MyBool = false, 94 | MyDateTime = new DateTime(2016, 10, 15), 95 | MyDouble = 123.123, 96 | MyDecimal = 12.12m 97 | }); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/CherrySeed.Test/IntegrationTests/PropertyTransformationTests/NullableEnumPropertyTransformationTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using CherrySeed.EntityDataProvider; 4 | using CherrySeed.Test.Asserts; 5 | using CherrySeed.Test.Base.Repositories; 6 | using CherrySeed.Test.Infrastructure; 7 | using CherrySeed.Test.Models; 8 | using Microsoft.VisualStudio.TestTools.UnitTesting; 9 | 10 | namespace CherrySeed.Test.IntegrationTests.PropertyTransformationTests 11 | { 12 | [TestClass] 13 | public class NullableEnumPropertyTransformationTests 14 | { 15 | private CherrySeedDriver _cherrySeedDriver; 16 | 17 | [TestInitialize] 18 | public void Setup() 19 | { 20 | _cherrySeedDriver = new CherrySeedDriver(); 21 | } 22 | 23 | [TestMethod] 24 | public void TransformNullableEnumTypes() 25 | { 26 | // Arrange 27 | var entityData = new List 28 | { 29 | new EntityDataBuilder("CherrySeed.Test.Models.EntityWithNullableEnumProperty", 30 | "EnumProperty1", "EnumProperty2") 31 | .WithEntity("EnumValue1", "EnumValue2") 32 | .Build() 33 | }; 34 | 35 | // Act 36 | var repository = new InMemoryRepository(); 37 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 38 | { 39 | cfg.ForEntity(); 40 | }); 41 | 42 | // Assert 43 | Assert.AreEqual(1, repository.CountSeededObjects()); 44 | Assert.AreEqual(1, repository.CountSeededObjects()); 45 | EntityAsserts.AssertEntityWithNullableEnumProperty(repository.GetEntities().First(), new EntityWithNullableEnumProperty 46 | { 47 | EnumProperty1 = TestEnum.EnumValue1, 48 | EnumProperty2 = TestEnum.EnumValue2 49 | }); 50 | } 51 | 52 | [TestMethod] 53 | public void TransformNullableEnumTypesWithNull() 54 | { 55 | // Arrange 56 | var entityData = new List 57 | { 58 | new EntityDataBuilder("CherrySeed.Test.Models.EntityWithNullableEnumProperty", 59 | "EnumProperty1", "EnumProperty2") 60 | .WithEntity("", "") 61 | .Build() 62 | }; 63 | 64 | // Act 65 | var repository = new InMemoryRepository(); 66 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 67 | { 68 | cfg.ForEntity(); 69 | }); 70 | 71 | // Assert 72 | Assert.AreEqual(1, repository.CountSeededObjects()); 73 | Assert.AreEqual(1, repository.CountSeededObjects()); 74 | EntityAsserts.AssertEntityWithNullableEnumProperty(repository.GetEntities().First(), new EntityWithNullableEnumProperty 75 | { 76 | EnumProperty1 = null, 77 | EnumProperty2 = null 78 | }); 79 | } 80 | 81 | [TestMethod] 82 | public void TransformNullableEnumTypesWithNumbers() 83 | { 84 | // Arrange 85 | var entityData = new List 86 | { 87 | new EntityDataBuilder("CherrySeed.Test.Models.EntityWithNullableEnumProperty", 88 | "EnumProperty1", "EnumProperty2") 89 | .WithEntity("0", "1") 90 | .Build() 91 | }; 92 | 93 | // Act 94 | var repository = new InMemoryRepository(); 95 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 96 | { 97 | cfg.ForEntity(); 98 | }); 99 | 100 | // Assert 101 | Assert.AreEqual(1, repository.CountSeededObjects()); 102 | Assert.AreEqual(1, repository.CountSeededObjects()); 103 | EntityAsserts.AssertEntityWithNullableEnumProperty(repository.GetEntities().First(), new EntityWithNullableEnumProperty 104 | { 105 | EnumProperty1 = TestEnum.EnumValue1, 106 | EnumProperty2 = TestEnum.EnumValue2 107 | }); 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow.Test/IntegrationTests/SpecFlowExtensionsTests.cs: -------------------------------------------------------------------------------- 1 | using CherrySeed.Configuration; 2 | using CherrySeed.DataProviders.SpecFlow.Test.Common; 3 | using CherrySeed.DataProviders.SpecFlow.Test.Entities; 4 | using CherrySeed.Test.Base.Repositories; 5 | using Microsoft.VisualStudio.TestTools.UnitTesting; 6 | 7 | namespace CherrySeed.DataProviders.SpecFlow.Test.IntegrationTests 8 | { 9 | [TestClass] 10 | public class SpecFlowExtensionsTests 11 | { 12 | [TestMethod] 13 | public void SeedCountryAndProject_SeededSuccessfully() 14 | { 15 | // Arrange 16 | var countryTable = ObjectMother.CreateCountryTable(table => 17 | { 18 | table.AddRow("C1", "Austria"); 19 | table.AddRow("C2", "Germany"); 20 | }); 21 | 22 | var projectTable = ObjectMother.CreateProjectTable(table => 23 | { 24 | table.AddRow("P1", "Project1", "C1"); 25 | table.AddRow("P2", "Project2", "C2"); 26 | }); 27 | 28 | // Act - seeding countries 29 | var repository = new InMemoryRepository(); 30 | var cherrySeedConfiguration = new CherrySeedConfiguration(cfg => 31 | { 32 | cfg.WithSpecFlowConfiguration(); 33 | cfg.WithRepository(repository); 34 | cfg.WithCountryAndProjectEntities(); 35 | 36 | cfg.ForEntity() 37 | .WithPrimaryKeyIdGenerationInApplicationAsInteger(); 38 | 39 | cfg.ForEntity() 40 | .WithPrimaryKeyIdGenerationInApplicationAsInteger(); 41 | }); 42 | 43 | var cherrySeeder = cherrySeedConfiguration.CreateSeeder(); 44 | cherrySeeder.Seed("Country", countryTable); 45 | 46 | // Assert - countries 47 | Assert.AreEqual(2, repository.CountSeededObjects()); 48 | Assert.AreEqual(2, repository.CountSeededObjects()); 49 | EntityAsserts.AssertCountry(repository.GetEntities()[0], new Country 50 | { 51 | Id = 1, 52 | Name = "Austria" 53 | }); 54 | EntityAsserts.AssertCountry(repository.GetEntities()[1], new Country 55 | { 56 | Id = 2, 57 | Name = "Germany" 58 | }); 59 | 60 | // Act - seeding projects 61 | cherrySeeder.Seed("Project", projectTable); 62 | 63 | // Assert - projects 64 | Assert.AreEqual(4, repository.CountSeededObjects()); 65 | Assert.AreEqual(2, repository.CountSeededObjects()); 66 | EntityAsserts.AssertProject(repository.GetEntities()[0], new Project 67 | { 68 | Id = 1, 69 | Name = "Project1", 70 | CountryId = 1 71 | }); 72 | EntityAsserts.AssertProject(repository.GetEntities()[1], new Project 73 | { 74 | Id = 2, 75 | Name = "Project2", 76 | CountryId = 2 77 | }); 78 | } 79 | 80 | [TestMethod] 81 | public void SeedAndClear_ClearedSuccessfully() 82 | { 83 | // Arrange 84 | var countryTable = ObjectMother.CreateCountryTable(table => 85 | { 86 | table.AddRow("C1", "Austria"); 87 | table.AddRow("C2", "Germany"); 88 | }); 89 | 90 | var projectTable = ObjectMother.CreateProjectTable(table => 91 | { 92 | table.AddRow("P1", "Project1", "C1"); 93 | table.AddRow("P2", "Project2", "C2"); 94 | }); 95 | 96 | var repository = new InMemoryRepository(); 97 | var cherrySeedConfiguration = new CherrySeedConfiguration(cfg => 98 | { 99 | cfg.WithSpecFlowConfiguration(); 100 | cfg.WithRepository(repository); 101 | cfg.WithCountryAndProjectEntities(); 102 | 103 | cfg.ForEntity() 104 | .WithPrimaryKeyIdGenerationInApplicationAsInteger(); 105 | 106 | cfg.ForEntity() 107 | .WithPrimaryKeyIdGenerationInApplicationAsInteger(); 108 | }); 109 | 110 | var cherrySeeder = cherrySeedConfiguration.CreateSeeder(); 111 | cherrySeeder.Seed("Country", countryTable); 112 | cherrySeeder.Seed("Project", projectTable); 113 | 114 | Assert.AreEqual(4, repository.CountSeededObjects()); 115 | 116 | // Act - seeding countries 117 | cherrySeeder.Clear(); 118 | Assert.AreEqual(0, repository.CountSeededObjects()); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/CherrySeed.Test/IntegrationTests/EntitySeedingOrderTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CherrySeed.EntityDataProvider; 3 | using CherrySeed.Test.Base.Repositories; 4 | using CherrySeed.Test.Infrastructure; 5 | using CherrySeed.Test.Models; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | 8 | namespace CherrySeed.Test.IntegrationTests 9 | { 10 | [TestClass] 11 | public class EntitySeedingOrderTests 12 | { 13 | private CherrySeedDriver _cherrySeedDriver; 14 | 15 | [TestInitialize] 16 | public void Setup() 17 | { 18 | _cherrySeedDriver = new CherrySeedDriver(); 19 | } 20 | 21 | [TestMethod] 22 | public void SeedingMultipleEntities() 23 | { 24 | // Arrange 25 | var entityData = new List 26 | { 27 | new EntityDataBuilder("CherrySeed.Test.Models.EntityWithSimpleProperties", 28 | "MyInteger", "MyString", "MyBool", "MyDateTime", "MyDouble", "MyDecimal") 29 | .WithEntity("1", "MyString 1", "true", "2016/05/03", "123,12", "12,33") 30 | .WithEntity("2", "MyString 1", "true", "2016/05/03", "123,12", "12,33") 31 | .Build(), 32 | 33 | new EntityDataBuilder("CherrySeed.Test.Models.EntityWithNullableProperties", 34 | "MyInteger", "MyString", "MyBool", "MyDateTime", "MyDouble", "MyDecimal") 35 | .WithEntity("1", "MyString 1", "true", "2016/05/03", "123,12", "12,33") 36 | .WithEntity("2", "MyString 1", "true", "2016/05/03", "123,12", "12,33") 37 | .Build() 38 | }; 39 | 40 | // Act 41 | var repository = new InMemoryRepository(); 42 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 43 | { 44 | cfg.ForEntity(); 45 | cfg.ForEntity(); 46 | }); 47 | 48 | // Assert 49 | Assert.AreEqual(repository.CountSeededObjects(), 4); 50 | Assert.AreEqual(repository.CountSeededObjects(), 2); 51 | Assert.AreEqual(repository.CountSeededObjects(), 2); 52 | Assert.IsTrue(repository.GetSeedingDateTime().Ticks < repository.GetSeedingDateTime().Ticks); 53 | } 54 | 55 | [TestMethod] 56 | public void ClearingMultipleEntities() 57 | { 58 | // Arrange 59 | var entityData = new List 60 | { 61 | new EntityDataBuilder("CherrySeed.Test.Models.EntityWithSimpleProperties", 62 | "MyInteger", "MyString", "MyBool", "MyDateTime", "MyDouble", "MyDecimal") 63 | .WithEntity("1", "MyString 1", "true", "2016/05/03", "123,12", "12,33") 64 | .WithEntity("2", "MyString 1", "true", "2016/05/03", "123,12", "12,33") 65 | .Build(), 66 | 67 | new EntityDataBuilder("CherrySeed.Test.Models.EntityWithNullableProperties", 68 | "MyInteger", "MyString", "MyBool", "MyDateTime", "MyDouble", "MyDecimal") 69 | .WithEntity("1", "MyString 1", "true", "2016/05/03", "123,12", "12,33") 70 | .WithEntity("2", "MyString 1", "true", "2016/05/03", "123,12", "12,33") 71 | .Build() 72 | }; 73 | 74 | // Act 75 | var repository = new InMemoryRepository(); 76 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 77 | { 78 | cfg.ForEntity(); 79 | cfg.ForEntity(); 80 | }); 81 | 82 | // Assert 83 | Assert.AreEqual(repository.CountSeededObjects(), 4); 84 | Assert.AreEqual(repository.CountSeededObjects(), 2); 85 | Assert.AreEqual(repository.CountSeededObjects(), 2); 86 | 87 | _cherrySeedDriver.Clear(); 88 | 89 | Assert.AreEqual(repository.CountSeededObjects(), 0); 90 | Assert.AreEqual(repository.CountSeededObjects(), 0); 91 | Assert.AreEqual(repository.CountSeededObjects(), 0); 92 | 93 | var entityWithNullablePropertiesClearingTime = repository.GetClearingDateTime(); 94 | var entityWithSimplePropertiesClearingTime = repository.GetClearingDateTime(); 95 | Assert.IsTrue(entityWithNullablePropertiesClearingTime.Ticks < entityWithSimplePropertiesClearingTime.Ticks); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | **/.vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Microsoft Azure ApplicationInsights config file 170 | ApplicationInsights.config 171 | 172 | # Windows Store app package directory 173 | AppPackages/ 174 | BundleArtifacts/ 175 | 176 | # Visual Studio cache files 177 | # files ending in .cache can be ignored 178 | *.[Cc]ache 179 | # but keep track of directories ending in .cache 180 | !*.[Cc]ache/ 181 | 182 | # Others 183 | ClientBin/ 184 | [Ss]tyle[Cc]op.* 185 | ~$* 186 | *~ 187 | *.dbmdl 188 | *.dbproj.schemaview 189 | *.pfx 190 | *.publishsettings 191 | node_modules/ 192 | orleans.codegen.cs 193 | 194 | # RIA/Silverlight projects 195 | Generated_Code/ 196 | 197 | # Backup & report files from converting an old project file 198 | # to a newer Visual Studio version. Backup files are not needed, 199 | # because we have git ;-) 200 | _UpgradeReport_Files/ 201 | Backup*/ 202 | UpgradeLog*.XML 203 | UpgradeLog*.htm 204 | 205 | # SQL Server files 206 | *.mdf 207 | *.ldf 208 | 209 | # Business Intelligence projects 210 | *.rdl.data 211 | *.bim.layout 212 | *.bim_*.settings 213 | 214 | # Microsoft Fakes 215 | FakesAssemblies/ 216 | 217 | # GhostDoc plugin setting file 218 | *.GhostDoc.xml 219 | 220 | # Node.js Tools for Visual Studio 221 | .ntvs_analysis.dat 222 | 223 | # Visual Studio 6 build log 224 | *.plg 225 | 226 | # Visual Studio 6 workspace options file 227 | *.opt 228 | 229 | # Visual Studio LightSwitch build output 230 | **/*.HTMLClient/GeneratedArtifacts 231 | **/*.DesktopClient/GeneratedArtifacts 232 | **/*.DesktopClient/ModelManifest.xml 233 | **/*.Server/GeneratedArtifacts 234 | **/*.Server/ModelManifest.xml 235 | _Pvt_Extensions 236 | 237 | # LightSwitch generated files 238 | GeneratedArtifacts/ 239 | ModelManifest.xml 240 | 241 | # Paket dependency manager 242 | .paket/paket.exe 243 | 244 | # FAKE - F# Make 245 | .fake/ -------------------------------------------------------------------------------- /src/CherrySeed.Test/IntegrationTests/EntityNameMatchingTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using CherrySeed.EntityDataProvider; 4 | using CherrySeed.Test.Asserts; 5 | using CherrySeed.Test.Base.Repositories; 6 | using CherrySeed.Test.Infrastructure; 7 | using CherrySeed.Test.Models; 8 | using Microsoft.VisualStudio.TestTools.UnitTesting; 9 | 10 | namespace CherrySeed.Test.IntegrationTests 11 | { 12 | [TestClass] 13 | public class EntityNameMatchingTests 14 | { 15 | private CherrySeedDriver _cherrySeedDriver; 16 | 17 | [TestInitialize] 18 | public void Setup() 19 | { 20 | _cherrySeedDriver = new CherrySeedDriver(); 21 | } 22 | 23 | [TestMethod] 24 | public void SetEntityNameAsFullNameInDataProvider() 25 | { 26 | // Arrange 27 | var entityData = new List 28 | { 29 | new EntityDataBuilder("CherrySeed.Test.Models.EntityWithSimpleProperties", 30 | "MyInteger") 31 | .WithEntity("1") 32 | .Build() 33 | }; 34 | 35 | // Act 36 | var repository = new InMemoryRepository(); 37 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 38 | { 39 | cfg.ForEntity(); 40 | }); 41 | 42 | // Assert 43 | Assert.AreEqual(repository.CountSeededObjects(), 1); 44 | Assert.AreEqual(repository.CountSeededObjects(), 1); 45 | EntityAsserts.AssertEntityWithSimpleProperties(repository.GetEntities().First(), new EntityWithSimpleProperties 46 | { 47 | MyInteger = 1 48 | }); 49 | } 50 | 51 | [TestMethod] 52 | public void SetEntityNameAsClassNameInDataProvider() 53 | { 54 | // Arrange 55 | var entityData = new List 56 | { 57 | new EntityDataBuilder("EntityWithSimpleProperties", 58 | "MyInteger") 59 | .WithEntity("1") 60 | .Build() 61 | }; 62 | 63 | // Act 64 | var repository = new InMemoryRepository(); 65 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 66 | { 67 | cfg.ForEntity(); 68 | }); 69 | 70 | // Assert 71 | Assert.AreEqual(repository.CountSeededObjects(), 1); 72 | Assert.AreEqual(repository.CountSeededObjects(), 1); 73 | EntityAsserts.AssertEntityWithSimpleProperties(repository.GetEntities().First(), new EntityWithSimpleProperties 74 | { 75 | MyInteger = 1 76 | }); 77 | } 78 | 79 | [TestMethod] 80 | public void SetEntityNameAsCustomNameInDataProvider() 81 | { 82 | // Arrange 83 | var entityData = new List 84 | { 85 | new EntityDataBuilder("MyEntity", 86 | "MyInteger") 87 | .WithEntity("1") 88 | .Build() 89 | }; 90 | 91 | // Act 92 | var repository = new InMemoryRepository(); 93 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 94 | { 95 | cfg.ForEntity() 96 | .HasEntityName("MyEntity"); 97 | }); 98 | 99 | // Assert 100 | Assert.AreEqual(repository.CountSeededObjects(), 1); 101 | Assert.AreEqual(repository.CountSeededObjects(), 1); 102 | EntityAsserts.AssertEntityWithSimpleProperties(repository.GetEntities().First(), new EntityWithSimpleProperties 103 | { 104 | MyInteger = 1 105 | }); 106 | } 107 | 108 | [TestMethod] 109 | public void SetEntityNameAsCustomNameInDataProvider_NoDataInDataProvider() 110 | { 111 | // Arrange 112 | var entityData = new List 113 | { 114 | new EntityDataBuilder("OtherEntity", 115 | "MyInteger") 116 | .WithEntity("1") 117 | .Build() 118 | }; 119 | 120 | // Act 121 | var repository = new InMemoryRepository(); 122 | _cherrySeedDriver.InitAndSeed(entityData.ToDictionaryDataProvider(), repository, cfg => 123 | { 124 | cfg.ForEntity() 125 | .HasEntityName("MyEntity"); 126 | }); 127 | 128 | // Assert 129 | Assert.AreEqual(repository.CountSeededObjects(), 0); 130 | Assert.AreEqual(repository.CountSeededObjects(), 0); 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/DataProviders.SpecFlow.Test/RealisticEnvironment/Features/Project.feature.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by SpecFlow (http://www.specflow.org/). 4 | // SpecFlow Version:2.1.0.0 5 | // SpecFlow Generator Version:2.0.0.0 6 | // 7 | // Changes to this file may cause incorrect behavior and will be lost if 8 | // the code is regenerated. 9 | // 10 | // ------------------------------------------------------------------------------ 11 | #region Designer generated code 12 | #pragma warning disable 13 | namespace CherrySeed.DataProviders.SpecFlow.Test.RealisticEnvironment.Features 14 | { 15 | using TechTalk.SpecFlow; 16 | 17 | 18 | [System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "2.1.0.0")] 19 | [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 20 | [Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute()] 21 | public partial class ProjectFeature 22 | { 23 | 24 | private static TechTalk.SpecFlow.ITestRunner testRunner; 25 | 26 | #line 1 "Project.feature" 27 | #line hidden 28 | 29 | [Microsoft.VisualStudio.TestTools.UnitTesting.ClassInitializeAttribute()] 30 | public static void FeatureSetup(Microsoft.VisualStudio.TestTools.UnitTesting.TestContext testContext) 31 | { 32 | testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner(null, 0); 33 | TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Project", null, ProgrammingLanguage.CSharp, ((string[])(null))); 34 | testRunner.OnFeatureStart(featureInfo); 35 | } 36 | 37 | [Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupAttribute()] 38 | public static void FeatureTearDown() 39 | { 40 | testRunner.OnFeatureEnd(); 41 | testRunner = null; 42 | } 43 | 44 | [Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute()] 45 | public virtual void TestInitialize() 46 | { 47 | if (((testRunner.FeatureContext != null) 48 | && (testRunner.FeatureContext.FeatureInfo.Title != "Project"))) 49 | { 50 | CherrySeed.DataProviders.SpecFlow.Test.RealisticEnvironment.Features.ProjectFeature.FeatureSetup(null); 51 | } 52 | } 53 | 54 | [Microsoft.VisualStudio.TestTools.UnitTesting.TestCleanupAttribute()] 55 | public virtual void ScenarioTearDown() 56 | { 57 | testRunner.OnScenarioEnd(); 58 | } 59 | 60 | public virtual void ScenarioSetup(TechTalk.SpecFlow.ScenarioInfo scenarioInfo) 61 | { 62 | testRunner.OnScenarioStart(scenarioInfo); 63 | } 64 | 65 | public virtual void ScenarioCleanup() 66 | { 67 | testRunner.CollectScenarioErrors(); 68 | } 69 | 70 | [Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()] 71 | [Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute("Seeding countries and projects")] 72 | [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("FeatureTitle", "Project")] 73 | public virtual void SeedingCountriesAndProjects() 74 | { 75 | TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Seeding countries and projects", ((string[])(null))); 76 | #line 3 77 | this.ScenarioSetup(scenarioInfo); 78 | #line hidden 79 | TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] { 80 | "Id", 81 | "Name"}); 82 | table1.AddRow(new string[] { 83 | "N", 84 | "North"}); 85 | table1.AddRow(new string[] { 86 | "S", 87 | "South"}); 88 | table1.AddRow(new string[] { 89 | "L", 90 | "London"}); 91 | #line 4 92 | testRunner.Given("the following countries exist", ((string)(null)), table1, "Given "); 93 | #line hidden 94 | TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] { 95 | "Id", 96 | "Name", 97 | "CountryId"}); 98 | table2.AddRow(new string[] { 99 | "P1", 100 | "Increase budget", 101 | "N"}); 102 | table2.AddRow(new string[] { 103 | "P2", 104 | "Move to USA", 105 | "S"}); 106 | table2.AddRow(new string[] { 107 | "P3", 108 | "Decrease tools", 109 | "S"}); 110 | #line 9 111 | testRunner.And("the following projects exist", ((string)(null)), table2, "And "); 112 | #line hidden 113 | this.ScenarioCleanup(); 114 | } 115 | } 116 | } 117 | #pragma warning restore 118 | #endregion 119 | -------------------------------------------------------------------------------- /src/DataProviders.Gherkin.Test/DataProviders.Gherkin.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {54E0F0AA-2273-49B6-A91A-9C9A4E2400B2} 7 | Library 8 | Properties 9 | DataProviders.Gherkin.Test 10 | DataProviders.Gherkin.Test 11 | v4.5.2 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | False 18 | UnitTest 19 | 20 | 21 | 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | 30 | 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | PreserveNewest 60 | 61 | 62 | 63 | 64 | {b2a5444d-82b9-410d-bb85-39951972ebb6} 65 | CherrySeed.Test.Base 66 | 67 | 68 | {f40a4d24-2e1d-4c23-9c06-e22c11c43a3c} 69 | CherrySeed 70 | 71 | 72 | {40ba2b6d-3897-481b-aff1-77bdb454a533} 73 | DataProviders.Gherkin 74 | 75 | 76 | 77 | 78 | 79 | 80 | False 81 | 82 | 83 | False 84 | 85 | 86 | False 87 | 88 | 89 | False 90 | 91 | 92 | 93 | 94 | 95 | 96 | 103 | -------------------------------------------------------------------------------- /src/DataProviders.Csv.Test/DataProviders.Csv.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {0FA87C7F-BA21-46E0-914E-A0712479731A} 7 | Library 8 | Properties 9 | DataProviders.Csv.Test 10 | DataProviders.Csv.Test 11 | v4.5.2 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | False 18 | UnitTest 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | {f40a4d24-2e1d-4c23-9c06-e22c11c43a3c} 60 | CherrySeed 61 | 62 | 63 | {d918620a-a15d-4ae2-a416-5a55bb189cd4} 64 | DataProviders.Csv 65 | 66 | 67 | 68 | 69 | PreserveNewest 70 | 71 | 72 | PreserveNewest 73 | 74 | 75 | PreserveNewest 76 | 77 | 78 | PreserveNewest 79 | 80 | 81 | 82 | 83 | 84 | 85 | False 86 | 87 | 88 | False 89 | 90 | 91 | False 92 | 93 | 94 | False 95 | 96 | 97 | 98 | 99 | 100 | 101 | 108 | -------------------------------------------------------------------------------- /src/CherrySeed/CherrySeeder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using CherrySeed.Configuration; 5 | using CherrySeed.EntityDataProvider; 6 | using CherrySeed.EntitySettings; 7 | using CherrySeed.IdMappings; 8 | using CherrySeed.ObjectTransformation; 9 | using CherrySeed.ObjectTransformation.PropertyHandlers; 10 | using CherrySeed.TypeTransformations; 11 | using CherrySeed.Utils; 12 | 13 | namespace CherrySeed 14 | { 15 | public interface ICherrySeeder 16 | { 17 | void Seed(); 18 | void Clear(); 19 | } 20 | 21 | public class CherrySeeder : ICherrySeeder 22 | { 23 | private readonly Dictionary _entityMetadataDict; 24 | private readonly IdMappingProvider _idMappingProvider; 25 | private readonly ObjectListTransformation _objectListTransformation; 26 | private readonly SeederConfiguration _configuration; 27 | 28 | public CherrySeeder(Action configurationExpression) 29 | { 30 | _entityMetadataDict = new Dictionary(); 31 | _idMappingProvider = new IdMappingProvider(); 32 | 33 | var configBuilder = new SeederConfigurationBuilder(); 34 | configurationExpression(configBuilder); 35 | _configuration = configBuilder.Build(); 36 | 37 | _objectListTransformation = new ObjectListTransformation( 38 | new ObjectTransformation.ObjectTransformation( 39 | new PropertyHandler( 40 | _idMappingProvider, 41 | new TypeTransformationProvider(_configuration.TypeTransformations) 42 | ) 43 | ) 44 | ); 45 | 46 | foreach (var entitySetting in _configuration.EntitySettings) 47 | { 48 | _entityMetadataDict.Add(entitySetting.EntityType, new EntityMetadata 49 | { 50 | EntityType = entitySetting.EntityType, 51 | EntitySetting = entitySetting 52 | }); 53 | } 54 | } 55 | 56 | public IDataProvider DataProvider => _configuration.DataProvider; 57 | 58 | public void Seed() 59 | { 60 | if (_configuration.IsClearBeforeSeedingEnabled) 61 | { 62 | Clear(); 63 | } 64 | 65 | var entityDataList = _configuration.DataProvider.GetEntityDataList(); 66 | 67 | foreach (var objectMetadataPair in _entityMetadataDict.OrderBy(em => em.Value.EntitySetting.Order)) 68 | { 69 | ProcessEntity(objectMetadataPair, entityDataList); 70 | } 71 | } 72 | 73 | private void ProcessEntity(KeyValuePair objectMetadataPair, List entityDataList) 74 | { 75 | var entityType = objectMetadataPair.Key; 76 | var entityMetadata = objectMetadataPair.Value; 77 | 78 | var eData = entityDataList.SingleOrDefault(od => entityMetadata.EntitySetting.EntityNames.Contains(od.EntityName)); 79 | 80 | if (eData == null) 81 | { 82 | return; 83 | } 84 | 85 | entityMetadata.ObjectsAsDict = eData.Objects; 86 | 87 | var entitySetting = entityMetadata.EntitySetting; 88 | var createEntityTarget = entitySetting.Repository; 89 | 90 | entityMetadata.Objects = Transform(entityMetadata.EntityType, entityMetadata.ObjectsAsDict, 91 | _objectListTransformation, entitySetting); 92 | 93 | for (var i = 0; i < entityMetadata.Objects.Count; i++) 94 | { 95 | var obj = entityMetadata.Objects[i]; 96 | var objDict = entityMetadata.ObjectsAsDict[i]; 97 | 98 | _configuration.BeforeSaveAction?.Invoke(objDict, obj); 99 | 100 | createEntityTarget.SaveEntity(obj); 101 | 102 | entitySetting.AfterSave(obj); 103 | _configuration.AfterSaveAction?.Invoke(objDict, obj); 104 | 105 | // store primary key (repository/data provider) mapping 106 | if (!string.IsNullOrEmpty(entitySetting.PrimaryKey.PrimaryKeyName)) 107 | { 108 | var entityIdInRepo = ReflectionUtil.GetPropertyValue(obj, entitySetting.PrimaryKey.PrimaryKeyName); 109 | var entityIdInProvider = GetProviderIdOfObject(objDict, entitySetting.PrimaryKey.PrimaryKeyName); 110 | 111 | _idMappingProvider.SetIdMapping(entityMetadata.EntityType, entityIdInProvider, entityIdInRepo); 112 | } 113 | } 114 | } 115 | 116 | public void Clear() 117 | { 118 | foreach (var entityMetadataPair in _entityMetadataDict.OrderByDescending(em => em.Value.EntitySetting.Order)) 119 | { 120 | var entityMetadata = entityMetadataPair.Value; 121 | var repository = entityMetadata.EntitySetting.Repository; 122 | 123 | repository.RemoveEntities(entityMetadata.EntityType); 124 | } 125 | } 126 | 127 | private string GetProviderIdOfObject(Dictionary objectDict, string primaryKeyName) 128 | { 129 | var providerId = objectDict[primaryKeyName]; 130 | return providerId; 131 | } 132 | 133 | private List Transform(Type type, List> inputObjectDictionary, 134 | ObjectListTransformation objectListTransformation, EntitySetting entitySetting) 135 | { 136 | return objectListTransformation.Transform(type, inputObjectDictionary, entitySetting); 137 | } 138 | } 139 | } -------------------------------------------------------------------------------- /src/Repositories.Ef.Test/Repositories.Ef.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {582E1BA4-BF43-4174-9315-3556EE3059E2} 7 | Library 8 | Properties 9 | Repositories.Ef.Test 10 | Repositories.Ef.Test 11 | v4.5.2 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | False 18 | UnitTest 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | ..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.dll 40 | True 41 | 42 | 43 | ..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.SqlServer.dll 44 | True 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | {f40a4d24-2e1d-4c23-9c06-e22c11c43a3c} 68 | CherrySeed 69 | 70 | 71 | {bb9996ec-f815-4aa3-b83a-17bafa66d690} 72 | Repositories.Ef 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | False 84 | 85 | 86 | False 87 | 88 | 89 | False 90 | 91 | 92 | False 93 | 94 | 95 | 96 | 97 | 98 | 99 | 106 | -------------------------------------------------------------------------------- /src/CherrySeed.Test/Asserts/EntityAsserts.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CherrySeed.Test.Models; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | 5 | namespace CherrySeed.Test.Asserts 6 | { 7 | public static class EntityAsserts 8 | { 9 | public static void AssertEntityWithSimpleProperties(EntityWithSimpleProperties actual, EntityWithSimpleProperties expected) 10 | { 11 | Assert.IsNotNull(actual); 12 | Assert.AreEqual(expected.MyString, actual.MyString); 13 | Assert.AreEqual(expected.MyBool, actual.MyBool); 14 | Assert.AreEqual(expected.MyDateTime, actual.MyDateTime); 15 | Assert.AreEqual(expected.MyDecimal, actual.MyDecimal); 16 | Assert.AreEqual(expected.MyDouble, actual.MyDouble); 17 | Assert.AreEqual(expected.MyInteger, actual.MyInteger); 18 | } 19 | 20 | public static void AssertEntityWithNullableProperties(EntityWithNullableProperties actual, EntityWithNullableProperties expected) 21 | { 22 | Assert.IsNotNull(actual); 23 | Assert.AreEqual(expected.MyString, actual.MyString); 24 | Assert.AreEqual(expected.MyBool, actual.MyBool); 25 | Assert.AreEqual(expected.MyDateTime, actual.MyDateTime); 26 | Assert.AreEqual(expected.MyDecimal, actual.MyDecimal); 27 | Assert.AreEqual(expected.MyDouble, actual.MyDouble); 28 | Assert.AreEqual(expected.MyInteger, actual.MyInteger); 29 | } 30 | 31 | public static void AssertEntityWithEnumProperty(EntityWithEnumProperty actual, EntityWithEnumProperty expected) 32 | { 33 | Assert.IsNotNull(actual); 34 | Assert.AreEqual(expected.EnumProperty1, actual.EnumProperty1); 35 | Assert.AreEqual(expected.EnumProperty2, actual.EnumProperty2); 36 | } 37 | 38 | public static void AssertEntityWithNullableEnumProperty(EntityWithNullableEnumProperty actual, EntityWithNullableEnumProperty expected) 39 | { 40 | Assert.IsNotNull(actual); 41 | Assert.AreEqual(expected.EnumProperty1, actual.EnumProperty1); 42 | Assert.AreEqual(expected.EnumProperty2, actual.EnumProperty2); 43 | } 44 | 45 | public static void AssertEntityWithNotSupportedProperty(EntityWithNotSupportedTypeProperty actual, EntityWithNotSupportedTypeProperty expected) 46 | { 47 | Assert.IsNotNull(actual); 48 | Assert.AreEqual(expected.UintProperty, actual.UintProperty); 49 | } 50 | 51 | public static void AssertEntityWithConformIntPk(EntityWithConformIntPk actual, EntityWithConformIntPk expected) 52 | { 53 | Assert.IsNotNull(actual); 54 | Assert.AreEqual(expected.Id, actual.Id); 55 | } 56 | 57 | public static void AssertEntityWithIntReference(EntityWithIntReference actual, EntityWithIntReference expected) 58 | { 59 | Assert.IsNotNull(actual); 60 | Assert.AreEqual(expected.ReferenceId, actual.ReferenceId); 61 | } 62 | 63 | public static void AssertEntityWithConformIntPk2(EntityWithConformIntPk2 actual, EntityWithConformIntPk2 expected) 64 | { 65 | Assert.IsNotNull(actual); 66 | Assert.AreEqual(expected.ID, actual.ID); 67 | } 68 | 69 | public static void AssertEntityWithConformIntPk3(EntityWithConformIntPk3 actual, EntityWithConformIntPk3 expected) 70 | { 71 | Assert.IsNotNull(actual); 72 | Assert.AreEqual(expected.EntityWithConformIntPk3Id, actual.EntityWithConformIntPk3Id); 73 | } 74 | 75 | public static void AssertEntityWithUnconformIntPk(EntityWithUnconformIntPk actual, EntityWithUnconformIntPk expected) 76 | { 77 | Assert.IsNotNull(actual); 78 | Assert.AreEqual(expected.CustomId, actual.CustomId); 79 | } 80 | 81 | public static void AssertEntityWithConformGuidPk(EntityWithConformGuidPk actual) 82 | { 83 | Assert.IsNotNull(actual); 84 | Assert.AreNotEqual(Guid.Empty, actual.Id); 85 | } 86 | 87 | public static void AssertEntityWithConformGuidPk(EntityWithConformGuidPk actual, EntityWithConformGuidPk expected) 88 | { 89 | Assert.IsNotNull(actual); 90 | Assert.AreEqual(expected.Id, actual.Id); 91 | } 92 | 93 | public static void AssertEntityWithConformStringPk(EntityWithConformStringPk actual, EntityWithConformStringPk expected) 94 | { 95 | Assert.IsNotNull(actual); 96 | Assert.AreEqual(expected.Id, actual.Id); 97 | } 98 | 99 | public static void AssertEntityWithGuidReference(EntityWithGuidReference actual, EntityWithGuidReference expected) 100 | { 101 | Assert.IsNotNull(actual); 102 | Assert.AreEqual(expected.ReferenceId, actual.ReferenceId); 103 | } 104 | 105 | public static void AssertEntityWithStringReference(EntityWithStringReference actual, EntityWithStringReference expected) 106 | { 107 | Assert.IsNotNull(actual); 108 | Assert.AreEqual(expected.ReferenceId, actual.ReferenceId); 109 | } 110 | 111 | public static void AssertEntityWithStringReferenceModel(EntityWithStringReferenceModel actual, EntityWithStringReferenceModel expected) 112 | { 113 | Assert.IsNotNull(actual); 114 | Assert.AreEqual(expected.ReferenceModel.Id, actual.ReferenceModel.Id); 115 | } 116 | 117 | public static void AssertEntityWithGuidReferenceModel(EntityWithGuidReferenceModel actual, EntityWithGuidReferenceModel expected) 118 | { 119 | Assert.IsNotNull(actual); 120 | Assert.AreEqual(expected.ReferenceModel.Id, actual.ReferenceModel.Id); 121 | } 122 | 123 | public static void AssertEntityWithIntReferenceModel(EntityWithIntReferenceModel actual, EntityWithIntReferenceModel expected) 124 | { 125 | Assert.IsNotNull(actual); 126 | Assert.AreEqual(expected.ReferenceModel.Id, actual.ReferenceModel.Id); 127 | } 128 | } 129 | } -------------------------------------------------------------------------------- /src/CherrySeed/CherrySeed.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {F40A4D24-2E1D-4C23-9C06-E22C11C43A3C} 8 | Library 9 | Properties 10 | CherrySeed 11 | CherrySeed 12 | v4.0 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | false 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | false 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 108 | --------------------------------------------------------------------------------