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); }
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); }
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(); }
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"); }
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); }
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"); }
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"); }
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); }
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"); }
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); }
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"); }
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() }); }