From 612ed4a58ac66f65677a8f52ad316301bebdc3cd Mon Sep 17 00:00:00 2001 From: Damian Edwards Date: Sat, 20 Apr 2024 15:39:48 -0700 Subject: [PATCH] Fix enumerable not getting IServiceProvider (#62) - Bump to version 0.9.1 & f - Bump to net8.0 - Use target-typed new --- global.json | 4 +- nuget.config | 8 +++ src/Directory.Build.props | 2 +- src/MiniValidation/MiniValidator.cs | 21 +------- .../MiniValidation.UnitTests.csproj | 4 +- tests/MiniValidation.UnitTests/Recursion.cs | 16 +++--- tests/MiniValidation.UnitTests/TestTypes.cs | 5 ++ tests/MiniValidation.UnitTests/TryValidate.cs | 52 ++++++++++++++++++- .../TypeDescriptorExtensions.cs | 2 +- 9 files changed, 80 insertions(+), 34 deletions(-) create mode 100644 nuget.config diff --git a/global.json b/global.json index e00c63f..501e79a 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "7.0.100", - "rollForward": "feature" + "version": "8.0.100", + "rollForward": "latestFeature" } } \ No newline at end of file diff --git a/nuget.config b/nuget.config new file mode 100644 index 0000000..6ce9759 --- /dev/null +++ b/nuget.config @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/Directory.Build.props b/src/Directory.Build.props index d2d2e35..5cac6aa 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 0.9.0 + 0.9.1 dev diff --git a/src/MiniValidation/MiniValidator.cs b/src/MiniValidation/MiniValidator.cs index 268e4bb..439a97b 100644 --- a/src/MiniValidation/MiniValidator.cs +++ b/src/MiniValidation/MiniValidator.cs @@ -414,7 +414,7 @@ private static async Task TryValidateImpl( if (target is IEnumerable) { RuntimeHelpers.EnsureSufficientExecutionStack(); - var task = TryValidateEnumerable(target, recurse, allowAsync, workingErrors, validatedObjects, validationResults, prefix, currentDepth); + var task = TryValidateEnumerable(target, serviceProvider, recurse, allowAsync, workingErrors, validatedObjects, validationResults, prefix, currentDepth); ThrowIfAsyncNotAllowed(task, allowAsync); isValid = await task.ConfigureAwait(false) && isValid; } @@ -434,7 +434,7 @@ private static async Task TryValidateImpl( if (propertyDetails.IsEnumerable) { var thePrefix = $"{prefix}{propertyDetails.Name}"; - var task = TryValidateEnumerable(propertyValue, recurse, allowAsync, workingErrors, validatedObjects, validationResults, thePrefix, currentDepth); + var task = TryValidateEnumerable(propertyValue, serviceProvider, recurse, allowAsync, workingErrors, validatedObjects, validationResults, thePrefix, currentDepth); ThrowIfAsyncNotAllowed(task, allowAsync); isValid = await task.ConfigureAwait(false) && isValid; } @@ -521,23 +521,6 @@ private static void ThrowIfAsyncNotAllowed(bool allowAsync) } } -#if NET6_0_OR_GREATER - private static async ValueTask TryValidateEnumerable( -#else - private static async Task TryValidateEnumerable( -#endif - object target, - bool recurse, - bool allowAsync, - Dictionary> workingErrors, - Dictionary validatedObjects, - List? validationResults, - string? prefix = null, - int currentDepth = 0) - { - return await TryValidateEnumerable(target, null, recurse, allowAsync, workingErrors, validatedObjects, validationResults, prefix, currentDepth); - } - #if NET6_0_OR_GREATER private static async ValueTask TryValidateEnumerable( #else diff --git a/tests/MiniValidation.UnitTests/MiniValidation.UnitTests.csproj b/tests/MiniValidation.UnitTests/MiniValidation.UnitTests.csproj index fc7cbec..0e7f43a 100644 --- a/tests/MiniValidation.UnitTests/MiniValidation.UnitTests.csproj +++ b/tests/MiniValidation.UnitTests/MiniValidation.UnitTests.csproj @@ -1,8 +1,8 @@  - net6.0;net7.0 - net471;net6.0;net7.0 + net6.0;net7.0;net8.0 + net471;net6.0;net7.0;net8.0 10.0 enable enable diff --git a/tests/MiniValidation.UnitTests/Recursion.cs b/tests/MiniValidation.UnitTests/Recursion.cs index 1c5a8cb..7220cfe 100644 --- a/tests/MiniValidation.UnitTests/Recursion.cs +++ b/tests/MiniValidation.UnitTests/Recursion.cs @@ -65,7 +65,7 @@ public void Valid_When_Child_Invalid_And_Property_Decorated_With_SkipRecursion() [Fact] public void Invalid_When_Enumerable_Item_Invalid_When_Recurse_Default() { - var thingToValidate = new List { new TestType { Child = new TestChildType { RequiredCategory = null, MinLengthFive = "123" } } }; + var thingToValidate = new List { new() { Child = new TestChildType { RequiredCategory = null, MinLengthFive = "123" } } }; var result = MiniValidator.TryValidate(thingToValidate, out var errors); @@ -76,7 +76,7 @@ public void Invalid_When_Enumerable_Item_Invalid_When_Recurse_Default() [Fact] public void Invalid_When_Enumerable_Item_Invalid_When_Recurse_True() { - var thingToValidate = new List { new TestType { Child = new TestChildType { RequiredCategory = null, MinLengthFive = "123" } } }; + var thingToValidate = new List { new() { Child = new TestChildType { RequiredCategory = null, MinLengthFive = "123" } } }; var result = MiniValidator.TryValidate(thingToValidate, recurse: true, out var errors); @@ -87,7 +87,7 @@ public void Invalid_When_Enumerable_Item_Invalid_When_Recurse_True() [Fact] public void Valid_When_Enumerable_Item_Invalid_When_Recurse_False() { - var thingToValidate = new List { new TestType { Child = new TestChildType { RequiredCategory = null, MinLengthFive = "123" } } }; + var thingToValidate = new List { new() { Child = new TestChildType { RequiredCategory = null, MinLengthFive = "123" } } }; var result = MiniValidator.TryValidate(thingToValidate, recurse: false, out _); @@ -97,7 +97,7 @@ public void Valid_When_Enumerable_Item_Invalid_When_Recurse_False() [Fact] public void Valid_When_Enumerable_Item_Has_Invalid_Descendant_But_Property_Decorated_With_SkipRecursion() { - var thingToValidate = new List { new TestType { SkippedChild = new() { RequiredCategory = null } } }; + var thingToValidate = new List { new() { SkippedChild = new() { RequiredCategory = null } } }; var result = MiniValidator.TryValidate(thingToValidate, recurse: true, out _); @@ -129,8 +129,8 @@ public void Error_Message_Keys_For_Root_Enumerable_Are_Formatted_Correctly() { var thingToValidate = new List { - new TestType() , - new TestType { RequiredName = null, TenOrMore = 5 }, + new() , + new() { RequiredName = null, TenOrMore = 5 }, }; var result = MiniValidator.TryValidate(thingToValidate, recurse: true, out var errors); @@ -162,8 +162,8 @@ public void First_Error_In_Root_Enumerable_Returns_Immediately() { var thingToValidate = new List { - new TestType { RequiredName = null }, - new TestType { RequiredName = null }, + new() { RequiredName = null }, + new() { RequiredName = null }, }; var result = MiniValidator.TryValidate(thingToValidate, recurse: true, out var errors); diff --git a/tests/MiniValidation.UnitTests/TestTypes.cs b/tests/MiniValidation.UnitTests/TestTypes.cs index 865ca97..3ffa818 100644 --- a/tests/MiniValidation.UnitTests/TestTypes.cs +++ b/tests/MiniValidation.UnitTests/TestTypes.cs @@ -80,6 +80,11 @@ public IEnumerable Validate(ValidationContext validationContex } } +class TestClassWithEnumerable +{ + public IEnumerable? Enumerable { get; set; } +} + class TestClassLevelAsyncValidatableOnlyType : IAsyncValidatableObject { public int TwentyOrMore { get; set; } = 20; diff --git a/tests/MiniValidation.UnitTests/TryValidate.cs b/tests/MiniValidation.UnitTests/TryValidate.cs index f4e7ddb..b9d4a03 100644 --- a/tests/MiniValidation.UnitTests/TryValidate.cs +++ b/tests/MiniValidation.UnitTests/TryValidate.cs @@ -173,7 +173,7 @@ public void Validator_DisplayAttribute_Name_Used_In_Error_Message_For_Record() [Fact] public void List_Invalid_When_Entry_Invalid() { - var collectionToValidate = new List { new TestType { RequiredName = null } }; + var collectionToValidate = new List { new() { RequiredName = null } }; var result = MiniValidator.TryValidate(collectionToValidate, out var errors); @@ -396,6 +396,56 @@ public async Task TryValidateAsync_With_ServiceProvider() Assert.Equal(nameof(IServiceProvider), errors.Keys.First()); } + [Fact] + public void TryValidate_Enumerable_With_ServiceProvider() + { + var serviceCollection = new ServiceCollection(); + serviceCollection.AddSingleton(); + var serviceProvider = serviceCollection.BuildServiceProvider(); + + var thingToValidate = new TestClassWithEnumerable + { + Enumerable = new List + { + new() + } + }; + + var result = MiniValidator.TryValidate(thingToValidate, serviceProvider, out var errors); + Assert.True(result); + + errors.Clear(); + result = MiniValidator.TryValidate(thingToValidate, out errors); + Assert.False(result); + Assert.Equal(1, errors.Count); + Assert.Equal($"{nameof(TestClassWithEnumerable.Enumerable)}.[0].{nameof(IServiceProvider)}", errors.Keys.First()); + } + + [Fact] + public async Task TryValidateAsync_Enumerable_With_ServiceProvider() + { + var serviceCollection = new ServiceCollection(); + serviceCollection.AddSingleton(); + var serviceProvider = serviceCollection.BuildServiceProvider(); + + var thingToValidate = new TestClassWithEnumerable + { + Enumerable = new List + { + new() + } + }; + + var (isValid, errors) = await MiniValidator.TryValidateAsync(thingToValidate, serviceProvider); + Assert.True(isValid); + + errors.Clear(); + (isValid, errors) = await MiniValidator.TryValidateAsync(thingToValidate); + Assert.False(isValid); + Assert.Equal(1, errors.Count); + Assert.Equal($"{nameof(TestClassWithEnumerable.Enumerable)}.[0].{nameof(IServiceProvider)}", errors.Keys.First()); + } + [Fact] public async Task TryValidateAsync_With_Attribute_Attached_Via_TypeDescriptor() { diff --git a/tests/MiniValidation.UnitTests/TypeDescriptorExtensions.cs b/tests/MiniValidation.UnitTests/TypeDescriptorExtensions.cs index 2a6b30e..325bcf8 100644 --- a/tests/MiniValidation.UnitTests/TypeDescriptorExtensions.cs +++ b/tests/MiniValidation.UnitTests/TypeDescriptorExtensions.cs @@ -28,7 +28,7 @@ public static void AttachAttribute(this Type type, string propertyName, Func overridePds = new Dictionary(); + private readonly Dictionary overridePds = new(); public PropertyOverridingTypeDescriptor(ICustomTypeDescriptor parent) : base(parent)