diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml new file mode 100644 index 0000000..97cd0d5 --- /dev/null +++ b/.github/workflows/build-and-test.yml @@ -0,0 +1,59 @@ +# This workflow will build a .NET project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net + +name: build-and-test + +on: + push: + branches: [ "develop" ] + pull_request: + branches: [ "develop", "master" ] + +jobs: + build_and_test: + name: Build and Test .NET Libraries + runs-on: windows-latest + + strategy: + matrix: + dotnet-version: [8.0.x, 4.8] + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Setup .NET 8 + if: matrix.dotnet-version == '8.0.x' + uses: actions/setup-dotnet@v3 + with: + dotnet-version: ${{ matrix.dotnet-version }} + + - name: Setup .NET Framework 4.8 + if: matrix.dotnet-version == '4.8' + run: echo "Using pre-installed .NET Framework 4.8" + + - name: Restore dependencies .NET 8 + if: matrix.dotnet-version == '8.0.x' + run: dotnet restore + + - name: Restore dependencies .NET 4.8 + if: matrix.dotnet-version == '4.8' + run: nuget restore ObjectFillerNET.sln + + - name: Build .NET 8 + if: matrix.dotnet-version == '8.0.x' + run: dotnet build --configuration Release --no-restore + + - name: Build .NET 4.8 + if: matrix.dotnet-version == '4.8' + run: | + &"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\bin\MSBuild.exe" ObjectFillerNET.sln /p:Configuration=Release + + - name: Test .NET 8 + if: matrix.dotnet-version == '8.0.x' + run: dotnet test --configuration Release --no-build --verbosity normal + + - name: Test .NET 4.8 + if: matrix.dotnet-version == '4.8' + run: | + &"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe" Tynamix.ObjectFiller.Test\bin\Release\net48\Tynamix.ObjectFiller.Test.dll diff --git a/.github/workflows/publish-to-nuget.yml b/.github/workflows/publish-to-nuget.yml new file mode 100644 index 0000000..178d210 --- /dev/null +++ b/.github/workflows/publish-to-nuget.yml @@ -0,0 +1,95 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json + +name: publish-to-nuget +on: + workflow_dispatch: # Allow running the workflow manually from the GitHub UI + push: + branches: + - 'master' # Run the workflow when pushing to the main branch + +env: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + DOTNET_NOLOGO: true + NuGetDirectory: ${{ github.workspace}}/nuget + +defaults: + run: + shell: pwsh + +jobs: + create_nuget: + runs-on: windows-latest + steps: + - name: checkout + uses: actions/checkout@v3 + + # Install the .NET SDK indicated in the global.json file + - name: Setup .NET + uses: actions/setup-dotnet@v4 + + # Create the NuGet package in the folder from the environment variable NuGetDirectory + - run: dotnet pack --configuration Release --output ${{ env.NuGetDirectory }} + + # Publish the NuGet package as an artifact, so they can be used in the following jobs + - uses: actions/upload-artifact@v3 + with: + name: nuget + if-no-files-found: error + retention-days: 7 + path: ${{ env.NuGetDirectory }}/*.nupkg + + validate_nuget: + runs-on: windows-latest + needs: [ create_nuget ] + steps: + # Install the .NET SDK indicated in the global.json file + - name: Setup .NET + uses: actions/setup-dotnet@v4 + + # Download the NuGet package created in the previous job + - uses: actions/download-artifact@v3 + with: + name: nuget + path: ${{ env.NuGetDirectory }} + + - name: Install nuget validator + run: dotnet tool update Meziantou.Framework.NuGetPackageValidation.Tool --global + + # Validate metadata and content of the NuGet package + # https://www.nuget.org/packages/Meziantou.Framework.NuGetPackageValidation.Tool#readme-body-tab + # If some rules are not applicable, you can disable them + # using the --excluded-rules or --excluded-rule-ids option + - name: Validate package + run: meziantou.validate-nuget-package (Get-ChildItem "${{ env.NuGetDirectory }}/*.nupkg") + + run_test: + runs-on: windows-latest + steps: + - uses: actions/checkout@v3 + - name: Setup .NET + uses: actions/setup-dotnet@v4 + - name: Run tests + run: dotnet test --configuration Release + + deploy: + runs-on: windows-latest + needs: [ validate_nuget, run_test ] + steps: + # Download the NuGet package created in the previous job + - uses: actions/download-artifact@v3 + with: + name: nuget + path: ${{ env.NuGetDirectory }} + + # Install the .NET SDK indicated in the global.json file + - name: Setup .NET Core + uses: actions/setup-dotnet@v4 + + # Publish all NuGet packages to NuGet.org + # Use --skip-duplicate to prevent errors if a package with the same version already exists. + # If you retry a failed workflow, already published packages will be skipped without error. + - name: Publish NuGet package + run: | + foreach($file in (Get-ChildItem "${{ env.NuGetDirectory }}" -Recurse -Include *.nupkg)) { + dotnet nuget push $file --api-key "${{ secrets.NUGET_API_KEY }}" --source https://api.nuget.org/v3/index.json --skip-duplicate + } diff --git a/.gitignore b/.gitignore index 43ffef6..3a812e3 100644 --- a/.gitignore +++ b/.gitignore @@ -180,3 +180,4 @@ ObjectFiller.Test/ObjectFiller.Test.v2.ncrunchproject .vs/config/applicationhost.config Output-Build.txt .vs/ +.idea/ diff --git a/Tynamix.ObjectFiller.Test/BugfixTests/Bug143InheritedAbstractPropertiesAreNotFilled.cs b/Tynamix.ObjectFiller.Test/BugfixTests/Bug143InheritedAbstractPropertiesAreNotFilled.cs new file mode 100644 index 0000000..fd779da --- /dev/null +++ b/Tynamix.ObjectFiller.Test/BugfixTests/Bug143InheritedAbstractPropertiesAreNotFilled.cs @@ -0,0 +1,34 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Tynamix.ObjectFiller.Test.BugfixTests +{ + internal abstract class EntityBase + { + public string Name { get; set; } + public abstract string AbstractName { get; set; } + } + + internal class CustomEntity : EntityBase + { + public override string AbstractName { get; set; } + } + + [TestClass] + public class Bug143InheritedAbstractPropertiesAreNotFilled + { + [TestMethod] + public void InheritedAbstractPropertiesShouldBeFilled() + { + Filler filler = new Filler(); + filler + .Setup(true) + .OnProperty(x => x.Name).Use("Alice") + .OnProperty(x => x.AbstractName).Use("John"); + var entity = filler.Create(); + + Assert.IsNotNull(entity); + Assert.AreEqual("Alice", entity.Name); + Assert.AreEqual("John", entity.AbstractName); + } + } +} diff --git a/Tynamix.ObjectFiller/NetTypeApiExtension.cs b/Tynamix.ObjectFiller/NetTypeApiExtension.cs index 9ee8050..b85ba93 100644 --- a/Tynamix.ObjectFiller/NetTypeApiExtension.cs +++ b/Tynamix.ObjectFiller/NetTypeApiExtension.cs @@ -88,6 +88,25 @@ internal static bool IsAbstract(this Type source) return source.IsAbstract; #endif } + + internal static bool IsAbstract(this PropertyInfo source) + { +#if NETSTANDARD + return source.GetMethod.IsAbstract; +#else + var methodInfo = source.GetGetMethod() ?? source.GetSetMethod(); + return methodInfo != null && methodInfo.IsAbstract; +#endif + } + + internal static Type GetBaseType(this Type source) + { +#if NETSTANDARD + return source.GetTypeInfo().BaseType; +#else + return source.BaseType; +#endif + } internal static IEnumerable GetImplementedInterfaces(this Type source) { @@ -100,50 +119,52 @@ internal static IEnumerable GetImplementedInterfaces(this Type source) internal static IEnumerable GetProperties(this Type source, bool ignoreInheritance) { -#if NETSTANDARD - if (ignoreInheritance) { - return source.GetTypeInfo().DeclaredProperties.ToList(); + return GetOwnProperties(source); } - return GetDeclaredPropertyInfosRecursive(new List(), source.GetTypeInfo()); -#else - - if (ignoreInheritance) - { - return source.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); - } - - return source.GetProperties(); -#endif - + return GetPropertiesRecursively(source, new List()); } + private static PropertyInfo[] GetOwnProperties(Type source) + { #if NETSTANDARD - - internal static List GetDeclaredPropertyInfosRecursive(List propertyInfos, TypeInfo typeInfo) + return source.GetTypeInfo().DeclaredProperties.ToArray(); +#else + return source.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); +#endif + } + + private static IEnumerable GetPropertiesRecursively(Type source, List propertyInfos) { - foreach (var property in typeInfo.DeclaredProperties) + foreach (var property in GetOwnProperties(source)) { - if (!propertyInfos.Any(x => x.Name == property.Name)) + var existingProperty = propertyInfos.FirstOrDefault(p => p.Name == property.Name); + if (existingProperty != null) + { + if (IsAbstract(property)) + { + // abstract properties take precedence over their concrete declaration counterpart + propertyInfos.Remove(existingProperty); + propertyInfos.Add(property); + } + } + else { propertyInfos.Add(property); } } - if(typeInfo.BaseType != null) + Type baseType = GetBaseType(source); + if(baseType != null) { - return GetDeclaredPropertyInfosRecursive(propertyInfos, typeInfo.BaseType.GetTypeInfo()); + return GetPropertiesRecursively(baseType, propertyInfos); } return propertyInfos; } -#endif - - - internal static Type[] GetGenericTypeArguments(this Type source) { #if NETSTANDARD diff --git a/Tynamix.ObjectFiller/Tynamix.ObjectFiller.csproj b/Tynamix.ObjectFiller/Tynamix.ObjectFiller.csproj index 46a58f2..f773cdc 100644 --- a/Tynamix.ObjectFiller/Tynamix.ObjectFiller.csproj +++ b/Tynamix.ObjectFiller/Tynamix.ObjectFiller.csproj @@ -1,163 +1,177 @@  + true netstandard1.0;netstandard1.3;netstandard2.0;net35;net452; False - 1.5.7 + 1.5.9 Roman Lautner, Hendrik L., Christian Harlass, GothikX Tynamix http://objectfiller.net/ + True + true + true + true + snupkg + true - -1.5.7 - * Fix multi inheritance bug on .NET Standard - * Add support for IDictionary (thx to wztech0192) - * Bug fixing - - -1.5.6 - * Added target framework netstandard1.3, netstandard2.0 to improve easier usage with .NET 5 - * Added Long Range plugin (thx to weitzhandler) - - -1.5.5 - * SetRandomSeed added to generate always the same random data - * URI Plugin implemented (Thx to twenzel) - * Bugfixing (thx to lichtel, jiaxuyang) - - -1.5.4.1 - * Bugfixing - * Collectionizer supports now also Arrays - - -1.5.4 - * Removed unecessary references for netstandard library - - -1.5.3 - * It is now possible to do an explicit setup (just fill properties which are configured in Filler Setup) - * IpAddress string plugin added - * Switched to .NET Core 1.0 - * Moved to VS 2017 - * Bug fixes - - -1.5.0 - * Collectionizer plugin implemented to use IRandomizer plugins in Collections - * Support for ArrayLists - * Ignore inheritance added to ignore base types of a POCO - * Optimizations in the Randomizer (thx to HerrLoesch) - * FloatRange plugin implemented (thx to HerrLoesch) - * Optimization of some Plugins - * Bug fixing - - -1.4.1 - * Fixing Bug with Multi Threaded Random Access (Thanks to blmeyers) - - -1.4.0 - * Updated to .NET Core. Now you can use ObjectFiller.NET in your .NET Core (DNX) and Windows 10 (UWP) environment! - * FillerSetup can now be used for dedicated properties or types - * Bugfixes - - -1.3.9 - * Bug fixed when creating types with a copy constructor - - -1.3.8 - * Support for Arrays and Nullable Enumerations - * Bugfixes (thx to Hendrik L.) - - -1.3.6 - * Added Randomizer<T> class to easy generate data for simple types like int, double, string -* Support for complex standalone CLR types like List<T> -* CityName plugin (Thx to Hendrik L.) -* E-Mail-Address plugin (Thx to Hendrik L.) -* StreetName plugin (Thx to Hendrik L.) -* CountryName plugin -* Code cleanup -* Bugfixes - --1.3.2 -* Bugfixes - --1.3.1 -* Easier usage of static values in the "Use" API -* Added missing type mappings -* Some bugfixes and improvements - --1.3.0 -* Circular Reference Detection (thx to GothikX) -* Export the ObjectFiller setup and reuse it somewhere else -* Improved LoremIpsum Plugin (thx to GothikX) -* Many bugfixes and improvements - --1.2.8 -* IgnoreAllUnknownTypes added -* Usage of RandomList-Plugin improved -* IntRange-Plugin handles now also nullable int! - --1.2.4 -* Create multiple instances -* Some bugfixes and improvements - --1.2.3 -* Use enumerables to fill objects (thx to charlass) -* Its now possible to fill enum properties (thx to charlass) -* Implemented SequenceGenerator (thx to charlass) - --1.2.1 -* Complete refactoring of the FluentAPI. Read the documentation on objectfiller.net for more information! -* Properties with private setter are able to write. -* Renamed ObjectFiller to Filler to avoid NameSpace conflicts -* Order properties implemented -* IntRange Plugin implemented -* ...some more improvements and bugfixes - --1.1.8 -* Bugfix in RandomizerForProperty - --1.1.7 -* Implemented a Lorem Ipsum string plugin - --1.1.6 -* new fantastic PatternGenerator-Plugin. Thanks to charlass for this! -* Adjust namespaces from ObjectFiller to Tynamix.ObjectFiller - --1.1.4 -* IgnoreAllOfType added. -* Little changes to the main API - --1.1.2 -* moved to github - --1.1.0 -* Changed the fluent API to make it even easier than before to use. - --1.0.22 -* Bugfix when handling lists - --1.0.21 -* Constructors with parameters are now possible as long as the types of parameters are configured in the ObjectFiller.NET setup! - --1.0.16 -* RandomListItem-Plugin - --1.0.15 -* Major Bugfix - --1.0.14 -* Bugfixes - --1.0.12 -* RealNameListString Plugin -* DoubleMinMax plugin - --1.0.10 -* Its now possible to ignore properties. -* Fluent API documented. -* Better ExceptionMessages -* Bugfixes - --1.0.6 -* Its now possible to setup a randomizer to a specific property! - --1.0.0 -* Initial release + -1.5.9 + * Support filling inherited abstract properties (thx to cguyonnet) + + -1.5.8 + * add support for records + + -1.5.7 + * Fix multi inheritance bug on .NET Standard + * Add support for IDictionary (thx to wztech0192) + * Bug fixing + + -1.5.6 + * Added target framework netstandard1.3, netstandard2.0 to improve easier usage with .NET 5 + * Added Long Range plugin (thx to weitzhandler) + + -1.5.5 + * SetRandomSeed added to generate always the same random data + * URI Plugin implemented (Thx to twenzel) + * Bugfixing (thx to lichtel, jiaxuyang) + + -1.5.4.1 + * Bugfixing + * Collectionizer supports now also Arrays + + -1.5.4 + * Removed unecessary references for netstandard library + + -1.5.3 + * It is now possible to do an explicit setup (just fill properties which are configured in Filler Setup) + * IpAddress string plugin added + * Switched to .NET Core 1.0 + * Moved to VS 2017 + * Bug fixes + + -1.5.0 + * Collectionizer plugin implemented to use IRandomizer plugins in Collections + * Support for ArrayLists + * Ignore inheritance added to ignore base types of a POCO + * Optimizations in the Randomizer (thx to HerrLoesch) + * FloatRange plugin implemented (thx to HerrLoesch) + * Optimization of some Plugins + * Bug fixing + + -1.4.1 + * Fixing Bug with Multi Threaded Random Access (Thanks to blmeyers) + + -1.4.0 + * Updated to .NET Core. Now you can use ObjectFiller.NET in your .NET Core (DNX) and Windows 10 (UWP) environment! + * FillerSetup can now be used for dedicated properties or types + * Bugfixes + + -1.3.9 + * Bug fixed when creating types with a copy constructor + + -1.3.8 + * Support for Arrays and Nullable Enumerations + * Bugfixes (thx to Hendrik L.) + + -1.3.6 + * Added Randomizer<T> class to easy generate data for simple types like int, double, string + * Support for complex standalone CLR types like List<T> + * CityName plugin (Thx to Hendrik L.) + * E-Mail-Address plugin (Thx to Hendrik L.) + * StreetName plugin (Thx to Hendrik L.) + * CountryName plugin + * Code cleanup + * Bugfixes + + -1.3.2 + * Bugfixes + + -1.3.1 + * Easier usage of static values in the "Use" API + * Added missing type mappings + * Some bugfixes and improvements + + -1.3.0 + * Circular Reference Detection (thx to GothikX) + * Export the ObjectFiller setup and reuse it somewhere else + * Improved LoremIpsum Plugin (thx to GothikX) + * Many bugfixes and improvements + + -1.2.8 + * IgnoreAllUnknownTypes added + * Usage of RandomList-Plugin improved + * IntRange-Plugin handles now also nullable int! + + -1.2.4 + * Create multiple instances + * Some bugfixes and improvements + + -1.2.3 + * Use enumerables to fill objects (thx to charlass) + * Its now possible to fill enum properties (thx to charlass) + * Implemented SequenceGenerator (thx to charlass) + + -1.2.1 + * Complete refactoring of the FluentAPI. Read the documentation on objectfiller.net for more information! + * Properties with private setter are able to write. + * Renamed ObjectFiller to Filler to avoid NameSpace conflicts + * Order properties implemented + * IntRange Plugin implemented + * ...some more improvements and bugfixes + + -1.1.8 + * Bugfix in RandomizerForProperty + + -1.1.7 + * Implemented a Lorem Ipsum string plugin + + -1.1.6 + * new fantastic PatternGenerator-Plugin. Thanks to charlass for this! + * Adjust namespaces from ObjectFiller to Tynamix.ObjectFiller + + -1.1.4 + * IgnoreAllOfType added. + * Little changes to the main API + + -1.1.2 + * moved to github + + -1.1.0 + * Changed the fluent API to make it even easier than before to use. + + -1.0.22 + * Bugfix when handling lists + + -1.0.21 + * Constructors with parameters are now possible as long as the types of parameters are configured in the ObjectFiller.NET setup! + + -1.0.16 + * RandomListItem-Plugin + + -1.0.15 + * Major Bugfix + + -1.0.14 + * Bugfixes + + -1.0.12 + * RealNameListString Plugin + * DoubleMinMax plugin + + -1.0.10 + * Its now possible to ignore properties. + * Fluent API documented. + * Better ExceptionMessages + * Bugfixes + + -1.0.6 + * Its now possible to setup a randomizer to a specific property! + + -1.0.0 + * Initial release + objectfiller tynamix test testdata prototyp prototyping unittest design designviewmodel generator random data randomdata testing poco lorem ipsum fakedata fake faker The Tynamix ObjectFiller.NET fills the properties of your objects with random data. Use it for unittest, prototyping and whereever you need some random testdata. @@ -167,13 +181,10 @@ It supports also IEnumerables and Dictionaries and constructors WITH parameters. It is also possible to fill instances and to write private properties. https://github.com/Tynamix/ObjectFiller.NET GitHub - True Copyright ©Roman Lautner 2022 - bin\Debug\Tynamix.ObjectFiller.xml - 1.5.7 - 1.5.7 logo.png MIT + @@ -187,4 +198,20 @@ It is also possible to fill instances and to write private properties. + + true + + + + + + + + + README.md + + + + + \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 540cff5..0000000 --- a/appveyor.yml +++ /dev/null @@ -1,12 +0,0 @@ -os: Visual Studio 2022 - -install: -- dotnet restore - -before_build: - - nuget restore - -build: - verbosity: minimal - -test: on