public async Task For_Validate_WhenRuleHasSetToStopValidationAfterFailure_Then_ValidationStopsWhenErrorOccurs()
        {
            // Arrange:
            var memberInfo = PropertyValidatorTestsCommon.CreateTestMemberInfo();
            var validator  = new AsyncPropertyValidator <string>(memberInfo);
            Func <string, Task <bool> > validationPredicate = async x =>
            {
                await Task.CompletedTask;
                return(x != "x");
            };
            const string message = "SOME MESSAGE";
            const string code    = "SOME CODE";

            validator.AddRule(validationPredicate, message, code);
            validator.StopValidationAfterFailure();
            validator.AddRule(x => x == null, "must be null", "MUST_BE_NULL");

            var toValidate = "x";

            // Act:
            var validationErrors = await validator.Validate(toValidate);

            // Assert:
            validationErrors.Count.Should().Be(1);
            validationErrors[0].ErrorMessage.Should().Be("SOME MESSAGE");
            validationErrors[0].ErrorCode.Should().Be("SOME CODE");
            validationErrors[0].PropertyPath.ToString().Should().Be("SomeProperty");
            validationErrors[0].ProvidedValue.Should().Be(toValidate);
        }
        public async Task For_Validate_When_ThereIsValidationRuleForAsyncRule_Then_ValidationErrorIsReturned()
        {
            // Arrange:
            var memberInfo = PropertyValidatorTestsCommon.CreateTestMemberInfo();
            var validator  = new AsyncPropertyValidator <string>(memberInfo);
            Func <string, Task <bool> > validationPredicate = async x =>
            {
                await Task.CompletedTask;
                return(x != "x");
            };
            const string message = "SOME MESSAGE";
            const string code    = "SOME CODE";

            validator.AddRule(validationPredicate, message, code);

            var toValidate = "x";

            // Act:
            var validationErrors = await validator.Validate(toValidate);

            // Assert:
            validationErrors.Count.Should().Be(1);
            var validationError = validationErrors.First();

            validationError.ErrorMessage.Should().Be(message);
            validationError.ErrorCode.Should().Be(code);
            validationError.PropertyPath.ToString().Should().Be("SomeProperty");
            validationError.ProvidedValue.Should().Be(toValidate);
        }
        public void For_ValidateObj_When_ProvidedObjectCanBeCastedToTPropType_Then_ValidationForTPropTypeIsCalled()
        {
            // Arrange:
            var memberInfo = PropertyValidatorTestsCommon.CreateTestMemberInfo();
            var validator  = new AsyncPropertyValidator <string>(memberInfo);
            var toValidate = (object)"x";

            // Act & Assert:
            Assert.DoesNotThrowAsync(() => validator.Validate(toValidate));
        }
        public void For_ValidateObj_When_ProvidedObjectCannotBeCastedToTPropType_Then_ExceptionIsThrown()
        {
            // Arrange:
            var memberInfo = PropertyValidatorTestsCommon.CreateTestMemberInfo();
            var validator  = new AsyncPropertyValidator <string>(memberInfo);
            var toValidate = 10;

            // Act & Assert:
            var exception = Assert.ThrowsAsync <ArgumentException>(() => validator.Validate(toValidate));

            exception.Message.Should().Be("'obj' is not String type");
        }
        public async Task For_Validate_When_ThereAreOverridesToApplyToValidationErrors_Then_AreAppliedToValidationErrors()
        {
            // Arrange:
            var memberInfo = PropertyValidatorTestsCommon.CreateTestMemberInfo();
            var validator  = new AsyncPropertyValidator <string>(memberInfo);
            Func <string, Task <bool> > validationPredicate = async x =>
            {
                await Task.CompletedTask;
                return(x != "x");
            };
            const string message = "SOME MESSAGE";
            const string code    = "SOME CODE";

            validator.AddRule(validationPredicate, message, code);
            validator.WithMessage("Cannot be x");
            validator.WithCode("MUST_NOT_BE_X");
            validator.AddRule(x => x == null, "must be null", "MUST_BE_NULL");
            validator.SetPropertyDisplayName("OverridenPropertyDisplayName");

            var toValidate = "x";

            // Act:
            var validationErrors = await validator.Validate(toValidate);

            // Assert:
            validationErrors.Count.Should().Be(2);

            validationErrors[0].ErrorMessage.Should().Be("Cannot be x");
            validationErrors[0].ErrorCode.Should().Be("MUST_NOT_BE_X");
            validationErrors[0].PropertyPath.ToString().Should().Be("OverridenPropertyDisplayName");
            validationErrors[0].ProvidedValue.Should().Be(toValidate);

            validationErrors[1].ErrorMessage.Should().Be("must be null");
            validationErrors[1].ErrorCode.Should().Be("MUST_BE_NULL");
            validationErrors[1].PropertyPath.ToString().Should().Be("OverridenPropertyDisplayName");
            validationErrors[1].ProvidedValue.Should().Be(toValidate);
        }