From d0c91f3cf2c73eba2c31988f9caa13b3d8aa2a7c Mon Sep 17 00:00:00 2001 From: Paul Welter Date: Tue, 28 May 2024 14:39:30 -0500 Subject: [PATCH] add .net 8 support --- .github/workflows/ci-main.yml | 14 ++++++------- .github/workflows/ci-pr.yml | 2 +- .../Blazored.FluentValidation.csproj | 16 +++++++++----- .../EditContextFluentValidationExtensions.cs | 16 +++++++------- .../FluentValidationsValidator.cs | 14 ++++++------- .../AssemblyScanning/Component.razor | 8 +++---- .../AssemblyScanning/Tests.cs | 6 +++--- .../BasicValidation/Tests.cs | 10 ++++----- .../Blazored.FluentValidation.Tests.csproj | 18 ++++++++-------- .../FullFailureAccess/AsyncTests.cs | 18 ++++++++-------- .../FullFailureAccess/SyncTests.cs | 21 +++++++++---------- .../Model/Address.cs | 2 +- .../Model/Person.cs | 2 +- 13 files changed, 77 insertions(+), 70 deletions(-) diff --git a/.github/workflows/ci-main.yml b/.github/workflows/ci-main.yml index b513263..e2e24b6 100644 --- a/.github/workflows/ci-main.yml +++ b/.github/workflows/ci-main.yml @@ -7,7 +7,7 @@ on: types: [ published ] env: - NETCORE_VERSION: '7.0.x' + NETCORE_VERSION: '8.0.x' DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true DOTNET_CLI_TELEMETRY_OPTOUT: true PROJECT_NAME: FluentValidation @@ -42,12 +42,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - + - name: Setup .NET Core uses: actions/setup-dotnet@v1 with: dotnet-version: ${{ env.NETCORE_VERSION }} - + - name: Create Release NuGet package run: | arrTag=(${GITHUB_REF//\// }) @@ -56,17 +56,17 @@ jobs: VERSION="${VERSION:1}" echo Clean Version: $VERSION dotnet pack -v normal -c Release --include-symbols --include-source -p:PackageVersion=$VERSION -o nupkg src/Blazored.$PROJECT_NAME/Blazored.$PROJECT_NAME.csproj - + - name: Push to NuGet Feed run: dotnet nuget push ./nupkg/*.nupkg --source $NUGET_FEED --api-key $NUGET_KEY --skip-duplicate - + - name: Publish Sample Site run: dotnet publish -c Release samples/BlazorWebAssembly/BlazorWebAssembly.csproj - name: Rewrite base href uses: SteveSandersonMS/ghaction-rewrite-base-href@v1 with: - html_path: samples/BlazorWebAssembly/bin/Release/net7.0/publish/wwwroot/index.html + html_path: samples/BlazorWebAssembly/bin/Release/net8.0/publish/wwwroot/index.html base_href: /${{ env.PROJECT_NAME }}/ - name: Deploy to Github Pages @@ -75,5 +75,5 @@ jobs: ACCESS_TOKEN: $GITHUB_TOKEN BASE_BRANCH: main # The branch the action should deploy from. BRANCH: gh-pages # The branch the action should deploy to. - FOLDER: samples/BlazorWebAssembly/bin/Release/net7.0/publish/wwwroot # The folder the action should deploy. + FOLDER: samples/BlazorWebAssembly/bin/Release/net8.0/publish/wwwroot # The folder the action should deploy. SINGLE_COMMIT: true diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index f3b4f98..864f0cf 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -6,7 +6,7 @@ on: env: PROJECT_NAME: Blazored.FluentValidation - NETCORE_VERSION: '7.0.x' + NETCORE_VERSION: '8.0.x' jobs: build: diff --git a/src/Blazored.FluentValidation/Blazored.FluentValidation.csproj b/src/Blazored.FluentValidation/Blazored.FluentValidation.csproj index 90ebca6..8add0c8 100644 --- a/src/Blazored.FluentValidation/Blazored.FluentValidation.csproj +++ b/src/Blazored.FluentValidation/Blazored.FluentValidation.csproj @@ -1,7 +1,7 @@  - net6.0;net7.0 + net6.0;net7.0;net8.0 enable enable @@ -31,14 +31,20 @@ + + + + - - + - - + + + + + diff --git a/src/Blazored.FluentValidation/EditContextFluentValidationExtensions.cs b/src/Blazored.FluentValidation/EditContextFluentValidationExtensions.cs index 7ab8ab8..755a44b 100644 --- a/src/Blazored.FluentValidation/EditContextFluentValidationExtensions.cs +++ b/src/Blazored.FluentValidation/EditContextFluentValidationExtensions.cs @@ -1,8 +1,10 @@ using FluentValidation; using FluentValidation.Internal; using FluentValidation.Results; + using Microsoft.AspNetCore.Components.Forms; using Microsoft.Extensions.DependencyInjection; + using static FluentValidation.AssemblyScanner; namespace Blazored.FluentValidation; @@ -59,12 +61,12 @@ private static async Task ValidateModel(EditContext editContext, messages.Clear(); fluentValidationValidator.LastValidationResult = new Dictionary>(); - + foreach (var validationResult in validationResults.Errors) { var fieldIdentifier = ToFieldIdentifier(editContext, validationResult.PropertyName); messages.Add(fieldIdentifier, validationResult.ErrorMessage); - + if (fluentValidationValidator.LastValidationResult.TryGetValue(fieldIdentifier, out var failures)) { failures.Add(validationResult); @@ -88,7 +90,7 @@ private static async Task ValidateField(EditContext editContext, { var properties = new[] { fieldIdentifier.FieldName }; var context = new ValidationContext(fieldIdentifier.Model, new PropertyChain(), new MemberNameValidatorSelector(properties)); - + validator ??= GetValidatorForModel(serviceProvider, fieldIdentifier.Model, disableAssemblyScanning); if (validator is not null) @@ -160,7 +162,7 @@ private static FieldIdentifier ToFieldIdentifier(in EditContext editContext, in var obj = editContext.Model; var nextTokenEnd = propertyPath.IndexOfAny(Separators); - + // Optimize for a scenario when parsing isn't needed. if (nextTokenEnd < 0) { @@ -187,8 +189,8 @@ private static FieldIdentifier ToFieldIdentifier(in EditContext editContext, in // we've got an Item property var indexerType = prop.GetIndexParameters()[0].ParameterType; var indexerValue = Convert.ChangeType(nextToken.ToString(), indexerType); - - newObj = prop.GetValue(obj, new [] { indexerValue }); + + newObj = prop.GetValue(obj, new[] { indexerValue }); } else { @@ -233,7 +235,7 @@ private static FieldIdentifier ToFieldIdentifier(in EditContext editContext, in } obj = newObj; - + nextTokenEnd = propertyPathAsSpan.IndexOfAny(Separators); if (nextTokenEnd < 0) { diff --git a/src/Blazored.FluentValidation/FluentValidationsValidator.cs b/src/Blazored.FluentValidation/FluentValidationsValidator.cs index 0f8ee8a..c6a6a9e 100644 --- a/src/Blazored.FluentValidation/FluentValidationsValidator.cs +++ b/src/Blazored.FluentValidation/FluentValidationsValidator.cs @@ -1,9 +1,9 @@ using FluentValidation; using FluentValidation.Internal; +using FluentValidation.Results; + using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms; -using System; -using FluentValidation.Results; namespace Blazored.FluentValidation; @@ -48,7 +48,7 @@ public async Task ValidateAsync(Action>? option { throw new NullReferenceException(nameof(CurrentEditContext)); } - + ValidateOptions = options; try @@ -61,7 +61,7 @@ public async Task ValidateAsync(Action>? option throw new InvalidOperationException("No pending ValidationResult found"); } - await (Task) asyncValidationTask; + await (Task)asyncValidationTask; return !CurrentEditContext.GetValidationMessages().Any(); } @@ -95,10 +95,10 @@ public ValidationFailure[] GetFailuresFromLastValidation(FieldIdentifier? fieldI if (fieldIdentifier is null) return LastValidationResult.Values.SelectMany(f => f).ToArray(); - + if (!LastValidationResult.TryGetValue(fieldIdentifier.Value, out var failures)) - return Array.Empty(); - + return Array.Empty(); + return failures.ToArray(); } } \ No newline at end of file diff --git a/tests/Blazored.FluentValidation.Tests/AssemblyScanning/Component.razor b/tests/Blazored.FluentValidation.Tests/AssemblyScanning/Component.razor index e501004..ca9d7a3 100644 --- a/tests/Blazored.FluentValidation.Tests/AssemblyScanning/Component.razor +++ b/tests/Blazored.FluentValidation.Tests/AssemblyScanning/Component.razor @@ -1,4 +1,4 @@ - @@ -11,21 +11,21 @@ { } - +

- +
@code { [Parameter] public bool? DisableAssemblyScanning { get; set; } private readonly Person _person = new(); - + internal ValidationResultType Result { get; private set; } = ValidationResultType.Valid; private void ValidSubmit() => Result = ValidationResultType.Valid; diff --git a/tests/Blazored.FluentValidation.Tests/AssemblyScanning/Tests.cs b/tests/Blazored.FluentValidation.Tests/AssemblyScanning/Tests.cs index 32be18a..3144750 100644 --- a/tests/Blazored.FluentValidation.Tests/AssemblyScanning/Tests.cs +++ b/tests/Blazored.FluentValidation.Tests/AssemblyScanning/Tests.cs @@ -5,7 +5,7 @@ namespace Blazored.FluentValidation.Tests.AssemblyScanning; public class Tests : TestContext { private readonly Fixture _fixture = new(); - + [Fact] public void DisableAssemblyScanning_SetToTrue_NoValidationHappens() { @@ -50,7 +50,7 @@ public void DisableAssemblyScanning_NotSet_ValidationHappens() // Assert cut.Instance.Result.Should().Be(ValidationResultType.Error); } - + [Fact] public void DisableAssemblyScanning_SetToTrueButValidatorsRegistered_ValidationHappens() { @@ -66,7 +66,7 @@ public void DisableAssemblyScanning_SetToTrueButValidatorsRegistered_ValidationH // Assert cut.Instance.Result.Should().Be(ValidationResultType.Error); } - + private class Fixture { public Person InvalidPerson() => new() diff --git a/tests/Blazored.FluentValidation.Tests/BasicValidation/Tests.cs b/tests/Blazored.FluentValidation.Tests/BasicValidation/Tests.cs index fdcef88..69317f6 100644 --- a/tests/Blazored.FluentValidation.Tests/BasicValidation/Tests.cs +++ b/tests/Blazored.FluentValidation.Tests/BasicValidation/Tests.cs @@ -58,26 +58,26 @@ public void Validate_AgeTooOld_ValidationErrorsPresent() // Arrange var cut = RenderComponent(); var person = _fixture.ValidPerson() with { Age = 250 }; - + // Act FillForm(cut, person); cut.Find("button").Click(); - + // Assert cut.Find(".validation-errors>.validation-message").TextContent.Should().Contain(PersonValidator.AgeMax); } - + [Fact] public void Validate_AddressLine1Missing_ValidationErrorsPresent() { // Arrange var cut = RenderComponent(); var person = _fixture.ValidPerson() with { Address = new() { Line1 = string.Empty } }; - + // Act FillForm(cut, person); cut.Find("button").Click(); - + // Assert cut.Find(".validation-errors>.validation-message").TextContent.Should().Contain(AddressValidator.Line1Required); } diff --git a/tests/Blazored.FluentValidation.Tests/Blazored.FluentValidation.Tests.csproj b/tests/Blazored.FluentValidation.Tests/Blazored.FluentValidation.Tests.csproj index 8269342..495a7b2 100644 --- a/tests/Blazored.FluentValidation.Tests/Blazored.FluentValidation.Tests.csproj +++ b/tests/Blazored.FluentValidation.Tests/Blazored.FluentValidation.Tests.csproj @@ -1,7 +1,7 @@ - + - net7.0 + net8.0 enable false @@ -10,23 +10,23 @@ - + - + - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - - + + all runtime; build; native; contentfiles; analyzers diff --git a/tests/Blazored.FluentValidation.Tests/FullFailureAccess/AsyncTests.cs b/tests/Blazored.FluentValidation.Tests/FullFailureAccess/AsyncTests.cs index 8491b24..aa6eb0a 100644 --- a/tests/Blazored.FluentValidation.Tests/FullFailureAccess/AsyncTests.cs +++ b/tests/Blazored.FluentValidation.Tests/FullFailureAccess/AsyncTests.cs @@ -13,48 +13,48 @@ public void GetFailuresFromLastValidation_PersonValid_ResultIsValid() // Arrange var person = _fixture.ValidPerson(); var cut = RenderComponent(); - + // Act FillForm(cut, person); cut.Find("button").Click(); cut.WaitForState(() => cut.Instance.Result is not null); - + // Assert cut.Instance.Result.Should().Be(ValidationResultType.Valid); } - + [Fact] public void GetFailuresFromLastValidation_EmailInvalid_ResultIsError() { // Arrange var person = _fixture.ValidPerson() with { EmailAddress = "invalid-email" }; var cut = RenderComponent(); - + // Act FillForm(cut, person); cut.Find("button").Click(); cut.WaitForState(() => cut.Instance.Result is not null); - + // Assert cut.Instance.Result.Should().Be(ValidationResultType.Error); } - + [Fact] public void GetFailuresFromLastValidation_AgeSuspect_ResultIsWarning() { // Arrange var person = _fixture.ValidPerson() with { Age = 69 }; var cut = RenderComponent(); - + // Act FillForm(cut, person); cut.Find("button").Click(); cut.WaitForState(() => cut.Instance.Result is not null); - + // Assert cut.Instance.Result.Should().Be(ValidationResultType.Warning); } - + private static void FillForm(IRenderedComponent cut, Person person) { diff --git a/tests/Blazored.FluentValidation.Tests/FullFailureAccess/SyncTests.cs b/tests/Blazored.FluentValidation.Tests/FullFailureAccess/SyncTests.cs index 78abfe9..107708b 100644 --- a/tests/Blazored.FluentValidation.Tests/FullFailureAccess/SyncTests.cs +++ b/tests/Blazored.FluentValidation.Tests/FullFailureAccess/SyncTests.cs @@ -1,5 +1,4 @@ -using System; -using Blazored.FluentValidation.Tests.Model; +using Blazored.FluentValidation.Tests.Model; namespace Blazored.FluentValidation.Tests.FullFailureAccess; @@ -13,45 +12,45 @@ public void GetFailuresFromLastValidation_PersonValid_ResultIsValid() // Arrange var person = _fixture.ValidPerson(); var cut = RenderComponent(); - + // Act FillForm(cut, person); cut.Find("button").Click(); - + // Assert cut.Instance.Result.Should().Be(ValidationResultType.Valid); } - + [Fact] public void GetFailuresFromLastValidation_EmailInvalid_ResultIsError() { // Arrange var person = _fixture.ValidPerson() with { EmailAddress = "invalid-email" }; var cut = RenderComponent(); - + // Act FillForm(cut, person); cut.Find("button").Click(); - + // Assert cut.Instance.Result.Should().Be(ValidationResultType.Error); } - + [Fact] public void GetFailuresFromLastValidation_AgeSuspect_ResultIsWarning() { // Arrange var person = _fixture.ValidPerson() with { Age = 69 }; var cut = RenderComponent(); - + // Act FillForm(cut, person); cut.Find("button").Click(); - + // Assert cut.Instance.Result.Should().Be(ValidationResultType.Warning); } - + private static void FillForm(IRenderedComponent cut, Person person) { diff --git a/tests/Blazored.FluentValidation.Tests/Model/Address.cs b/tests/Blazored.FluentValidation.Tests/Model/Address.cs index d7a5332..0eeebc2 100644 --- a/tests/Blazored.FluentValidation.Tests/Model/Address.cs +++ b/tests/Blazored.FluentValidation.Tests/Model/Address.cs @@ -15,7 +15,7 @@ public class AddressValidator : AbstractValidator
public const string TownRequired = "You must enter a town"; public const string CountyRequired = "You must enter a county"; public const string PostcodeRequired = "You must enter a postcode"; - + public AddressValidator() { RuleFor(p => p.Line1).NotEmpty().WithMessage(Line1Required); diff --git a/tests/Blazored.FluentValidation.Tests/Model/Person.cs b/tests/Blazored.FluentValidation.Tests/Model/Person.cs index fc8c0f5..0ab6ca6 100644 --- a/tests/Blazored.FluentValidation.Tests/Model/Person.cs +++ b/tests/Blazored.FluentValidation.Tests/Model/Person.cs @@ -23,7 +23,7 @@ public class PersonValidator : AbstractValidator public const string EmailValid = "You must provide a valid email address"; public const string EmailUnique = "Email address must be unique"; public const string DuplicateEmail = "mail@my.com"; - + public PersonValidator() { RuleSet("Names", () =>