public async Task Validates_with_callback_accepting_derived_async()
        {
            var validator      = new InlineValidator <Root>();
            var impl1Validator = new InlineValidator <FooImpl1>();
            var impl2Validator = new InlineValidator <FooImpl2>();

            impl1Validator.RuleFor(x => x.Name).MustAsync((s, token) => Task.FromResult(s != null));
            impl2Validator.RuleFor(x => x.Number).MustAsync((i, token) => Task.FromResult(i > 0));

            validator.RuleFor(x => x.Foo).SetInheritanceValidator(v => {
                v.Add <FooImpl1>((x, impl1) => {
                    Assert.NotNull(impl1);
                    return(impl1Validator);
                })
                .Add <FooImpl2>((x, impl2) => {
                    Assert.NotNull(impl2);
                    return(impl2Validator);
                });
            });

            var result = await validator.ValidateAsync(new Root { Foo = new FooImpl1() });

            result.Errors.Count.ShouldEqual(1);
            result.Errors[0].PropertyName.ShouldEqual("Foo.Name");

            result = await validator.ValidateAsync(new Root { Foo = new FooImpl2() });

            result.Errors.Count.ShouldEqual(1);
            result.Errors[0].PropertyName.ShouldEqual("Foo.Number");
        }
        public async Task Validates_ruleset_async()
        {
            var validator      = new InlineValidator <Root>();
            var impl1Validator = new InlineValidator <FooImpl1>();
            var impl2Validator = new InlineValidator <FooImpl2>();

            impl1Validator.RuleFor(x => x.Name).Equal("Foo");
            impl1Validator.RuleSet("RuleSet1", () => {
                impl1Validator.RuleFor(x => x.Name).MustAsync((s, token) => Task.FromResult(s != null));
            });


            impl2Validator.RuleFor(x => x.Number).Equal(42);
            impl2Validator.RuleSet("RuleSet2", () => {
                impl2Validator.RuleFor(x => x.Number).MustAsync((i, token) => Task.FromResult(i > 0));
            });

            validator.RuleFor(x => x.Foo).SetInheritanceValidator(v => {
                v.Add(impl1Validator, "RuleSet1")
                .Add(impl2Validator, "RuleSet2");
            });

            var result = await validator.ValidateAsync(new Root { Foo = new FooImpl1() });

            result.Errors.Count.ShouldEqual(1);
            result.Errors[0].PropertyName.ShouldEqual("Foo.Name");

            result = await validator.ValidateAsync(new Root { Foo = new FooImpl2() });

            result.Errors.Count.ShouldEqual(1);
            result.Errors[0].PropertyName.ShouldEqual("Foo.Number");
        }
        public async Task When_async_condition_executed_for_each_instance_of_RuleForEach_condition_should_not_be_cached()
        {
            var person = new Person {
                Children = new List <Person> {
                    new Person {
                        Id = 1
                    },
                    new Person {
                        Id = 0
                    }
                }
            };

            var childValidator = new InlineValidator <Person>();
            int executions     = 0;

            childValidator.WhenAsync(async(a, ct) => {
                executions++;
                return(a.Id != 0);
            }, () => {
                childValidator.RuleFor(a => a.Id).Equal(1);
            });
            var personValidator = new InlineValidator <Person>();

            personValidator.RuleForEach(p => p.Children).SetValidator(childValidator);

            var validationResult = await personValidator.ValidateAsync(person);

            validationResult.IsValid.ShouldBeTrue();
            executions.ShouldEqual(2);
        }
        public async Task RuleForEach_async_RunsTasksSynchronously()
        {
            var validator = new InlineValidator <Person>();
            var result    = new List <bool>();

            validator.RuleForEach(x => x.Children).MustAsync(async(person, token) =>
                                                             await ExclusiveDelay(1)
                                                             .ContinueWith(t => result.Add(t.Result), token)
                                                             .ContinueWith(t => true, token)
                                                             );

            await validator.ValidateAsync(new Person()
            {
                Children = new List <Person> {
                    new Person(), new Person()
                }
            });

            Assert.NotEmpty(result);
#if NET35
            AssertEx
#else
            Assert
#endif
            .All(result, Assert.True);
        }
Exemple #5
0
        public async Task Invokes_custom_validator_async()
        {
            var validator = new InlineValidator <Person>();

            validator.RuleFor(x => x.Forename).SetValidator(new LegacyNotNullValidator());
            var result = await validator.ValidateAsync(new Person());

            result.Errors.Single().ErrorMessage.ShouldEqual("A value is required for Forename.");
        }
        public async Task Transforms_property_value_with_propagated_original_object_async()
        {
            var validator = new InlineValidator <Person>();

            validator.Transform(x => x.Forename, (person, forename) => new { Nicks = person.NickNames, Name = forename })
            .Must(context => context.Nicks.Any(nick => nick == context.Name.ToLower()));

            var result = await validator.ValidateAsync(new Person { NickNames = new[] { "good11", "peter" }, Forename = "Peter" });

            result.IsValid.ShouldBeTrue();
        }
        public void CustomAsync_within_ruleset()
        {
            var validator = new InlineValidator <Person>();

            validator.RuleSet("foo", () => validator.CustomAsync(async x => new ValidationFailure("x", "y")));
            validator.RuleSet("bar", () => validator.CustomAsync(async x => new ValidationFailure("x", "y")));

            var result = validator.ValidateAsync(new Person(), ruleSet: "foo").Result;

            result.Errors.Count.ShouldEqual(1);
        }
Exemple #8
0
        public async Task When_runs_outside_RuleForEach_loop_async()
        {
            // Shouldn't throw an exception if the condition is run outside the loop.
            var validator = new InlineValidator <Tuple <Person> >();

            validator.RuleForEach(x => x.Item1.Orders)
            .MustAsync((x, c) => Task.FromResult(false))
            .When(x => x.Item1 != null);

            var result = await validator.ValidateAsync(Tuple.Create((Person)null));

            result.IsValid.ShouldBeTrue();

            result = await validator.ValidateAsync(Tuple.Create(new Person()
            {
                Orders = new List <Order> {
                    new Order()
                }
            }));

            result.IsValid.ShouldBeFalse();
        }
Exemple #9
0
        public async Task Can_access_colletion_index_async()
        {
            var validator = new InlineValidator <Person>();

            validator.RuleForEach(x => x.Orders).NotNull().WithMessage("{CollectionIndex}");
            var result = await validator.ValidateAsync(new Person { Orders = new List <Order>()
                                                                    {
                                                                        new Order(), null
                                                                    } });

            result.IsValid.ShouldBeFalse();
            result.Errors[0].ErrorMessage.ShouldEqual("1");
        }
Exemple #10
0
        public async Task Failing_condition_should_prevent_multiple_components_running_and_not_throw_async()
        {
            // https://github.com/FluentValidation/FluentValidation/issues/1698
            var validator = new InlineValidator <Person>();

            validator.RuleForEach(x => x.Orders)
            .MustAsync((o, ct) => Task.FromResult(o != null))
            .MustAsync((o, ct) => Task.FromResult(o != null))
            .When(x => x.Orders.Count > 0);

            var result = await validator.ValidateAsync(new Person());

            result.IsValid.ShouldBeTrue();
        }
        public async Task Validates_collection_async()
        {
            var validator      = new InlineValidator <Root>();
            var impl1Validator = new InlineValidator <FooImpl1>();
            var impl2Validator = new InlineValidator <FooImpl2>();

            impl1Validator.RuleFor(x => x.Name).MustAsync((s, token) => Task.FromResult(s != null));
            impl2Validator.RuleFor(x => x.Number).MustAsync((i, token) => Task.FromResult(i > 0));

            validator.RuleForEach(x => x.Foos).SetInheritanceValidator(v => {
                v.Add(impl1Validator)
                .Add(impl2Validator);
            });

            var result = await validator.ValidateAsync(new Root { Foos = { new FooImpl1() } });

            result.Errors.Count.ShouldEqual(1);
            result.Errors[0].PropertyName.ShouldEqual("Foos[0].Name");

            result = await validator.ValidateAsync(new Root { Foos = { new FooImpl2() } });

            result.Errors.Count.ShouldEqual(1);
            result.Errors[0].PropertyName.ShouldEqual("Foos[0].Number");
        }
        public async Task Transforms_collection_element_async()
        {
            var validator = new InlineValidator <Person>();

            validator.TransformForEach(x => x.Orders, order => order.Amount)
            .MustAsync((amt, token) => Task.FromResult(amt > 0));

            var result = await validator.ValidateAsync(new Person()
            {
                Orders = new List <Order> {
                    new Order()
                }
            });

            result.Errors.Count.ShouldEqual(1);
        }
Exemple #13
0
        public async Task Multiple_rules_in_chain_with_childvalidator_shouldnt_reuse_accessor_async()
        {
            var validator     = new InlineValidator <Person>();
            var addrValidator = new InlineValidator <Address>();

            addrValidator.RuleFor(x => x.Line1).MustAsync((l, t) => Task.FromResult(l != null));

            validator.RuleFor(x => x.Address).SetValidator(addrValidator)
            .MustAsync((a, t) => Task.FromResult(a != null));

            var result = await validator.ValidateAsync(new Person()
            {
                Address = new Address()
            });

            result.Errors.Count.ShouldEqual(1);
        }
        public async Task Validates_collection_several_levels_deep_async()
        {
            var validator = new TestValidator {
                v => v.RuleFor(x => x.Surname).NotNull(),
                v => v.RuleForEach(x => x.Orders).SetValidator(y => new OrderValidator(y))
            };

            var rootValidator = new InlineValidator <Tuple <Person, object> >();

            rootValidator.RuleFor(x => x.Item1).SetValidator(validator);

            var results = await rootValidator.ValidateAsync(Tuple.Create(person, new object()));

            results.Errors.Count.ShouldEqual(3);

            results.Errors[1].PropertyName.ShouldEqual("Item1.Orders[0].ProductName");
            results.Errors[2].PropertyName.ShouldEqual("Item1.Orders[2].ProductName");
        }
Exemple #15
0
        public async Task Includes_all_rulesets_async()
        {
            var validator = new InlineValidator <Person>();

            validator.RuleFor(x => x.Forename).MustAsync((x, t) => Task.FromResult(x != null));
            validator.RuleSet("Test1", () => {
                validator.RuleFor(x => x.Surname).MustAsync((x, t) => Task.FromResult(x != null));
            });
            validator.RuleSet("Test2", () => {
                validator.RuleFor(x => x.Age).MustAsync((x, t) => Task.FromResult(x > 0));
            });

            var result = await validator.ValidateAsync(new Person(), options => {
                options.IncludeAllRuleSets();
            });

            result.Errors.Count.ShouldEqual(3);
        }
        public async Task Combines_rulesets_and_explicit_properties_async()
        {
            var validator = new InlineValidator <Person>();

            validator.RuleFor(x => x.Forename).NotNull();
            validator.RuleFor(x => x.Surname).NotNull();
            validator.RuleSet("Test", () => {
                validator.RuleFor(x => x.Age).GreaterThan(0);
            });

            var result = await validator.ValidateAsync(new Person(), options => {
                options.IncludeRuleSets("Test");
                options.IncludeProperties(x => x.Forename);
            });

            result.Errors.Count.ShouldEqual(2);
            result.Errors[0].PropertyName.ShouldEqual("Forename");
            result.Errors[1].PropertyName.ShouldEqual("Age");
        }
Exemple #17
0
        public async Task Collection_async_RunsTasksSynchronously()
        {
            var result         = new List <bool>();
            var validator      = new InlineValidator <Person>();
            var orderValidator = new InlineValidator <Order>();

            orderValidator.RuleFor(x => x.ProductName).MustAsync((x, token) => {
                return(ExclusiveDelay(1)
                       .ContinueWith(t => result.Add(t.Result))
                       .ContinueWith(t => true));
            });

            validator.RuleFor(x => x.Orders).SetCollectionValidator(orderValidator);

            await validator.ValidateAsync(person);

            Assert.NotEmpty(result);
            Assert.All(result, Assert.True);
        }
        public async Task Transforms_collection_element_with_propagated_original_object_async()
        {
            var validator = new InlineValidator <Person>();

            validator.TransformForEach(x => x.Children, (parent, children) => new { ParentName = parent.Surname, Children = children })
            .Must(context => context.ParentName == context.Children.Surname);

            var child = new Person {
                Surname = "Pupa"
            };
            var result = await validator.ValidateAsync(new Person()
            {
                Surname = "Lupa", Children = new List <Person> {
                    child
                }
            });

            result.IsValid.ShouldBeFalse();
            result.Errors.Count.ShouldEqual(1);
        }
        public void New_CustomAsync_within_ruleset()
        {
            var validator = new InlineValidator <Person>();

            validator.RuleSet("foo", () => {
                validator.RuleFor(x => x).CustomAsync(async(x, ctx, cancel) => {
                    ctx.AddFailure("x", "y");
                });
            });

            validator.RuleSet("bar", () => {
                validator.RuleFor(x => x).CustomAsync(async(x, ctx, cancel) => {
                    ctx.AddFailure("x", "y");
                });
            });

            var result = validator.ValidateAsync(new Person(), ruleSet: "foo").Result;

            result.Errors.Count.ShouldEqual(1);
        }
Exemple #20
0
        public async Task Includes_combination_of_rulesets_async()
        {
            var validator = new InlineValidator <Person>();

            validator.RuleFor(x => x.Forename).MustAsync((x, t) => Task.FromResult(x != null));
            validator.RuleSet("Test1", () => {
                validator.RuleFor(x => x.Surname).MustAsync((x, t) => Task.FromResult(x != null));
            });
            validator.RuleSet("Test2", () => {
                validator.RuleFor(x => x.Age).MustAsync((x, t) => Task.FromResult(x > 0));
            });

            var result = await validator.ValidateAsync(new Person(), options => {
                options.IncludeRuleSets("Test1").IncludeRulesNotInRuleSet();
            });

            result.Errors.Count.ShouldEqual(2);
            result.Errors[0].PropertyName.ShouldEqual("Forename");
            result.Errors[1].PropertyName.ShouldEqual("Surname");
        }
Exemple #21
0
        public async Task Resets_state_correctly_between_rules_async()
        {
            var v = new InlineValidator <Person>();

            v.RuleForEach(x => x.NickNames).NotNull();
            v.RuleFor(x => x.Forename).NotNull();

            // The ValidationContext is reinitialized for each item in the collection
            // Specifically, the PropertyChain is reset and modified.
            // After the collection has been validated, the PropertyChain should be reset to its original value.
            // We can test this by checking the final output of the property names for subsequent rules after the RuleForEach.
            var result = await v.ValidateAsync(new Person()
            {
                NickNames = new[] { null, "Foo", null }, Forename = null
            });

            result.Errors.Count.ShouldEqual(3);
            result.Errors[0].PropertyName.ShouldEqual("NickNames[0]");
            result.Errors[1].PropertyName.ShouldEqual("NickNames[2]");
            result.Errors[2].PropertyName.ShouldEqual("Forename");
        }
        public async Task New_CustomAsync_within_ruleset()
        {
            var validator = new InlineValidator <Person>();

            validator.RuleSet("foo", () => {
                validator.RuleFor(x => x).CustomAsync((x, ctx, cancel) => {
                    ctx.AddFailure("x", "y");
                    return(Task.CompletedTask);
                });
            });

            validator.RuleSet("bar", () => {
                validator.RuleFor(x => x).CustomAsync((x, ctx, cancel) => {
                    ctx.AddFailure("x", "y");
                    return(Task.CompletedTask);
                });
            });

            var result = await validator.ValidateAsync(new Person(), v => v.IncludeRuleSets("foo"));

            result.Errors.Count.ShouldEqual(1);
        }
Exemple #23
0
        public async Task Can_access_parent_index_async()
        {
            var personValidator = new InlineValidator <Person>();
            var orderValidator  = new InlineValidator <Order>();

            orderValidator.RuleFor(order => order.ProductName)
            .NotEmpty()
            .WithMessage("{CollectionIndex} must not be empty");

            // Two rules - one for each collection syntax.

            personValidator.RuleFor(x => x.Orders)
            .NotEmpty()
            .ForEach(order => {
                order.SetValidator(orderValidator);
            });

            personValidator.RuleForEach(x => x.Orders).SetValidator(orderValidator);

            var result = await personValidator.ValidateAsync(new Person()
            {
                Orders = new List <Order> {
                    new Order()
                    {
                        ProductName = "foo"
                    },
                    new Order(),
                    new Order()
                    {
                        ProductName = "bar"
                    }
                }
            });

            result.IsValid.ShouldBeFalse();
            result.Errors[0].ErrorMessage.ShouldEqual("1 must not be empty");
            result.Errors[0].ErrorMessage.ShouldEqual("1 must not be empty");
        }
Exemple #24
0
        public async Task Shouldnt_break_with_hashcode_collision_async()
        {
            var v1 = new InlineValidator <Collision1>();
            var v2 = new InlineValidator <Collision2>();

            var v = new InlineValidator <CollisionBase>();

            v.WhenAsync((x, ct) => Task.FromResult(x is Collision1), () => {
                v.RuleFor(x => ((Collision1)x).Name).NotNull();
            });
            v.WhenAsync((x, ct) => Task.FromResult(x is Collision2), () => {
                v.RuleFor(x => ((Collision2)x).Name).NotNull();
            });

            var containerValidator = new InlineValidator <List <CollisionBase> >();

            containerValidator.RuleForEach(x => x).SetValidator(v);

            // shouldn't throw an InvalidCastException.
            await containerValidator.ValidateAsync(new List <CollisionBase> {
                new Collision1(), new Collision2()
            });
        }