From 2fcae010fea6b8d30ac916da71a263727e0d959b Mon Sep 17 00:00:00 2001 From: Aleksei Pankratev Date: Thu, 5 May 2022 17:56:24 +0400 Subject: [PATCH 1/4] Apply validation predicate to matched entries only for Without*** worked correctly when there is more than one failure --- .../ValidatorTesterTester.cs | 16 ++++++++++++++++ .../TestHelper/ITestValidationContinuation.cs | 1 + .../TestHelper/ValidatorTestExtensions.cs | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/FluentValidation.Tests/ValidatorTesterTester.cs b/src/FluentValidation.Tests/ValidatorTesterTester.cs index 12f038ddb..83ed26b9d 100644 --- a/src/FluentValidation.Tests/ValidatorTesterTester.cs +++ b/src/FluentValidation.Tests/ValidatorTesterTester.cs @@ -469,6 +469,22 @@ public class ValidatorTesterTester { ex.Message.ShouldEqual("Found an unexpected error code of 'bar'"); } + [Fact] + public void Unexpected_without_error_code_check() { + //#1937 + var validator = new InlineValidator { + v => v.RuleFor(x => x.Surname).NotNull(), + v => v.RuleFor(x => x.Forename).NotNull() + }; + + validator.TestValidate(new Person()) + .ShouldHaveValidationErrorFor(x => x.Surname) + .WithoutErrorCode("foo") + .WithoutErrorMessage("bar") + .WithoutSeverity(Severity.Warning) + .WithoutCustomState(1); + } + [Fact] public void Expected_severity_check() { var validator = new InlineValidator { diff --git a/src/FluentValidation/TestHelper/ITestValidationContinuation.cs b/src/FluentValidation/TestHelper/ITestValidationContinuation.cs index 8255413e5..29ad27e2f 100644 --- a/src/FluentValidation/TestHelper/ITestValidationContinuation.cs +++ b/src/FluentValidation/TestHelper/ITestValidationContinuation.cs @@ -9,6 +9,7 @@ public interface ITestValidationWith : ITestValidationContinuation { } public interface ITestValidationContinuation : IEnumerable { + IEnumerable MatchedFailures { get; } IEnumerable UnmatchedFailures { get; } } diff --git a/src/FluentValidation/TestHelper/ValidatorTestExtensions.cs b/src/FluentValidation/TestHelper/ValidatorTestExtensions.cs index ba0efd45b..feb66c74d 100644 --- a/src/FluentValidation/TestHelper/ValidatorTestExtensions.cs +++ b/src/FluentValidation/TestHelper/ValidatorTestExtensions.cs @@ -198,7 +198,7 @@ public static class ValidationTestExtension { } public static ITestValidationContinuation WhenAll(this ITestValidationContinuation failures, Func failurePredicate, string exceptionMessage = null) { - var result = TestValidationContinuation.Create(failures); + var result = TestValidationContinuation.Create(failures.MatchedFailures); result.ApplyPredicate(failurePredicate); bool allMatched = !result.UnmatchedFailures.Any(); From 40866cf9b9823e7ee5f20634db4029676f1c61fc Mon Sep 17 00:00:00 2001 From: Aleksei Pankratev Date: Thu, 5 May 2022 18:35:25 +0400 Subject: [PATCH 2/4] Use typecast to avoid extension of public interface --- src/FluentValidation/TestHelper/ITestValidationContinuation.cs | 1 - src/FluentValidation/TestHelper/ValidatorTestExtensions.cs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/FluentValidation/TestHelper/ITestValidationContinuation.cs b/src/FluentValidation/TestHelper/ITestValidationContinuation.cs index 29ad27e2f..8255413e5 100644 --- a/src/FluentValidation/TestHelper/ITestValidationContinuation.cs +++ b/src/FluentValidation/TestHelper/ITestValidationContinuation.cs @@ -9,7 +9,6 @@ public interface ITestValidationWith : ITestValidationContinuation { } public interface ITestValidationContinuation : IEnumerable { - IEnumerable MatchedFailures { get; } IEnumerable UnmatchedFailures { get; } } diff --git a/src/FluentValidation/TestHelper/ValidatorTestExtensions.cs b/src/FluentValidation/TestHelper/ValidatorTestExtensions.cs index feb66c74d..71ce33abe 100644 --- a/src/FluentValidation/TestHelper/ValidatorTestExtensions.cs +++ b/src/FluentValidation/TestHelper/ValidatorTestExtensions.cs @@ -198,7 +198,7 @@ public static class ValidationTestExtension { } public static ITestValidationContinuation WhenAll(this ITestValidationContinuation failures, Func failurePredicate, string exceptionMessage = null) { - var result = TestValidationContinuation.Create(failures.MatchedFailures); + var result = TestValidationContinuation.Create(((TestValidationContinuation)failures).MatchedFailures); result.ApplyPredicate(failurePredicate); bool allMatched = !result.UnmatchedFailures.Any(); From 41ccaad1bd51bd5ac646ebc9e75ba5f45df48a56 Mon Sep 17 00:00:00 2001 From: Aleksei Pankratev Date: Fri, 6 May 2022 22:04:52 +0400 Subject: [PATCH 3/4] Rename test, cover With*** assertions for multiple failures --- .../ValidatorTesterTester.cs | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/FluentValidation.Tests/ValidatorTesterTester.cs b/src/FluentValidation.Tests/ValidatorTesterTester.cs index 83ed26b9d..f9c149d07 100644 --- a/src/FluentValidation.Tests/ValidatorTesterTester.cs +++ b/src/FluentValidation.Tests/ValidatorTesterTester.cs @@ -470,7 +470,7 @@ public class ValidatorTesterTester { } [Fact] - public void Unexpected_without_error_code_check() { + public void Expected_without_error_code_check() { //#1937 var validator = new InlineValidator { v => v.RuleFor(x => x.Surname).NotNull(), @@ -485,6 +485,26 @@ public class ValidatorTesterTester { .WithoutCustomState(1); } + [Fact] + public void Expected_with_error_code_check() { + //#1937 + var validator = new InlineValidator { + v => v.RuleFor(x => x.Forename).NotNull(), + v => v.RuleFor(x => x.Surname).NotNull() + .WithErrorCode("foo") + .WithMessage("bar") + .WithSeverity(Severity.Warning) + .WithState(_ => 1) + }; + + validator.TestValidate(new Person()) + .ShouldHaveValidationErrorFor(x => x.Surname) + .WithErrorCode("foo") + .WithErrorMessage("bar") + .WithSeverity(Severity.Warning) + .WithCustomState(1); + } + [Fact] public void Expected_severity_check() { var validator = new InlineValidator { From 253cf6dfa2f7f087fdfd494b39c357507257aa68 Mon Sep 17 00:00:00 2001 From: Aleksei Pankratev Date: Sat, 7 May 2022 08:40:13 +0400 Subject: [PATCH 4/4] Apply validation predicate only to matched entries for With*** assertions too to correctly display failures --- .../ValidatorTesterTester.cs | 17 ++++++++++++++++- .../TestHelper/ValidatorTestExtensions.cs | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/FluentValidation.Tests/ValidatorTesterTester.cs b/src/FluentValidation.Tests/ValidatorTesterTester.cs index f9c149d07..0e8c410ff 100644 --- a/src/FluentValidation.Tests/ValidatorTesterTester.cs +++ b/src/FluentValidation.Tests/ValidatorTesterTester.cs @@ -486,8 +486,23 @@ public class ValidatorTesterTester { } [Fact] - public void Expected_with_error_code_check() { + public void Unexpected_with_error_message_check() { //#1937 + var validator = new InlineValidator + { + v => v.RuleFor(x => x.Forename).NotEmpty(), + v => v.RuleFor(x => x.Surname).NotEmpty() + }; + + var ex = Assert.Throws(() => + validator.TestValidate(new Person()) + .ShouldHaveValidationErrorFor(x => x.Surname) + .WithErrorMessage("bar")); + ex.Message.ShouldEqual("Expected an error message of 'bar'. Actual message was ''Surname' must not be empty.'"); + } + + [Fact] + public void Expected_with_error_code_check() { var validator = new InlineValidator { v => v.RuleFor(x => x.Forename).NotNull(), v => v.RuleFor(x => x.Surname).NotNull() diff --git a/src/FluentValidation/TestHelper/ValidatorTestExtensions.cs b/src/FluentValidation/TestHelper/ValidatorTestExtensions.cs index 71ce33abe..8930446a7 100644 --- a/src/FluentValidation/TestHelper/ValidatorTestExtensions.cs +++ b/src/FluentValidation/TestHelper/ValidatorTestExtensions.cs @@ -184,7 +184,7 @@ public static class ValidationTestExtension { } public static ITestValidationWith When(this ITestValidationContinuation failures, Func failurePredicate, string exceptionMessage = null) { - var result = TestValidationContinuation.Create(failures); + var result = TestValidationContinuation.Create(((TestValidationContinuation)failures).MatchedFailures); result.ApplyPredicate(failurePredicate); var anyMatched = result.Any();