Пример #1
0
        public async Task ValidateAsyncShouldReturnFailureResultForSingleFailedRule([IntegrationTesting] IGetsValidator validatorFactory)
        {
            var validator = validatorFactory.GetValidator <Person>(typeof(PersonValidatorBuilder));

            var person = new Person
            {
                Name     = null,
                Birthday = new DateTime(2000, 1, 1),
                Pets     = new[] {
                    new Pet {
                        Name         = "Miffles",
                        NumberOfLegs = 4,
                        Type         = "Cat"
                    },
                },
            };

            var result = await validator.ValidateAsync(person).ConfigureAwait(false);

            Assert.Multiple(() =>
            {
                Assert.That(result.Passed, Is.False, "Overall result");
                Assert.That(result.RuleResults,
                            Has.One.Matches <ValidationRuleResult>(r => r.Identifier.MemberName == "Name" && r.Outcome == RuleOutcome.Failed),
                            "Correct failing rule");
            });
        }
Пример #2
0
        public void ValidatingACircularReferenceShouldNotThrowOrTimeOut([IntegrationTesting] IGetsValidator validatorFactory)
        {
            var manifest = new ValidationManifest
            {
                ValidatedType = typeof(Node),
                RootValue     = new ManifestValue
                {
                    ValidatedType    = typeof(Node),
                    IdentityAccessor = obj => ((Node)obj).Identity,
                    Children         = new[] {
                        new ManifestValue
                        {
                            ValidatedType      = typeof(NodeChild),
                            IdentityAccessor   = obj => ((NodeChild)obj).Identity,
                            AccessorFromParent = obj => ((Node)obj).Child,
                        },
                        new ManifestValue
                        {
                            ValidatedType      = typeof(string),
                            AccessorFromParent = obj => ((Node)obj).Name,
                        }
                    }
                }
            };
            var nameValue = manifest.RootValue.Children.Single(x => x.ValidatedType == typeof(string));
            var nameRule  = new ManifestRule(nameValue, new ManifestRuleIdentifier(nameValue, typeof(MatchesRegex)))
            {
                RuleConfiguration = obj => ((MatchesRegex)obj).Pattern = "^Foo",
            };

            nameValue.Rules.Add(nameRule);
            var childValue     = manifest.RootValue.Children.Single(x => x.ValidatedType == typeof(NodeChild));
            var recursiveValue = new RecursiveManifestValue(manifest.RootValue)
            {
                AccessorFromParent = obj => ((NodeChild)obj).Node,
            };

            childValue.Children.Add(recursiveValue);

            var validatedObject = new Node
            {
                Child = new NodeChild
                {
                    Node = new Node
                    {
                        Child = new NodeChild {
                            Node = new Node {
                                Name = "Invalid"
                            }
                        }
                    }
                }
            };

            validatedObject.Child.Node.Child.Node.Child = validatedObject.Child;
            var sut = validatorFactory.GetValidator <Node>(manifest);

            Assert.That(() => sut.ValidateAsync(validatedObject).Wait(300), Is.True, "Validation completes within 300ms");
        }
        /// <summary>
        /// Gets a validator instance for a specified generic type, using a specified manifest model.
        /// The model must describe a validator which is able to validate the object type <typeparamref name="TValidated"/>.
        /// </summary>
        /// <typeparam name="TValidated">The type of object to validate.</typeparam>
        /// <param name="factory">The validator factory.</param>
        /// <param name="manifestModel">The validation manifest model.</param>
        /// <returns>A strongly-typed validator implementation.</returns>
        /// <exception cref="ArgumentNullException">If either <paramref name="factory"/> or <paramref name="manifestModel"/> are <see langword="null"/>.</exception>
        public static IValidator <TValidated> GetValidator <TValidated>(this IGetsValidator factory, ManifestModel.Value manifestModel)
        {
            if (factory is null)
            {
                throw new ArgumentNullException(nameof(factory));
            }

            return((IValidator <TValidated>)factory.GetValidator(manifestModel, typeof(TValidated)));
        }
        public void GetValidatorShouldReturnCorrectGenericValidatorForBuilder(IGetsValidator factory,
                                                                              StubValidator validator)
        {
            Mock.Get(factory)
            .Setup(x => x.GetValidator(typeof(ValidatedObjectBuilder)))
            .Returns(validator);

            Assert.That(() => factory.GetValidator <ValidatedObject>(typeof(ValidatedObjectBuilder)), Is.SameAs(validator));
        }
        public void GetValidatorShouldReturnCorrectGenericValidatorForModel(IGetsValidator factory,
                                                                            StubValidator validator,
                                                                            [ManifestModel] Value model)
        {
            Mock.Get(factory)
            .Setup(x => x.GetValidator(model, typeof(ValidatedObject)))
            .Returns(validator);

            Assert.That(() => factory.GetValidator <ValidatedObject>(model), Is.SameAs(validator));
        }
        /// <summary>
        /// Gets a validator instance for a specified generic type, using a specified validation manifest.
        /// The manifest must describe a validator which is able to validate the object type <typeparamref name="TValidated"/>.
        /// </summary>
        /// <typeparam name="TValidated">The type of object to validate.</typeparam>
        /// <param name="factory">The validator factory.</param>
        /// <param name="manifest">The validation manifest.</param>
        /// <returns>A strongly-typed validator implementation.</returns>
        /// <exception cref="ArgumentNullException">If either <paramref name="factory"/> or <paramref name="manifest"/> are <see langword="null"/>.</exception>
        /// <exception cref="ArgumentException">If <paramref name="manifest"/> does not describe a validator for <typeparamref name="TValidated"/>.</exception>
        public static IValidator <TValidated> GetValidator <TValidated>(this IGetsValidator factory, Manifest.ValidationManifest manifest)
        {
            if (factory is null)
            {
                throw new ArgumentNullException(nameof(factory));
            }
            if (!IsCorrectValidatedType <TValidated>(manifest.ValidatedType))
            {
                throw new ArgumentException(String.Format(GetExceptionMessage("ValidatedTypeMustBeSelectedValidatedType"), typeof(TValidated).Name), nameof(manifest));
            }

            return((IValidator <TValidated>)factory.GetValidator(manifest));
        }
        /// <summary>
        /// Gets a validator instance for a specified generic type, using a specified builder type.
        /// The builder type must implement <see cref="IBuildsValidator{TValidated}"/> for the generic
        /// type <typeparamref name="TValidated"/>.
        /// </summary>
        /// <typeparam name="TValidated">The type of object to validate.</typeparam>
        /// <param name="factory">The validator factory.</param>
        /// <param name="builderType">A type indicating the type of validator-builder service to use.</param>
        /// <returns>A strongly-typed validator implementation.</returns>
        /// <exception cref="ArgumentNullException">If either <paramref name="factory"/> or <paramref name="builderType"/> are <see langword="null"/>.</exception>
        /// <exception cref="ArgumentException">If <paramref name="builderType"/> is not of a type appropriate to validate <typeparamref name="TValidated"/>.</exception>
        public static IValidator <TValidated> GetValidator <TValidated>(this IGetsValidator factory, Type builderType)
        {
            if (factory is null)
            {
                throw new ArgumentNullException(nameof(factory));
            }
            if (!IsCorrectBuilderType <TValidated>(builderType))
            {
                throw new ArgumentException(String.Format(GetExceptionMessage("BuilderTypeMustBeForSelectedValidatedType"), GetBuilderType <TValidated>()), nameof(builderType));
            }

            return((IValidator <TValidated>)factory.GetValidator(builderType));
        }
Пример #8
0
        public async Task ValidateAsyncShouldReturnPassResultForValidObject([IntegrationTesting] IGetsValidator validatorFactory)
        {
            var validator = validatorFactory.GetValidator <Person>(typeof(PersonValidatorBuilder));

            var person = new Person
            {
                Name     = "Bobby",
                Birthday = new DateTime(2000, 1, 1),
                Pets     = new[] {
                    new Pet {
                        Name         = "Miffles",
                        NumberOfLegs = 4,
                        Type         = "Cat"
                    },
                },
            };

            var result = await validator.ValidateAsync(person).ConfigureAwait(false);

            Assert.That(result.Passed, Is.True);
        }
Пример #9
0
        public async Task ForMatchingMemberItemCanFindRulesForTheCorrectItem([IntegrationTesting] IGetsValidator validatorFactory)
        {
            var validator = validatorFactory.GetValidator <Customer>(typeof(CustomerValidatorBuilder));
            var customer  = new Customer
            {
                Person = new Person
                {
                    Name     = "John Smith",
                    Birthday = new DateTime(2000, 1, 1),
                    Pets     = new[] {
                        new Pet {
                            Name = "Pet1"
                        },
                        new Pet {
                            Name = "Pet2"
                        },
                        new Pet {
                            Name = "Pet3"
                        },
                        new Pet {
                            Name = "Pet4"
                        },
                        new Pet {
                            Name = "Pet5"
                        },
                        new Pet {
                            Name = "Pet6"
                        },
                    }
                }
            };

            var result = await validator.ValidateAsync(customer, new ValidationOptions { EnableMessageGeneration = true }).ConfigureAwait(false);

            var expectedPet = customer.Person.Pets.Skip(1).First();

            Assert.That(result.ForMember(x => x.Person).ForMatchingMemberItem(x => x.Pets, expectedPet).ForOnlyThisValue().First().ValidatedValue,
                        Is.SameAs(expectedPet));
        }
Пример #10
0
        public async Task PolymorphicAsShouldThrowIfUsedTwiceInSuccessionFromAResult([IntegrationTesting] IGetsValidator validatorFactory)
        {
            var validator = validatorFactory.GetValidator <Customer>(typeof(CustomerValidatorBuilder));
            var customer  = new FrequentShopper
            {
                Person = new Employee
                {
                    Name     = "John Smith",
                    Birthday = new DateTime(2000, 1, 1),
                    Pets     = new[] {
                        new Pet {
                            Name = "Pet1"
                        },
                        new Pet {
                            Name = "Pet2"
                        },
                        new Pet {
                            Name = "Pet3"
                        },
                        new Pet {
                            Name = "Pet4"
                        },
                        new Pet {
                            Name = "Pet5"
                        },
                        new Pet {
                            Name = "Pet6"
                        },
                    },
                    PayrollNumber = -5,
                },
                LoyaltyPoints = -100,
            };

            var result = await validator.ValidateAsync(customer).ConfigureAwait(false);

            Assert.That(() => result.ForMember(x => x.Person).PolymorphicAs <Employee>().PolymorphicAs <Employee>(),
                        Throws.ArgumentException.And.Message.StartWith("The validation manifest value for the current context must implement IHasPolymorphicTypes"));
        }
Пример #11
0
        public async Task ValidateAsyncShouldReturnPassResultForARulewithADependency([IntegrationTesting] IGetsValidator validatorFactory)
        {
            var validator = validatorFactory.GetValidator <Customer>(typeof(CustomerValidatorBuilder));

            var customer = new Customer
            {
                Person = new Person
                {
                    Name     = "John Smith",
                    Birthday = new DateTime(2000, 1, 1),
                    Pets     = new[] {
                        new Pet {
                            Name         = "Miffles",
                            NumberOfLegs = 4,
                            Type         = "Cat"
                        },
                    },
                }
            };

            var result = await validator.ValidateAsync(customer).ConfigureAwait(false);

            Assert.That(result.Passed, Is.True);
        }
Пример #12
0
        public async Task ValidateAsyncShouldTakeApproximatelyTheCorrectTimeToRunAParallelRuleset([IntegrationTesting] IGetsValidator validatorFactory,
                                                                                                  [NoAutoProperties] Person person)
        {
            var validator = validatorFactory.GetValidator <Person>(typeof(ParallelValidatorBuilder));

            stopwatch.Start();
            await validator.ValidateAsync(person, new ValidationOptions { EnableRuleParallelization = true }).ConfigureAwait(false);

            stopwatch.Stop();

            // Best case time :  [largest of (300, 300, 200, 200)] + 200 + 150 = 650    (represents perfect parallelisation with no overhead)
            // Worst case time:  300 + 300 + 200 + 200             + 200 + 150 = 1350   (represents serial execution, although still no overhead)
            //
            // The total time for validation should be a little over "the best case time".
            // We allow a short grace period because that best case is totally hypothetical and impossible to actually achieve.
            // Even with the grace period, the target time is well below the worst case (representing totally non-parallel execution).
            var bestCaseMilliseconds = 650;

            Assert.That(stopwatch.ElapsedMilliseconds,
                        Is.GreaterThan(bestCaseMilliseconds).And.LessThan(bestCaseMilliseconds + millisecondsGrace),
                        "The validator is expected to take between 650 and 800 milliseconds to complete validation.");
        }
Пример #13
0
        public async Task ValidateAsyncShouldReturnFailureResultForARulewithAFailedDependency([IntegrationTesting] IGetsValidator validatorFactory)
        {
            var validator = validatorFactory.GetValidator <Customer>(typeof(CustomerValidatorBuilder));

            var customer = new Customer
            {
                Person = new Person
                {
                    Name     = "John Smith",
                    Birthday = new DateTime(2000, 1, 1),
                    Pets     = null,
                }
            };

            var result = await validator.ValidateAsync(customer).ConfigureAwait(false);

            Assert.Multiple(() =>
            {
                Assert.That(result.Passed, Is.False, "Result is false");

                var dependencyFailures = result.RuleResults
                                         .Where(x => !x.IsPass && x.Outcome == RuleOutcome.DependencyFailed)
                                         .Select(x => x.Identifier.RuleType)
                                         .ToList();
                var failures = result.RuleResults
                               .Where(x => !x.IsPass && x.Outcome == RuleOutcome.Failed)
                               .Select(x => x.Identifier.RuleType)
                               .ToList();
                Assert.That(failures, Is.EqualTo(new[] { typeof(NotNull) }), "One normal failure and it's the right type");
            });
        }
Пример #14
0
        public async Task ValidateAsyncWithMessageSupportShouldReturnMessagesForAFailingRule([IntegrationTesting] IGetsValidator validatorFactory)
        {
            var validator = validatorFactory.GetValidator <Person>(typeof(PersonValidatorBuilder));
            var person    = new Person
            {
                Name     = "John Smith",
                Birthday = new DateTime(1750, 1, 1),
                Pets     = Array.Empty <Pet>(),
            };

            var result = await validator.ValidateAsync(person, new ValidationOptions { EnableMessageGeneration = true }).ConfigureAwait(false);

            Assert.That(result.RuleResults.Single(x => !x.IsPass).Message,
                        Is.EqualTo("The date 1750-01-01 is invalid. It must equal-to or later than 1900-01-01."));
        }
Пример #15
0
        public async Task RecursiveValidationShouldReturnaResultFromADescendentObjectValidatedUsingTheSameManifestAsAnAncestor([IntegrationTesting] IGetsValidator validatorFactory)
        {
            var manifest = new ValidationManifest
            {
                ValidatedType = typeof(Node),
                RootValue     = new ManifestValue
                {
                    ValidatedType    = typeof(Node),
                    IdentityAccessor = obj => ((Node)obj).Identity,
                    Children         = new[] {
                        new ManifestValue
                        {
                            ValidatedType      = typeof(NodeChild),
                            IdentityAccessor   = obj => ((NodeChild)obj).Identity,
                            AccessorFromParent = obj => ((Node)obj).Child,
                        },
                        new ManifestValue
                        {
                            ValidatedType      = typeof(string),
                            AccessorFromParent = obj => ((Node)obj).Name,
                        }
                    }
                }
            };
            var nameValue = manifest.RootValue.Children.Single(x => x.ValidatedType == typeof(string));
            var nameRule  = new ManifestRule(nameValue, new ManifestRuleIdentifier(nameValue, typeof(MatchesRegex)))
            {
                RuleConfiguration = obj => ((MatchesRegex)obj).Pattern = "^Foo",
            };

            nameValue.Rules.Add(nameRule);
            var childValue     = manifest.RootValue.Children.Single(x => x.ValidatedType == typeof(NodeChild));
            var recursiveValue = new RecursiveManifestValue(manifest.RootValue)
            {
                AccessorFromParent = obj => ((NodeChild)obj).Node,
            };

            childValue.Children.Add(recursiveValue);

            var validatedObject = new Node
            {
                Child = new NodeChild
                {
                    Node = new Node
                    {
                        Child = new NodeChild {
                            Node = new Node {
                                Name = "Invalid"
                            }
                        }
                    }
                }
            };
            var sut = validatorFactory.GetValidator <Node>(manifest);

            var result = await sut.ValidateAsync(validatedObject);

            Assert.That(result, Has.One.Matches <ValidationRuleResult>(r => r.Outcome == RuleOutcome.Failed && Equals(r.ValidatedValue, "Invalid")));
        }
Пример #16
0
        public async Task ValidateAsyncWithMessageSupportShouldReturnAMessageFromARuleThatHasAMessage([IntegrationTesting] IGetsValidator validatorFactory)
        {
            var validator = validatorFactory.GetValidator <Customer>(typeof(CustomerValidatorBuilder));
            var customer  = new Customer
            {
                Person = new Person
                {
                    Name     = "John Smith",
                    Birthday = new DateTime(2000, 1, 1),
                    Pets     = new[] {
                        new Pet {
                            Name = "Pet1"
                        },
                        new Pet {
                            Name = "Pet2"
                        },
                        new Pet {
                            Name = "Pet3"
                        },
                        new Pet {
                            Name = "Pet4"
                        },
                        new Pet {
                            Name = "Pet5"
                        },
                        new Pet {
                            Name = "Pet6"
                        },
                    }
                }
            };

            var result = await validator.ValidateAsync(customer, new ValidationOptions { EnableMessageGeneration = true }).ConfigureAwait(false);

            Assert.That(result.RuleResults.Single(x => !x.IsPass).Message,
                        Is.EqualTo("Nobody may have more than 5 pets."));
        }
Пример #17
0
        public async Task ForMemberAndWithoutSuccessesShouldBeUsableToTraverseToASingleResult([IntegrationTesting] IGetsValidator validatorFactory)
        {
            var validator = validatorFactory.GetValidator <Customer>(typeof(CustomerValidatorBuilder));
            var customer  = new Customer
            {
                Person = new Person
                {
                    Name     = "John Smith",
                    Birthday = new DateTime(2000, 1, 1),
                    Pets     = new[] {
                        new Pet {
                            Name = "Pet1"
                        },
                        new Pet {
                            Name = "Pet2"
                        },
                        new Pet {
                            Name = "Pet3"
                        },
                        new Pet {
                            Name = "Pet4"
                        },
                        new Pet {
                            Name = "Pet5"
                        },
                        new Pet {
                            Name = "Pet6"
                        },
                    }
                }
            };

            var result = await validator.ValidateAsync(customer, new ValidationOptions { EnableMessageGeneration = true }).ConfigureAwait(false);

            Assert.That(result.ForMember(x => x.Person).WithoutSuccesses().Single().Message,
                        Is.EqualTo("Nobody may have more than 5 pets."));
        }
 public void GetValidatorShouldThrowIfBuilderTypeIsNotCorrectForValidatedType(IGetsValidator factory)
 {
     Assert.That(() => factory.GetValidator <ValidatedObject>(typeof(DifferentObjectBuilder)), Throws.ArgumentException);
 }
Пример #19
0
        public async Task ToSerializableResultShouldReturnSameNumberOfRuleResultsAsOriginalResult([IntegrationTesting] IGetsValidator validatorFactory)
        {
            var validator = validatorFactory.GetValidator <Person>(typeof(PersonValidatorBuilder));

            var person = new Person
            {
                Name     = "Bobby",
                Birthday = new DateTime(2000, 1, 1),
                Pets     = new[] {
                    new Pet {
                        Name         = "Miffles",
                        NumberOfLegs = 4,
                        Type         = "Cat"
                    },
                },
            };

            var result = await validator.ValidateAsync(person).ConfigureAwait(false);

            Assert.That(result.ToSerializableResult().RuleResults.Length, Is.EqualTo(result.RuleResults.Count));
        }
 public void GetValidatorShouldThrowIfManifestTypeIsNotCorrectForValidatedType(IGetsValidator factory,
                                                                               [ManifestModel] ValidationManifest manifest)
 {
     manifest.ValidatedType = typeof(string);
     Assert.That(() => factory.GetValidator <ValidatedObject>(manifest), Throws.ArgumentException);
 }
Пример #21
0
        public async Task PolymorphicValidationShouldBeAbleToCreateAnErrorResultForADerivedClass([IntegrationTesting] IGetsValidator validatorFactory)
        {
            var validator = validatorFactory.GetValidator <Customer>(typeof(CustomerValidatorBuilder));
            var customer  = new FrequentShopper
            {
                Person = new Employee
                {
                    Name     = "John Smith",
                    Birthday = new DateTime(2000, 1, 1),
                    Pets     = new[] {
                        new Pet {
                            Name = "Pet1"
                        },
                        new Pet {
                            Name = "Pet2"
                        },
                        new Pet {
                            Name = "Pet3"
                        },
                        new Pet {
                            Name = "Pet4"
                        },
                        new Pet {
                            Name = "Pet5"
                        },
                        new Pet {
                            Name = "Pet6"
                        },
                    },
                    PayrollNumber = -5,
                },
                LoyaltyPoints = -100,
            };

            var result = await validator.ValidateAsync(customer).ConfigureAwait(false);

            Assert.That(result.ForMember(x => x.Person).PolymorphicAs <Employee>().ForMember(x => x.PayrollNumber),
                        Has.One.Matches <ValidationRuleResult>(r => r.Identifier.RuleType == typeof(IntegerInRange) &&
                                                               r.IsPass == false &&
                                                               Equals(r.ValidatedValue, -5)));
        }