public void MemberPath_can_be_set_differently_for_the_same_rule_in_different_contexts()
        {
            var nameNotEmpty =
                Validate.That <Species>(s => !string.IsNullOrEmpty(s.Name));

            var plan = new ValidationPlan <Species>();

            plan.AddRule(nameNotEmpty.ForMember("species"));
            plan.AddRule(
                s => s.Individuals.Every(
                    i => nameNotEmpty.ForMember("subspecies").Check(i.Species)));

            var cat    = new Species();
            var fluffy = new Individual {
                Species = cat
            };

            cat.Individuals.Add(fluffy);
            var report = plan.Execute(cat);

            Console.WriteLine(report);
            Assert.AreEqual(3, report.Failures.Count());
            Assert.AreEqual(1, report.Failures.Where(f => f.MemberPath == "species").Count());
            Assert.AreEqual(1, report.Failures.Where(f => f.MemberPath == "subspecies").Count());
        }
        public void ErrorCode_can_be_set_differently_for_the_same_rule_in_different_contexts()
        {
            var nameNotEmpty =
                Validate
                .That <Species>(s => !string.IsNullOrEmpty(s.Name))
                .WithErrorCode("NameCannotBeEmpty");

            var plan = new ValidationPlan <Species>();

            plan.AddRule(
                s => s.Individuals.Every(
                    i => nameNotEmpty
                    .WithErrorCode("IndividualsSpeciesNameCannotBeEmpty")
                    .Check(i.Species)));
            plan.AddRule(nameNotEmpty.WithErrorCode("SpeciesNameCannotBeEmpty"));

            var cat    = new Species();
            var fluffy = new Individual {
                Species = cat
            };

            cat.Individuals.Add(fluffy);
            var report = plan.Execute(cat);

            Console.WriteLine(report);
            Assert.AreEqual(3, report.Failures.Count());
            Assert.AreEqual(1, report.Failures.Count(f => f.ErrorCode == "SpeciesNameCannotBeEmpty"));
            Assert.AreEqual(1, report.Failures.Count(f => f.ErrorCode == "IndividualsSpeciesNameCannotBeEmpty"));
        }
        public void One_rule_can_be_evaluated_inside_another_without_framework_being_aware_of_it()
        {
            var individualNameRule = Validate.That <Individual>(i => !string.IsNullOrEmpty(i.Name))
                                     .WithErrorCode("Name");
            var speciesNameRule = Validate
                                  .That <Species>(s => !string.IsNullOrEmpty(s.Name))
                                  .WithErrorCode("Name");
            var speciesIndividualsRule = Validate.That <Species>(s => s.Individuals.All(individualNameRule.Check));

            var plan = new ValidationPlan <Species>();

            plan.AddRule(speciesNameRule);
            plan.AddRule(speciesIndividualsRule);

            var cat    = new Species("Felis silvestris");
            var fluffy = new Individual {
                Name = "Fluffy", Species = cat
            };
            var boots = new Individual {
                Name = "Boots", Species = cat
            };

            cat.Individuals.AddRange(new[] { fluffy, boots });

            Assert.IsFalse(plan.Execute(cat).HasFailures);

            // adding an individual without a name causes the plan to evaluate to false
            cat.Individuals.Add(new Individual {
                Species = cat
            });
            var report = plan.Execute(cat);

            Console.WriteLine(report);
            Assert.IsTrue(report.HasFailures);
        }
        public void Rules_can_be_aggregated_from_function_calls()
        {
            var plan = new ValidationPlan <Species>();

            plan.AddRule(Validate.That <Species>(IndividualsAreAllOfSpecies().Check));

            var cat    = new Species("Felis silvestris");
            var fluffy = new Individual {
                Name = "Fluffy", Species = cat
            };
            var boots = new Individual {
                Name = "Boots", Species = cat
            };

            cat.Individuals.AddRange(new[] { fluffy, boots });

            Assert.IsFalse(plan.Execute(cat).HasFailures);

            // adding an individual without a name causes the plan to evaluate to false
            var fido = new Individual {
                Name = "Fido", Species = new Species("Canis familiaris")
            };

            cat.Individuals.Add(fido);

            var report = plan.Execute(cat);

            Assert.IsTrue(report.HasFailures);
            Console.WriteLine(report);
            Assert.AreEqual(3, report.Failures.Count());
            Assert.That(report.Failures.Any(failure => failure.Target == fido));
            Assert.That(report.Failures.Any(failure => failure.Target == cat));
        }
예제 #5
0
        private static void InitializeTwitterPlan()
        {
            isTwitterFreeUrl = new ValidationPlan <string>();
            isTwitterFreeUrl.AddRule(
                s =>
            {
                var client = new WebClient();

                try
                {
                    var response = client.DownloadString(s.As("url"));
                    return(!response.ToLower().Contains("twitter"));
                }
                catch (WebException ex)
                {
                    ex.Message.As("error");
                    return(false);
                }
                catch (Exception ex)
                {
                    ex.As("error");
                    return(false);
                }
            },
                only => only
                .When(isValidHttpUrl)
                .WithErrorMessage("Oh no! The page at {url} contains the word 'twitter'")
                .WithSuccessMessage("The page at {url} doesn't contain the word 'twitter'")
                );
        }
예제 #6
0
        public void When_items_are_validated_in_parallel_the_rule_evaluations_are_reported_correctly()
        {
            DescribeThread();
            var plan = new ValidationPlan <IEnumerable <string> >();

            plan.AddRule(urls => urls.Parallel(url =>
            {
                if (string.IsNullOrWhiteSpace(Thread.CurrentThread.Name))
                {
                    Thread.CurrentThread.Name = url;
                }
                Console.WriteLine(
                    "checking {0} in scope {2} on thread {1} ", url,
                    Thread.CurrentThread.ManagedThreadId,
                    ValidationScope.Current);
                return(isReachableUrl.Check(url));
            }));

            var report = plan.Execute(Urls());

            Console.WriteLine(report);

            Assert.That(report.Evaluations.Count(),
                        Is.GreaterThan(Urls().Count()));
        }
        public void Dependencies_can_be_declared_within_expression_using_Validate_That()
        {
            var plan = new ValidationPlan <IEnumerable <Species> >();

            plan
            .AddRule(list =>
                     list.Every(species =>
                                Validate
                                .That <Species>(s => s.Name.Length < 20)
                                .WithErrorCode("name too long")
                                .When(
                                    Validate
                                    .That <Species>(s => s.Name != null)
                                    .WithErrorCode("name null"))
                                .Check(species)));

            var listToValidate = new[]
            {
                new Species {
                    Name = null
                },
                new Species {
                    Name = "this name is way too "
                }
            };

            var report = plan.Execute(listToValidate);

            Console.WriteLine(report);
            Assert.AreEqual(2, report.Failures.Count());
            Assert.AreEqual(1, report.Failures.Count(f => f.ErrorCode == "name too long"));
        }
        public void ValidationPlan_executes_multiple_rules_and_ValidationFailure_count_is_correct()
        {
            var plan  = new ValidationPlan <Species>();
            var rule1 = Validate.That <Species>(s => s.Name != "cat");
            var rule2 = Validate.That <Species>(s => s.Genus.Name != "felis");

            plan.AddRule(rule1);
            plan.AddRule(rule2);

            var report = plan.Execute(new Species {
                Name = "cat", Genus = new Genus {
                    Name = "felis"
                }
            });

            Assert.AreEqual(2, report.Failures.Count());
        }
        public void ValidationPlans_can_be_combined()
        {
            var plan1 = new ValidationPlan <Species>();

            plan1.AddRule(
                Validate.That <Species>(
                    s =>
                    s.Individuals.Every(
                        i => Validate.That <Individual>(
                            ind => ind.Species == s)
                        .WithErrorCode("species mismatch")
                        .Check(i))
                    )
                );

            var plan2 = new ValidationPlan <Species>();

            plan2.AddRule(
                Validate.That <Species>(
                    s =>
                    s.Individuals.Every(
                        Validate.That <Individual>(
                            ind => !string.IsNullOrEmpty(ind.Name))
                        .WithErrorCode("empty name")
                        .Check)
                    )
                );

            var species = new Species {
                Name = "Felis silvestris"
            };
            var nameless = new Individual {
                Name = "", Species = species
            };

            species.Individuals.Add(nameless);
            species.Individuals.Add(new Individual {
                Name = "Garfield", Species = species
            });
            species.Individuals.Add(new Individual {
                Name = "Morris", Species = species
            });
            var fido = new Individual {
                Name = "Fido"
            };

            species.Individuals.Add(fido);

            var report = ValidationPlan <Species> .Merge(
                new KeyValuePair <string, ValidationPlan <Species> >("one", plan1),
                new KeyValuePair <string, ValidationPlan <Species> >("two", plan2)
                ).Execute(species);

            Assert.That(report.Failures.Count(f => f.ErrorCode == "one"), Is.EqualTo(2));
            Assert.That(report.Failures.Count(f => f.ErrorCode == "two"), Is.EqualTo(2));
            Assert.That(report.Failures.Count(f => f.Target == fido), Is.EqualTo(1));
            Assert.That(report.Failures.Count(f => f.Target == nameless), Is.EqualTo(1));
        }
예제 #10
0
        public void Rules_within_ValidationPlan_can_be_iterated()
        {
            var plan = new ValidationPlan <string>();

            Enumerable.Range(1, 10).ForEach(_AppDomain =>
                                            plan.AddRule(Validate.That <string>(s => false)));

            Assert.AreEqual(10, plan.Count());
        }
예제 #11
0
        public void Nested_Rules_within_ValidationPlan_are_not_iterated_when_plan_is_iterated()
        {
            var plan = new ValidationPlan <string>();

            Enumerable.Range(1, 10).ForEach(_ => plan.AddRule(new ValidationPlan <string>
            {
                Validate.That <string>(s => false),
                Validate.That <string>(s => false)
            }));

            Assert.AreEqual(10, plan.Count());
        }
        public void ValidationFailures_use_MessageGenerator_assigned_to_ValidationPlan()
        {
            var messageGenerator = new MessageTemplate("result");

            var plan = new ValidationPlan <string>(messageGenerator);

            // always fail
            plan.AddRule(s => false);

            var failure = plan.Execute("test").Failures.First();

            failure.Message.Should().Be("result");
        }
        public void ValidationReport_contains_rules_that_were_called()
        {
            var plan = new ValidationPlan <string>();

            for (var i = 0; i < 10; i++)
            {
                var rule = Validate.That <string>(_ => true);
                plan.AddRule(rule);
            }

            var report = plan.Execute(string.Empty);

            Assert.AreEqual(10, report.RulesExecuted.Count());
        }
예제 #14
0
        public void ValidationPlan_evaluates_all_when_strategy_is_EvaluateAll()
        {
            var plan = new ValidationPlan <string>
            {
                Strategy = EvaluationStrategy <string> .EvaluateAll
            };

            for (int i = 0; i < 10; i++)
            {
                plan.AddRule(_ => false);
            }

            Assert.That(plan.Execute(null).Evaluations.Count(),
                        Is.EqualTo(10));
        }
        public void ErrorCode_can_be_declared_using_optional_parameter_on_AddRule()
        {
            var plan = new ValidationPlan <Species>();

            plan.AddRule(s => s.Name.Length < 20,
                         rule => rule.WithErrorCode("oops"));

            var speciesWithLongName = new Species {
                Name = "this name is way too long"
            };

            var reportOnSpeciesWithLongName = plan.Execute(speciesWithLongName);

            Assert.AreEqual("oops", reportOnSpeciesWithLongName.Failures.First().ErrorCode);
        }
예제 #16
0
        public void ValidationPlan_halts_on_first_failure_when_strategy_is_HaltOnFirstFailure()
        {
            // TODO: (ValidationPlan_halts_on_first_failure_when_strategy_is_HaltOnFirstFailure)
            var plan = new ValidationPlan <string>
            {
                Strategy = EvaluationStrategy <string> .HaltOnFirstFailure
            };

            for (int i = 0; i < 10; i++)
            {
                plan.AddRule(_ => false);
            }

            Assert.That(plan.Execute(null).Evaluations.Count(),
                        Is.EqualTo(1));
        }
        public void Nested_validations_can_be_supported()
        {
            ValidationPlan <Account> accountValidator = new ValidationPlan <Account>()
                                                        .ConfigureFromAttributes();
            ValidationPlan <Order> orderValidator = new ValidationPlan <Order>()
                                                    .ConfigureFromAttributes();

            orderValidator.AddRule(o => accountValidator.Check(o.Account));
            var order = new Order {
                Account = new Account()
            };

            ValidationReport report = orderValidator.Execute(order);

            Assert.That(report.Failures.Any(f => f.Message == "What's your name?" && f.Target == order.Account));
            Assert.That(report.Failures.Any(f => f.Message == "You can't place an order for nothing." && f.Target == order));
        }
        public void ValidationScope_raises_events_as_evaluations_are_added_to_child_scopes_on_other_threads()
        {
            int evaluationCount = 0;
            var plan            = new ValidationPlan <IEnumerable <string> >();

            // parallelize
            plan.AddRule(
                ss => ss.Parallel(Validate.That <string>(s => false).Check));

            using (var scope = new ValidationScope())
            {
                scope.RuleEvaluated += (o, e) => Interlocked.Increment(ref evaluationCount);
                plan.Execute(Enumerable.Range(1, 30).Select(i => i.ToString()));
            }

            Assert.AreEqual(31, evaluationCount);
        }
예제 #19
0
        public void Iterative_nested_tasks_can_be_executed_with_short_circuiting()
        {
            var innerRule = Validate.That <Individual>(i => false);
            var plan      = new ValidationPlan <Species>();

            plan.AddRule(s => s.Individuals.All(innerRule.Check));
            var species = new Species();

            species.Individuals.Add(new Individual());
            species.Individuals.Add(new Individual());
            species.Individuals.Add(new Individual());
            species.Individuals.Add(new Individual());

            var task   = plan.ExecuteAsync(species);
            var report = task.Result;

            Assert.That(report.Failures.Count(f => f.Target is Individual), Is.EqualTo(1));
        }
예제 #20
0
        public void Iterative_nested_tasks_are_all_executed()
        {
            var innerRule = Validate.That <Individual>(i => false);
            var plan      = new ValidationPlan <Species>();

            plan.AddRule(s => s.Individuals.Every(innerRule.Check));
            var species = new Species();

            species.Individuals.Add(new Individual());
            species.Individuals.Add(new Individual());
            species.Individuals.Add(new Individual());
            species.Individuals.Add(new Individual());

            var task   = plan.ExecuteAsync(species);
            var report = task.Result;

            Assert.AreEqual(4, report.Failures.Where(f => f.Target is Individual).Count());
        }
예제 #21
0
        public void Iterative_nested_rules_can_be_executed_with_short_circuiting()
        {
            var innerRule = Validate.That <Individual>(i => false);

            var plan = new ValidationPlan <Species>();

            plan.AddRule(s => s.Individuals.All(innerRule.Check));

            var species = new Species();

            species.Individuals.Add(new Individual());
            species.Individuals.Add(new Individual());
            species.Individuals.Add(new Individual());
            species.Individuals.Add(new Individual());

            var report = plan.Execute(species);

            Assert.AreEqual(1, report.Failures.Where(f => f.Target is Individual).Count());
        }
        public void Dependencies_can_be_declared_using_optional_parameter_on_AddRule()
        {
            var plan = new ValidationPlan <Species>();

            plan.AddRule(s => s.Name.Length < 20,
                         only => only.When(s => s.Name != null));

            var speciesWithNullName = new Species {
                Name = null
            };
            var speciesWithLongName = new Species {
                Name = "this name is way too long"
            };

            var reportOnSpeciesWithNullName = plan.Execute(speciesWithNullName);
            var reportOnSpeciesWithLongName = plan.Execute(speciesWithLongName);

            Assert.AreEqual(0, reportOnSpeciesWithNullName.Failures.Count());
            Assert.AreEqual(1, reportOnSpeciesWithLongName.Failures.Count());
        }
예제 #23
0
        public void When_the_same_plan_is_run_on_two_threads_simultaneously_they_each_report_success_and_failure_correctly()
        {
            var barrier = new Barrier(2);
            var plan    = new ValidationPlan <string>();

            plan.AddRule(s =>
            {
                barrier.SignalAndWait();
                return(s != "fail");
            });

            var succeed = Task <ValidationReport> .Factory.StartNew(() => plan.Execute("succeed"));

            var fail = Task <ValidationReport> .Factory.StartNew(() => plan.Execute("fail"));

            succeed.Wait();
            fail.Wait();

            Assert.That(succeed.Result.HasFailures, Is.False);
            Assert.That(fail.Result.HasFailures, Is.True);
        }
예제 #24
0
                /// <summary>
                ///     Specifies an authorization rule for a principal applying a specific command type to a specific resource type.
                /// </summary>
                /// <param name="requirement">The requirement.</param>
                /// <param name="message">A message indicating the reason for the authorization failure. This message is intended for diagnostic and monitoring purposes only.</param>
                public static void Requires(Func <TPrincipal, TCommand, TResource, bool> requirement, string message = null)
                {
                    ValidateTypeParameters();

                    ValidationPlan <IAuthorizationQuery <TResource, TCommand, TPrincipal> > plan = AuthorizationPolicy.For <TResource, TCommand, TPrincipal>().ValidationPlan;

                    var defaultRule = AuthorizationPolicy <TResource, TCommand, TPrincipal> .Default;

                    if (plan.Any(rule => rule == defaultRule))
                    {
                        // the default rule will cause the authz check to fail, so we remove it
                        plan.Remove(defaultRule);
                    }

                    var authzRule = Validate
                                    .That <IAuthorizationQuery <TResource, TCommand, TPrincipal> >(query =>
                                                                                                   requirement(query.Principal, query.Command, query.Resource))
                                    .WithErrorMessage(message ?? ("Requirement for " + typeof(TCommand)));

                    plan.AddRule(authzRule);
                }
        public void Can_customize_message_differently_for_the_same_rule_in_different_plans()
        {
            IValidationMessageGenerator generator1 = new MessageTemplate("one");
            IValidationMessageGenerator generator2 = new MessageTemplate("two");

            var rule = Validate.That <string>(s => false);

            var plan1 = new ValidationPlan <string>(generator1);
            var plan2 = new ValidationPlan <string>(generator2);

            plan1.AddRule(rule);
            plan2.AddRule(rule);

            var report1 = plan1.Execute("");
            var report2 = plan2.Execute("");

            Assert.AreEqual(1, report1.Failures.Count());
            Assert.AreEqual(1, report2.Failures.Count());

            Assert.AreEqual("one", report1.Failures.First().Message);
            Assert.AreEqual("two", report2.Failures.First().Message);
        }
        public void A_rule_can_be_instantiated_and_evaluated_during_another_rules_execution()
        {
            var plan = new ValidationPlan <Species>();

            plan.AddRule(
                s => s.Individuals.Every(
                    Validate.That <Individual>(ind => ind.Species == s).Check));

            Console.WriteLine(plan);

            var cat    = new Species("Felis silvestris");
            var fluffy = new Individual {
                Name = "Fluffy", Species = cat
            };
            var boots = new Individual {
                Name = "Boots", Species = cat
            };

            cat.Individuals.AddRange(new[] { fluffy, boots });

            plan.Execute(cat).HasFailures.Should().BeFalse();

            var fido = new Individual {
                Name = "Fido", Species = new Species("Canis familiaris")
            };

            cat.Individuals.Add(fido);

            var report = plan.Execute(cat);

            Assert.IsTrue(report.HasFailures);
            Console.WriteLine(report);
            Assert.AreEqual(2, report.Failures.Count());
            Assert.That(report.Failures.Any(failure => failure.Target == fido));
            Assert.That(report.Failures.Any(failure => failure.Target == cat));
        }