Exemple #1
0
        public void RemoveRule_ThereAreTwoFailedRules_RemoveOne_ResultChangedShouldBeFiredWithNewResultStillInvalid()
        {
            // ARRANGE
            var dummy = new DummyViewModel();

            var validation = new ValidationHelper();

            validation.AddRule(nameof(dummy.Foo), () => RuleResult.Invalid("error2"));
            var invalidRule = validation.AddRule(nameof(dummy.Foo), () => RuleResult.Invalid("error"));

            var validationResult = validation.ValidateAll();

            Assert.False(validationResult.IsValid);

            bool resultChangedEventFired = false;

            validation.ResultChanged += (sender, args) =>
            {
                Assert.Equal(nameof(dummy.Foo), args.Target);
                Assert.False(args.NewResult.IsValid);

                resultChangedEventFired = true;
            };

            // ACT
            validation.RemoveRule(invalidRule);

            // VERIFY
            Assert.True(resultChangedEventFired);
        }
Exemple #2
0
        private void SetupValidation()
        {
            var validationRules = new ValidationHelper();

            // Simple properties
            validationRules.AddRule(nameof(StringProperty),
                                    () =>
                                    RuleResult.Assert(!string.IsNullOrEmpty(StringProperty),
                                                      "StringProperty cannot be null or empty string"));

            validationRules.AddRule(nameof(IntProperty),
                                    () => RuleResult.Assert(IntProperty > 0, "IntProperty should be greater than zero."));

            // Dependant properties
            validationRules.AddRule(nameof(RangeStart),
                                    nameof(RangeEnd),
                                    () => RuleResult.Assert(RangeEnd > RangeStart, "RangeEnd must be grater than RangeStart"));

            // Long-running validation (simulates call to a web service or something)
            validationRules.AddRule(
                nameof(StringProperty2),
                () =>
            {
                SyncValidationRuleExecutedAsyncroniouslyDelegate?.Invoke();

                return(RuleResult.Assert(!string.IsNullOrEmpty(StringProperty2),
                                         "StringProperty2 cannot be null or empty string"));
            });

            Validation = validationRules;
            DataErrorInfoValidationAdapter = new NotifyDataErrorInfoAdapter(Validation);
        }
Exemple #3
0
        public void Validate_MultipleRulesForSameTarget_DoesNotExecuteRulesIfPerviousFailed()
        {
            // ARRANGE
            var validation = new ValidationHelper();
            var dummy      = new DummyViewModel();

            bool firstRuleExecuted  = false;
            bool secondRuleExecuted = false;

            validation.AddRule(nameof(dummy.Foo),
                               () =>
            {
                firstRuleExecuted = true;
                return(RuleResult.Invalid("Error1"));
            });
            validation.AddRule(nameof(dummy.Foo),
                               () =>
            {
                secondRuleExecuted = true;
                return(RuleResult.Invalid("Error2"));
            });

            // ACT

            validation.ValidateAll();

            // VERIFY

            Assert.True(firstRuleExecuted, "First rule must have been executed");
            Assert.False(secondRuleExecuted, "Second rule should not have been executed because first rule failed.");
        }
Exemple #4
0
        public void RemoveAllRules_HadTwoNegativeRulesRegisteredForDifferentTargets_ResultChangedIsFiredForAllTargets()
        {
            // ARRANGE
            var dummy = new DummyViewModel();

            var validation = new ValidationHelper();

            validation.AddRule(() => dummy.Foo, () => RuleResult.Invalid("error1"));
            validation.AddRule(() => dummy.Bar, () => RuleResult.Invalid("error2"));

            validation.ValidateAll();

            int resultChangedFiredCount = 0;

            validation.ResultChanged += (sender, args) =>
            {
                resultChangedFiredCount++;
            };

            // ACT
            validation.RemoveAllRules();

            // VERIFY
            Assert.Equal(2, resultChangedFiredCount);
        }
Exemple #5
0
        public void Validate_MultipleRulesForSameTarget_ClearsResultsBeforeValidation()
        {
            // ARRANGE
            var validation = new ValidationHelper();
            var dummy      = new DummyViewModel();

            RuleResult firstRuleResult  = RuleResult.Valid();
            RuleResult secondRuleResult = RuleResult.Invalid("Error2");

            validation.AddRule(nameof(dummy.Foo),
                               () => { return(firstRuleResult); });
            validation.AddRule(nameof(dummy.Foo),
                               () => { return(secondRuleResult); });

            // ACT

            validation.ValidateAll();

            firstRuleResult = RuleResult.Invalid("Error1");

            validation.ValidateAll();

            // VERIFY

            var result = validation.GetResult(nameof(dummy.Foo));

            Assert.False(result.IsValid);
            Assert.Equal(1, result.ErrorList.Count);
            Assert.Equal("Error1", result.ErrorList[0].ErrorText);
        }
Exemple #6
0
        public void ResultChanged_ValidateExecutedForSeveralRules_FiresForEachTarget()
        {
            // Arrange
            var validation = new ValidationHelper();
            var dummy      = new DummyViewModel();

            validation.AddRule(nameof(dummy.Foo),
                               () => RuleResult.Invalid("Error"));
            validation.AddRule(nameof(dummy.Foo),
                               RuleResult.Valid);
            validation.AddRule(nameof(dummy.Bar),
                               RuleResult.Valid);
            validation.AddRule(() => RuleResult.Invalid("Error"));

            const int expectedTimesToFire = 0 + 1 /*Invalid Foo*/ + 1 /* Invalid general target */;
            var       eventFiredTimes     = 0;

            validation.ResultChanged += (o, e) => { eventFiredTimes++; };

            // Act
            validation.ValidateAll();

            // Verify
            Assert.Equal(expectedTimesToFire, eventFiredTimes);
        }
Exemple #7
0
        public void RemoveRule_ThisRuleHadValidationError_ResultChangedEventIsFiredForCorrectTargetAndTargetIsValid()
        {
            // ARRANGE
            var validation = new ValidationHelper();

            validation.AddRule(RuleResult.Valid);
            var invalidRule = validation.AddRule("test_target", () => RuleResult.Invalid("error"));

            var validationResult = validation.ValidateAll();

            Assert.False(validationResult.IsValid);

            bool resultChangedEventFired = false;

            validation.ResultChanged += (sender, args) =>
            {
                Assert.Equal("test_target", args.Target);
                Assert.True(args.NewResult.IsValid);

                resultChangedEventFired = true;
            };

            // ACT
            validation.RemoveRule(invalidRule);

            // VERIFY
            Assert.True(resultChangedEventFired);
        }
Exemple #8
0
        public void CombineRuleResults_ResultContainsErrorsFromAllCombinedResults()
        {
            // Arrange
            var validation = new ValidationHelper();

            validation.AddRule(() =>
            {
                //var r1 = RuleResult.Invalid("Error1");
                //var r2 = RuleResult.Valid();
                //var r3 = RuleResult.Invalid("Error2");

                return
                (RuleResult.Assert(false, "Error1").Combine(
                     RuleResult.Assert(true, "Error0")).Combine(
                     RuleResult.Assert(false, "Error2")));

                //return r1.Combine(r2).Combine(r3);
            });

            // Act
            var result = validation.ValidateAll();

            // Assert
            Assert.False(result.IsValid, "The validation must fail");
            Assert.Equal(2, result.ErrorList.Count);
            Assert.True(result.ErrorList.Any(e => e.ErrorText == "Error1"));
            Assert.True(result.ErrorList.Any(e => e.ErrorText == "Error2"));
        }
        public void CombineRuleResults_ResultContainsErrorsFromAllCombinedResults()
        {
            // Arrange
            var validation = new ValidationHelper();
            validation.AddRule(() =>
            {
                //var r1 = RuleResult.Invalid("Error1");
                //var r2 = RuleResult.Valid();
                //var r3 = RuleResult.Invalid("Error2");

                return
                    RuleResult.Assert(false, "Error1").Combine(
                        RuleResult.Assert(true, "Error0")).Combine(
                            RuleResult.Assert(false, "Error2"));

                //return r1.Combine(r2).Combine(r3);
            });

            // Act
            var result = validation.ValidateAll();

            // Assert
            Assert.False(result.IsValid, "The validation must fail");
            Assert.Equal(2, result.ErrorList.Count);
            Assert.True(result.ErrorList.Any(e => e.ErrorText == "Error1"));
            Assert.True(result.ErrorList.Any(e => e.ErrorText == "Error2"));
        }
Exemple #10
0
        public void RemoveAllRules_HadTwoNegativeRulesRegistered_ValidationSucceds()
        {
            // ARRANGE
            var validation = new ValidationHelper();

            validation.AddRule(() => RuleResult.Invalid("error1"));
            validation.AddRule(() => RuleResult.Invalid("error2"));

            // ACT
            validation.RemoveAllRules();

            var validationResult = validation.ValidateAll();

            // VERIFY
            Assert.True(validationResult.IsValid, "Validation should not produce any errors after all rules were removed.");
        }
Exemple #11
0
        public void SyncValidation_SeveralRulesForOneTarget_ValidWhenAllRulesAreValid()
        {
            var vm = new DummyViewModel();

            var validation = new ValidationHelper();

            validation.AddRule(vm, RuleResult.Valid);

            validation.AddRule(vm, () => { return(RuleResult.Invalid("Rule 2 failed")); });

            validation.AddRule(vm, RuleResult.Valid);

            var r = validation.Validate(vm);

            Assert.False(r.IsValid);
        }
Exemple #12
0
        public void AsyncValidation_SyncRule_ExecutedAsyncroniously()
        {
            TestUtils.ExecuteWithDispatcher((dispatcher, completedAction) =>
            {
                var vm = new DummyViewModel();
                vm.Foo = null;

                var validation = new ValidationHelper();

                validation.AddRule(() =>
                {
                    Assert.False(dispatcher.Thread.ManagedThreadId == Thread.CurrentThread.ManagedThreadId,
                                 "Rule must be executed in a background thread.");

                    if (string.IsNullOrEmpty(vm.Foo))
                    {
                        return(RuleResult.Invalid("Foo cannot be empty string."));
                    }

                    return(RuleResult.Valid());
                });

                validation.ValidateAllAsync().ContinueWith(r => completedAction());
            });
        }
Exemple #13
0
        private bool ValidateTokenAddress()
        {
            var validator = new ValidationHelper();

            validator.AddRequiredRule(() => ContractAddress, "Token address is required.");
            var resultOne = validator.ValidateAll();

            if (!resultOne.IsValid)
            {
                Errors = resultOne.ErrorList;

                return(resultOne.IsValid);
            }

            bool isValidAddress;

            try
            {
                isValidAddress = new Regex("^(?=.{42}$)0x[a-fA-F0-9]*").IsMatch(ContractAddress);
            }
            catch (Exception e)
            {
                isValidAddress = false;
            }
            validator.AddRule(ContractAddress, () => RuleResult.Assert(isValidAddress, "Token address is not valid Ethereum smart contract address."));

            var result = validator.ValidateAll();

            Errors = result.ErrorList;

            return(result.IsValid);
        }
 public static void AddErrors(this ValidationHelper validator, string target, List <string> errors)
 {
     errors?.ForEach(it =>
     {
         validator.AddRule(target, () => RuleResult.Invalid($"{target}: {it}"));
     });
 }
Exemple #15
0
        protected override void ConfigureValidationRules(ValidationHelper validationHelper)
        {
            validationHelper.AddRule(
                () => Username,
                () => !string.IsNullOrWhiteSpace(Password) && string.IsNullOrWhiteSpace(Username)
                    ? RuleResult.Invalid("Username is required")
                    : RuleResult.Valid()
                );

            validationHelper.AddRule(
                () => Password,
                () => !string.IsNullOrWhiteSpace(Username) && string.IsNullOrWhiteSpace(Password)
                    ? RuleResult.Invalid("Password is required")
                    : RuleResult.Valid()
                );
        }
Exemple #16
0
        private void ValidateTransaction()
        {
            try
            {
                this._amount = BigDecimal.Parse(this._amountString);
            }
            catch (Exception e)
            {
                this._amount = null;
            }

            var validator = new ValidationHelper();

            validator.AddRequiredRule(() => ReceiverAddress, "Address receiver is required.");
            validator.AddRequiredRule(() => _amount, "Valid amount is required.");
            validator.AddRequiredRule(() => Token, "Select token to send.");

            var resultTemp = validator.ValidateAll();

            if (!resultTemp.IsValid)
            {
                Errors  = resultTemp.ErrorList;
                IsValid = resultTemp.IsValid;
                return;
            }

            bool isValidAddress;

            try
            {
                isValidAddress = new Regex("^(?=.{42}$)0x[a-zA-Z0-9]*").IsMatch(ReceiverAddress);
            }
            catch (Exception e)
            {
                isValidAddress = false;
            }
            validator.AddRule(ReceiverAddress, () => RuleResult.Assert(isValidAddress, "Receiver address is not valid Ethereum account address."));
            validator.AddRule(Amount, () => RuleResult.Assert(this._amount > new BigDecimal(0), "Amount is zero."));
            validator.AddRule(Amount, () => RuleResult.Assert(this._amount < Token.Balance, "You don't have enough funds."));

            var result = validator.ValidateAll();

            Errors = result.ErrorList;

            IsValid = result.IsValid;
        }
Exemple #17
0
        public void RemoveAllRules_HadTwoFailedRules_ErrorGetsRemovedAlso()
        {
            // ARRANGE
            var validation = new ValidationHelper();

            validation.AddRule(() => RuleResult.Invalid("error1"));
            validation.AddRule(() => RuleResult.Invalid("error2"));

            var validationResult = validation.ValidateAll();

            // ACT
            validation.RemoveAllRules();

            validationResult = validation.GetResult();

            // VERIFY
            Assert.True(validationResult.IsValid, "Validation should not produce any errors after all rules were removed.");
        }
Exemple #18
0
        public async void SyncValidation_RuleThrowsException_ExceptionIsPropogated()
        {
            // ARRANGE
            var validator = new ValidationHelper();

            validator.AddRule(() => { throw new InvalidOperationException("Test"); });

            // ACT & VERIFY
            await Assert.ThrowsAsync <ValidationException>(() => validator.ValidateAllAsync());
        }
Exemple #19
0
        public void RemoveRule_ThisRuleHadValidationError_ErrorGetsRemovedAlso()
        {
            // ARRANGE
            var validation = new ValidationHelper();

            validation.AddRule(RuleResult.Valid);
            var invalidRule = validation.AddRule(() => RuleResult.Invalid("error"));

            var validationResult = validation.ValidateAll();

            Assert.False(validationResult.IsValid);

            // ACT
            validation.RemoveRule(invalidRule);

            validationResult = validation.GetResult();

            // VERIFY
            Assert.True(validationResult.IsValid);
        }
Exemple #20
0
        public void Reset_AllTargetsBecomeValidAgain()
        {
            // ARRANGE
            var dummy = new DummyViewModel();

            var validation = new ValidationHelper();

            validation.AddRule(nameof(dummy.Foo), () => RuleResult.Invalid("error1"));
            validation.AddRule(nameof(dummy.Bar), () => RuleResult.Invalid("error2"));

            validation.ValidateAll();

            // ACT
            validation.Reset();

            // VERIFY
            Assert.True(validation.GetResult().IsValid);
            Assert.True(validation.GetResult(nameof(dummy.Foo)).IsValid);
            Assert.True(validation.GetResult(nameof(dummy.Bar)).IsValid);
        }
        public void Validate_MultipleRulesForSameTarget_OptionToAllowValidationOnFailedTargetsIsSetForSpecificRule_ThatRuleIsExecuted()
        {
            // ARRANGE
            var validation = new ValidationHelper();

            var dummy = new DummyViewModel();

            bool firstRuleExecuted  = false;
            bool secondRuleExecuted = false;
            bool thirdRuleExecuted  = false;

            validation.AddRule(nameof(dummy.Foo),
                               () =>
            {
                firstRuleExecuted = true;
                return(RuleResult.Invalid("Error1"));
            });
            validation.AddRule(nameof(dummy.Foo),
                               () =>
            {
                secondRuleExecuted = true;
                return(RuleResult.Invalid("Error2"));
            });

            validation.AddRule(nameof(dummy.Foo),
                               () =>
            {
                thirdRuleExecuted = true;
                return(RuleResult.Invalid("Error3"));
            }).WithSettings(s => s.ExecuteOnAlreadyInvalidTarget = true);

            // ACT

            validation.ValidateAll();

            // VERIFY

            Assert.True(firstRuleExecuted, "First rule must have been executed");
            Assert.False(secondRuleExecuted, "Second rule should not have been executed because first rule failed.");
            Assert.True(thirdRuleExecuted, "Third rule should be executed because it is configured to be executed on already invalid target.");
        }
Exemple #22
0
        public void Reset_ResultChangedFiresForInvalidTargets()
        {
            // ARRANGE
            var dummy = new DummyViewModel();

            var validation = new ValidationHelper();

            validation.AddRule(RuleResult.Valid);
            validation.AddRule(nameof(dummy.Foo), () => RuleResult.Invalid("error1"));
            validation.AddRule(nameof(dummy.Bar), () => RuleResult.Invalid("error2"));

            validation.ValidateAll();

            bool eventFiredForFoo = false;
            bool evernFiredForBar = false;

            validation.ResultChanged += (sender, args) =>
            {
                if (Equals(args.Target, nameof(dummy.Foo)))
                {
                    eventFiredForFoo = true;
                }
                else if (Equals(args.Target, nameof(dummy.Bar)))
                {
                    evernFiredForBar = true;
                }
                else
                {
                    Assert.False(true, "ResultChanged event fired for an unexpected target.");
                }

                Assert.True(args.NewResult.IsValid);
            };

            // ACT
            validation.Reset();

            // VERIFY
            Assert.True(eventFiredForFoo);
            Assert.True(evernFiredForBar);
        }
Exemple #23
0
        public void RemoveRule_ReExecuteValidation_RemovedRuleDoesNotExecute()
        {
            // ARRANGE
            var validation = new ValidationHelper();

            validation.AddRule(RuleResult.Valid);
            var invalidRule = validation.AddRule(() => RuleResult.Invalid("error"));

            var validationResult = validation.ValidateAll();

            Assert.False(validationResult.IsValid);


            // ACT
            validation.RemoveRule(invalidRule);

            validationResult = validation.ValidateAll();

            // VERIFY
            Assert.True(validationResult.IsValid);
        }
Exemple #24
0
        public void ResultChanged_RuleErrorsChangedButRuleValidityDidNotChange_EventStillFires()
        {
            // ARRANGE
            var validation = new ValidationHelper();
            var dummy      = new DummyViewModel();

            validation.AddRule(() => dummy.Foo,
                               () =>
            {
                if (string.IsNullOrEmpty(dummy.Foo))
                {
                    return(RuleResult.Invalid("Foo should not be empty"));
                }

                return
                (RuleResult.Assert(dummy.Foo.Length > 5, "Length must be greater than 5").Combine(
                     RuleResult.Assert(dummy.Foo.Any(Char.IsDigit), "Must contain digit")));
            });

            var       resultChangedCalledTimes   = 0;
            const int expectedResultChangedCalls = 1 /* First invalid value */ + 1 /* Second invalid value */ + 1 /* Third invalid value */ + 1 /* Valid value */;

            validation.ResultChanged += (o, e) =>
            {
                resultChangedCalledTimes++;
            };

            // ACT

            dummy.Foo = null;

            // Should generage "Foo should not be empty" error
            validation.ValidateAll();

            dummy.Foo = "123";

            // Should generate the "Length must be greater than 5" error
            validation.ValidateAll();

            dummy.Foo = "sdfldlssd";

            // Should generate the "Must contain digit" error
            validation.ValidateAll();

            dummy.Foo = "lsdklfjsld2342";

            // Now should be valid
            validation.ValidateAll();

            // VERIFY
            Assert.Equal(expectedResultChangedCalls, resultChangedCalledTimes);
        }
Exemple #25
0
        private void ValidateToken()
        {
            var validator = new ValidationHelper();

            validator.AddRequiredRule(() => TokenName, "Token name is required.");
            validator.AddRequiredRule(() => TokenSymbol, "Token symbol is required.");
            validator.AddRequiredRule(() => Decimals, "Token decimals is required.");

            if (!string.IsNullOrWhiteSpace(Decimals))
            {
                var isValid = int.TryParse(Decimals, out int temp);
                validator.AddRule(ContractAddress, () => RuleResult.Assert(temp >= 0, "Decimals must be greater than zero."));
                validator.AddRule(ContractAddress, () => RuleResult.Assert(isValid, "Decimals must be valid number."));
            }


            var result = validator.ValidateAll();

            Errors = result.ErrorList;

            IsValid = result.IsValid;
        }
Exemple #26
0
        public void Validate_ValidationResultIsValid_ToStringReturnsEmptyString()
        {
            // ARRANGE
            var validation = new ValidationHelper();

            validation.AddRule(RuleResult.Valid);

            // ACT
            var r = validation.ValidateAll();

            // VERIFY
            Assert.True(r.ToString() == string.Empty);
        }
        public void Validate_MultipleRulesForSameTarget_OptionToAllowValidationOnFailedTargetsIsSetGlobally_AllRulesAreExecuted()
        {
            // ARRANGE
            var validation = new ValidationHelper(new ValidationSettings
            {
                DefaultRuleSettings = new ValidationRuleSettings
                {
                    ExecuteOnAlreadyInvalidTarget = true
                }
            });

            var dummy = new DummyViewModel();

            bool firstRuleExecuted  = false;
            bool secondRuleExecuted = false;

            validation.AddRule(nameof(dummy.Foo),
                               () =>
            {
                firstRuleExecuted = true;
                return(RuleResult.Invalid("Error1"));
            });
            validation.AddRule(nameof(dummy.Foo),
                               () =>
            {
                secondRuleExecuted = true;
                return(RuleResult.Invalid("Error2"));
            });

            // ACT

            validation.ValidateAll();

            // VERIFY

            Assert.True(firstRuleExecuted, "First rule must have been executed");
            Assert.True(secondRuleExecuted, "Second rule should be executed as well even though the target is already invalid.");
        }
Exemple #28
0
        public void Validate_ThereAreAsyncRules_ThrowsException()
        {
            // ARRANGE
            var validation = new ValidationHelper();

            // Add a simple sync rule
            validation.AddRule(RuleResult.Valid);

            // Add an async rule
            validation.AddAsyncRule(() => Task.Run(() => RuleResult.Invalid("Error")));

            // ACT
            Assert.Throws <InvalidOperationException>(() => { validation.ValidateAll(); });
        }
Exemple #29
0
        public void AsyncValidation_MixedAsyncAndNotAsyncRules_AllExecutedBeforeValidationCompleted()
        {
            TestUtils.ExecuteWithDispatcher((dispatcher, completedAction) =>
            {
                var vm = new DummyViewModel();

                var validation = new ValidationHelper();

                bool rule1Executed = false;

                validation.AddAsyncRule(vm, () =>
                {
                    return(Task.Run(() =>
                    {
                        rule1Executed = true;
                        return RuleResult.Valid();
                    }));
                });

                bool rule2Executed = false;

                validation.AddRule(vm, () =>
                {
                    rule2Executed = true;
                    return(RuleResult.Valid());
                });

                bool rule3Executed = false;

                validation.AddAsyncRule(vm, () =>
                {
                    return(Task.Run(() =>
                    {
                        rule3Executed = true;
                        return RuleResult.Valid();
                    }));
                });

                validation.ValidateAllAsync().ContinueWith(r =>
                {
                    Assert.True(rule1Executed);
                    Assert.True(rule2Executed);
                    Assert.True(rule3Executed);
                    Assert.True(r.Result.IsValid);

                    completedAction();
                });
            });
        }
        private bool ValidateMnemonicPhrase()
        {
            var validator = new ValidationHelper();

            validator.AddRequiredRule(() => this.InputMnemonic, "Mnemonic phrase is required.");
            foreach (var func in Validators)
            {
                validator.AddRule(nameof(this.InputMnemonic), () => RuleResult.Assert(func.Value(InputMnemonic), func.Key));
            }

            var result = validator.ValidateAll();

            Errors = result.ErrorList;

            return(result.IsValid);
        }
        private bool Validate()
        {
            ValidationHelper validator = new ValidationHelper();

            validator.AddRequiredRule(() => ReminderDay, LocalizationManager.GetString("reminder_date_required"));
            validator.AddRequiredRule(() => ReminderTime, LocalizationManager.GetString("reminder_time_required"));
            validator.AddRequiredRule(() => SelectedReminder.Title, LocalizationManager.GetString("reminder_title_required"));

            validator.AddRule("MinimumDate", () =>
            {
                bool condition = true;

                if (_reminderDay.HasValue && !string.IsNullOrEmpty(_reminderTime))
                {
                    var day = _reminderDay.Value;

                    var timeElements = _reminderTime.Split(':');
                    if (timeElements.Length >= 2)
                    {
                        int hour = -1, minute = -1;
                        if (int.TryParse(timeElements[0], out hour))
                        {
                            if (int.TryParse(timeElements[1], out minute))
                            {
                                DateTime newDate = new DateTime(day.Year, day.Month, day.Day, hour, minute, 0, DateTimeKind.Local);
                                newDate          = newDate.ToUniversalTime();

                                long unixDateTime      = ((DateTimeOffset)newDate).ToUnixTimeSeconds();
                                _selectedReminder.Date = unixDateTime;

                                condition = _selectedReminder.Date > ((DateTimeOffset)DateTime.UtcNow).ToUnixTimeSeconds();
                            }
                        }
                    }
                }

                return(RuleResult.Assert(condition, LocalizationManager.GetString("date_time_not_past_error")));
            });

            var result = validator.ValidateAll();

            Errors = result.AsObservableDictionary();

            return(result.IsValid);
        }
		public void SyncValidation_SeveralRulesForOneTarget_ValidWhenAllRulesAreValid()
		{
			var vm = new DummyViewModel();

			var validation = new ValidationHelper();

			validation.AddRule(vm, RuleResult.Valid);

			validation.AddRule(vm, () =>
			{
				return RuleResult.Invalid("Rule 2 failed");
			});

			validation.AddRule(vm, RuleResult.Valid);

			var r = validation.Validate(vm);

			Assert.False(r.IsValid);
		}
		public void AsyncValidation_SyncRule_ExecutedAsyncroniously()
		{
			TestUtils.ExecuteWithDispatcher((dispatcher, completedAction) =>
			{
				var vm = new DummyViewModel();
				vm.Foo = null;

				var validation = new ValidationHelper();

				validation.AddRule(() =>
				{
					Assert.False(dispatcher.Thread.ManagedThreadId == Thread.CurrentThread.ManagedThreadId,
					               "Rule must be executed in a background thread.");

					if (string.IsNullOrEmpty(vm.Foo))
					{
						return RuleResult.Invalid("Foo cannot be empty string.");
					}

					return RuleResult.Valid();

				});

				validation.ValidateAllAsync().ContinueWith(r => completedAction());
			});
		}
		public void ValidateAsync_MultipleRulesForSameTarget_DoesNotExecuteRulesIfPerviousFailed()
		{
			TestUtils.ExecuteWithDispatcher((uiThreadDispatcher, completedAction) =>
			{
				// ARRANGE
				var validation = new ValidationHelper();
				var dummy = new DummyViewModel();

				bool firstRuleExecuted = false;
				bool secondRuleExecuted = false;

				validation.AddRule(() => dummy.Foo,
				                   () =>
				                   {
				                   	firstRuleExecuted = true;
				                   	return RuleResult.Invalid("Error1");
				                   });

				validation.AddAsyncRule(() => dummy.Foo,
				                        onCompleted =>
				                        {
				                        	secondRuleExecuted = true;
				                        	onCompleted(RuleResult.Invalid("Error2"));
				                        });

				// ACT

				validation.ValidateAllAsync().ContinueWith(result =>
				{
					// VERIFY

					Assert.True(firstRuleExecuted, "First rule must have been executed");
					Assert.False(secondRuleExecuted, "Second rule should not have been executed because first rule failed.");

					completedAction();
				});
			});
		}
        public void ValidationResultChanged_ValidateExecutedForOneRule_FiresOneTime()
        {
            // Arrange
            var validation = new ValidationHelper();
            var dummy = new DummyViewModel();

            validation.AddRule(() => dummy.Foo,
                               () => RuleResult.Invalid("Error"));

            var eventFiredTimes = 0;

            validation.ResultChanged += (o, e) =>
            {
                eventFiredTimes++;
            };

            // Act
            validation.ValidateAll();

            // Verity
            Assert.Equal(1, eventFiredTimes);
        }
        public void Reset_AllTargetsBecomeValidAgain()
        {
            // ARRANGE
            var dummy = new DummyViewModel();

            var validation = new ValidationHelper();
            validation.AddRule(() => dummy.Foo, () => RuleResult.Invalid("error1"));
            validation.AddRule(() => dummy.Bar, () => RuleResult.Invalid("error2"));

            validation.ValidateAll();

            // ACT
            validation.Reset();

            // VERIFY
            Assert.True(validation.GetResult().IsValid);
            Assert.True(validation.GetResult(() => dummy.Foo).IsValid);
            Assert.True(validation.GetResult(() => dummy.Bar).IsValid);
        }
        public void RemoveAllRules_HadTwoNegativeRulesRegisteredForDifferentTargets_ResultChangedIsFiredForAllTargets()
        {
            // ARRANGE
            var dummy = new DummyViewModel();

            var validation = new ValidationHelper();
            validation.AddRule(() => dummy.Foo, () => RuleResult.Invalid("error1"));
            validation.AddRule(() => dummy.Bar, () => RuleResult.Invalid("error2"));

            validation.ValidateAll();

            int resultChangedFiredCount = 0;

            validation.ResultChanged += (sender, args) =>
            {
                resultChangedFiredCount++;
            };

            // ACT
            validation.RemoveAllRules();

            // VERIFY
            Assert.Equal(2, resultChangedFiredCount);
        }
        public void Validate_MultipleRulesForSameTarget_OptionToAllowValidationOnFailedTargetsIsSetForSpecificRule_ThatRuleIsExecuted()
        {
            // ARRANGE
            var validation = new ValidationHelper();

            var dummy = new DummyViewModel();

            bool firstRuleExecuted = false;
            bool secondRuleExecuted = false;
            bool thirdRuleExecuted = false;

            validation.AddRule(nameof(dummy.Foo),
                () =>
                {
                    firstRuleExecuted = true;
                    return RuleResult.Invalid("Error1");
                });
            validation.AddRule(nameof(dummy.Foo),
                () =>
                {
                    secondRuleExecuted = true;
                    return RuleResult.Invalid("Error2");
                });

            validation.AddRule(nameof(dummy.Foo),
                () =>
                {
                    thirdRuleExecuted = true;
                    return RuleResult.Invalid("Error3");
                }).WithSettings(s => s.ExecuteOnAlreadyInvalidTarget = true);

            // ACT

            validation.ValidateAll();

            // VERIFY

            Assert.True(firstRuleExecuted, "First rule must have been executed");
            Assert.False(secondRuleExecuted, "Second rule should not have been executed because first rule failed.");
            Assert.True(thirdRuleExecuted, "Third rule should be executed because it is configured to be executed on already invalid target.");
        }
        public void Validate_MultipleRulesForSameTarget_OptionToAllowValidationOnFailedTargetsIsSetGlobally_AllRulesAreExecuted()
        {
            // ARRANGE
            var validation = new ValidationHelper(new ValidationSettings
            {
                DefaultRuleSettings = new ValidationRuleSettings
                {
                    ExecuteOnAlreadyInvalidTarget = true
                }
            });

            var dummy = new DummyViewModel();

            bool firstRuleExecuted = false;
            bool secondRuleExecuted = false;

            validation.AddRule(nameof(dummy.Foo),
                () =>
                {
                    firstRuleExecuted = true;
                    return RuleResult.Invalid("Error1");
                });
            validation.AddRule(nameof(dummy.Foo),
                () =>
                {
                    secondRuleExecuted = true;
                    return RuleResult.Invalid("Error2");
                });

            // ACT

            validation.ValidateAll();

            // VERIFY

            Assert.True(firstRuleExecuted, "First rule must have been executed");
            Assert.True(secondRuleExecuted, "Second rule should be executed as well even though the target is already invalid.");
        }
        public void ResultChanged_RuleErrorsChangedButRuleValidityDidNotChange_EventStillFires()
        {
            // ARRANGE
            var validation = new ValidationHelper();
            var dummy = new DummyViewModel();

            validation.AddRule(() => dummy.Foo,
                () =>
                {
                    if (string.IsNullOrEmpty(dummy.Foo))
                    {
                        return RuleResult.Invalid("Foo should not be empty");
                    }

                    return
                        RuleResult.Assert(dummy.Foo.Length > 5, "Length must be greater than 5").Combine(
                            RuleResult.Assert(dummy.Foo.Any(Char.IsDigit), "Must contain digit"));
                });

            var resultChangedCalledTimes = 0;
            const int expectedResultChangedCalls = 1 /* First invalid value */+ 1 /* Second invalid value */+ 1 /* Third invalid value */ + 1 /* Valid value */;

            validation.ResultChanged += (o, e) =>
            {
                resultChangedCalledTimes++;
            };

            // ACT

            dummy.Foo = null;

            // Should generage "Foo should not be empty" error
            validation.ValidateAll();

            dummy.Foo = "123";

            // Should generate the "Length must be greater than 5" error
            validation.ValidateAll();

            dummy.Foo = "sdfldlssd";

            // Should generate the "Must contain digit" error
            validation.ValidateAll();

            dummy.Foo = "lsdklfjsld2342";

            // Now should be valid
            validation.ValidateAll();

            // VERIFY
            Assert.Equal(expectedResultChangedCalls, resultChangedCalledTimes);
        }
        public void ResultChanged_ValidateExecutedForSeveralRules_FiresForEachTarget()
        {
            // Arrange
            var validation = new ValidationHelper();
            var dummy = new DummyViewModel();

            validation.AddRule(() => dummy.Foo,
                               () => RuleResult.Invalid("Error"));
            validation.AddRule(() => dummy.Foo,
                               RuleResult.Valid);
            validation.AddRule(() => dummy.Bar,
                                RuleResult.Valid);
            validation.AddRule(() => RuleResult.Invalid("Error"));

            const int expectedTimesToFire = 0 + 1 /*Invalid Foo*/+ 1 /* Invalid general target */;
            var eventFiredTimes = 0;

            validation.ResultChanged += (o, e) =>
            {
                eventFiredTimes++;
            };

            // Act
            validation.ValidateAll();

            // Verify
            Assert.Equal(expectedTimesToFire, eventFiredTimes);
        }
		public void ValidateAllAsync_SimilteniousCalls_DoesNotFail()
		{
			TestUtils.ExecuteWithDispatcher((dispatcher, completedAction) =>
			{
				const int numThreadsPerIternation = 4;
				const int iterationCount = 10;
				const int numThreads = numThreadsPerIternation * iterationCount;
				var resetEvent = new ManualResetEvent(false);
				int toProcess = numThreads;

				var validation = new ValidationHelper();

				for (int i = 0; i < iterationCount; i++)
				{
					var target1 = new object();
					var target2 = new object();

					validation.AddAsyncRule(setResult =>
					{
						setResult(RuleResult.Invalid("Error1"));
					});

					validation.AddAsyncRule(target1, setResult =>
					{
						setResult(RuleResult.Valid());
					});

					validation.AddRule(target2, () =>
					{
						return RuleResult.Invalid("Error2");
					});

					validation.AddRule(target2, RuleResult.Valid);

					Action<Action> testThreadBody = exercise =>
					{
						try
						{
							exercise();

							if (Interlocked.Decrement(ref toProcess) == 0)
								resetEvent.Set();
						}
						catch (Exception ex)
						{
							dispatcher.BeginInvoke(new Action(() =>
							{
								throw new AggregateException(ex);
							}));
						}
					};

					var thread1 = new Thread(() =>
					{
						testThreadBody(() =>
						{
							validation.ValidateAllAsync().Wait();
						});
					});

					var thread2 = new Thread(() =>
					{
						testThreadBody(() =>
						{
							validation.ValidateAllAsync().Wait();
						});
					});

					var thread3 = new Thread(() =>
					{
						testThreadBody(() =>
						{
							validation.Validate(target2);
						});
					});

					var thread4 = new Thread(() =>
					{
						testThreadBody(() =>
						{
							validation.Validate(target2);
						});
					});

					thread1.Start();
					thread2.Start();
					thread3.Start();
					thread4.Start();
				}

				ThreadPool.QueueUserWorkItem(_ =>
				{
					resetEvent.WaitOne();
					completedAction();
				});

			});
		}
        public void ResultChanged_CorrectingValidationError_EventIsFiredForWithValidResultAfterCorrection()
        {
            // ARRANGE
            var validation = new ValidationHelper();
            var dummy = new DummyViewModel();

            var fooResult = RuleResult.Valid();

            // ReSharper disable AccessToModifiedClosure // Intended
            validation.AddRule(() => dummy.Foo, () => fooResult);
            // ReSharper restore AccessToModifiedClosure

            var onResultChanged = new Action<ValidationResultChangedEventArgs>(r => { });

            // ReSharper disable AccessToModifiedClosure // Intended
            validation.ResultChanged += (o, e) => onResultChanged(e);
            // ReSharper restore AccessToModifiedClosure

            // ACT & VERIFY

            // First, verify that the event is fired with invalid result

            fooResult = RuleResult.Invalid("Error");

            onResultChanged = r =>
            {
                Assert.False(r.NewResult.IsValid, "ResultChanged must be fired with invalid result first.");
            };
            validation.ValidateAll();

            // Second, verify that after second validation when error was corrected, the event fires with the valid result

            fooResult = RuleResult.Valid();

            onResultChanged = r =>
            {
                Assert.True(r.NewResult.IsValid, "ResultChanged must be fired with valid result after succesfull validation.");
            };

            validation.ValidateAll();
        }
        public void Reset_ResultChangedFiresForInvalidTargets()
        {
            // ARRANGE
            var dummy = new DummyViewModel();

            var validation = new ValidationHelper();
            validation.AddRule(RuleResult.Valid);
            validation.AddRule(() => dummy.Foo, () => RuleResult.Invalid("error1"));
            validation.AddRule(() => dummy.Bar, () => RuleResult.Invalid("error2"));

            validation.ValidateAll();

            bool eventFiredForFoo = false;
            bool evernFiredForBar = false;

            validation.ResultChanged += (sender, args) =>
            {
                if (Equals(args.Target, PropertyName.For(() => dummy.Foo)))
                {
                    eventFiredForFoo = true;
                }
                else if (Equals(args.Target, PropertyName.For(() => dummy.Bar)))
                {
                    evernFiredForBar = true;
                }
                else
                {
                    Assert.False(true, "ResultChanged event fired for an unexpected target.");
                }

                Assert.True(args.NewResult.IsValid);
            };

            // ACT
            validation.Reset();

            // VERIFY
            Assert.True(eventFiredForFoo);
            Assert.True(evernFiredForBar);
        }
		public void AsyncValidation_MixedAsyncAndNotAsyncRules_AllExecutedBeforeValidationCompleted()
		{
			TestUtils.ExecuteWithDispatcher((dispatcher, completedAction) =>
			{
				var vm = new DummyViewModel();

				var validation = new ValidationHelper();

				bool rule1Executed = false;

				validation.AddAsyncRule(vm, setResultDelegate => ThreadPool.QueueUserWorkItem(_ =>
				{
					rule1Executed = true;
					setResultDelegate(RuleResult.Valid());
				}));

				bool rule2Executed = false;

				validation.AddRule(vm, () =>
				{
					rule2Executed = true;
					return RuleResult.Valid();
				});

				bool rule3Executed = false;

				validation.AddAsyncRule(vm, setResultDelegate => ThreadPool.QueueUserWorkItem(_ =>
				{
					rule3Executed = true;
					setResultDelegate(RuleResult.Valid());
				}));

				validation.ValidateAllAsync().ContinueWith(r =>
				{
					Assert.True(rule1Executed);
					Assert.True(rule2Executed);
					Assert.True(rule3Executed);
					Assert.True(r.Result.IsValid);

					completedAction();
				});
			});
		}
        public void Validate_ThereAreAsyncRules_ThrowsException()
        {
            // ARRANGE
            var validation = new ValidationHelper();

            // Add a simple sync rule
            validation.AddRule(RuleResult.Valid);

            // Add an async rule
            validation.AddAsyncRule(onCompleted => onCompleted(RuleResult.Invalid("Error")));

            // ACT
            Assert.Throws<InvalidOperationException>(() =>
                {
                    validation.ValidateAll();
                });
        }
        public void RemoveAllRules_HadTwoNegativeRulesRegistered_ValidationSucceds()
        {
            // ARRANGE
            var validation = new ValidationHelper();
            validation.AddRule(() => RuleResult.Invalid("error1"));
            validation.AddRule(() => RuleResult.Invalid("error2"));

            // ACT
            validation.RemoveAllRules();

            var validationResult = validation.ValidateAll();

            // VERIFY
            Assert.True(validationResult.IsValid, "Validation should not produce any errors after all rules were removed.");
        }
        public void Validate_ValidationResultIsValid_ToStringReturnsEmptyString()
        {
            // ARRANGE
            var validation = new ValidationHelper();
            validation.AddRule(RuleResult.Valid);

            // ACT
            var r = validation.ValidateAll();

            // VERIFY
            Assert.True(r.ToString() == string.Empty);
        }
        public void RemoveAllRules_HadTwoFailedRules_ErrorGetsRemovedAlso()
        {
            // ARRANGE
            var validation = new ValidationHelper();
            validation.AddRule(() => RuleResult.Invalid("error1"));
            validation.AddRule(() => RuleResult.Invalid("error2"));

            var validationResult = validation.ValidateAll();

            // ACT
            validation.RemoveAllRules();

            validationResult = validation.GetResult();

            // VERIFY
            Assert.True(validationResult.IsValid, "Validation should not produce any errors after all rules were removed.");
        }
        public void ValidationCompleted_ValidateRuleWithMultipleTargets_ResultContainsErrorsForAllTargsts()
        {
            // Arrange
            var validation = new ValidationHelper();
            var dummy = new DummyViewModel();
            validation.AddRule(() => dummy.Foo, () => dummy.Bar,
                               () =>
                               {
                                   return RuleResult.Invalid("Error");
                               });

            // Act
            var result = validation.ValidateAll();

            // Assert
            Assert.False(result.IsValid);

            Assert.True(result.ErrorList.Count == 2, "There must be two errors: one for each property target");
            Assert.True(Equals(result.ErrorList[0].Target, "dummy.Foo"), "Target for the first error must be dummy.Foo");
            Assert.True(Equals(result.ErrorList[1].Target, "dummy.Bar"), "Target for the second error must be dummy.Bar");
        }
        public void Validate_MultipleRulesForSameTarget_ClearsResultsBeforeValidation()
        {
            // ARRANGE
            var validation = new ValidationHelper();
            var dummy = new DummyViewModel();

            RuleResult firstRuleResult = RuleResult.Valid();
            RuleResult secondRuleResult = RuleResult.Invalid("Error2");

            validation.AddRule(() => dummy.Foo,
                               () =>
                               {
                                   return firstRuleResult;
                               });
            validation.AddRule(() => dummy.Foo,
                               () =>
                               {
                                   return secondRuleResult;
                               });

            // ACT

            validation.ValidateAll();

            firstRuleResult = RuleResult.Invalid("Error1");

            validation.ValidateAll();

            // VERIFY

            var result = validation.GetResult(() => dummy.Foo);

            Assert.False(result.IsValid);
            Assert.Equal(1, result.ErrorList.Count);
            Assert.Equal("Error1", result.ErrorList[0].ErrorText);
        }
        public void RemoveRule_ThisRuleHadValidationError_ResultChangedEventIsFiredForCorrectTargetAndTargetIsValid()
        {
            // ARRANGE
            var validation = new ValidationHelper();

            validation.AddRule(RuleResult.Valid);
            var invalidRule = validation.AddRule("test_target", () => RuleResult.Invalid("error"));

            var validationResult = validation.ValidateAll();

            Assert.False(validationResult.IsValid);

            bool resultChangedEventFired = false;

            validation.ResultChanged += (sender, args) =>
            {
                Assert.Equal("test_target", args.Target);
                Assert.True(args.NewResult.IsValid);

                resultChangedEventFired = true;
            };

            // ACT
            validation.RemoveRule(invalidRule);

            // VERIFY
            Assert.True(resultChangedEventFired);
        }
        public void RemoveRule_ReExecuteValidation_RemovedRuleDoesNotExecute()
        {
            // ARRANGE
            var validation = new ValidationHelper();

            validation.AddRule(RuleResult.Valid);
            var invalidRule = validation.AddRule(() => RuleResult.Invalid("error"));

            var validationResult = validation.ValidateAll();

            Assert.False(validationResult.IsValid);

            // ACT
            validation.RemoveRule(invalidRule);

            validationResult = validation.ValidateAll();

            // VERIFY
            Assert.True(validationResult.IsValid);
        }
        public void Validate_MultipleRulesForSameTarget_DoesNotExecuteRulesIfPerviousFailed()
        {
            // ARRANGE
            var validation = new ValidationHelper();
            var dummy = new DummyViewModel();

            bool firstRuleExecuted = false;
            bool secondRuleExecuted = false;

            validation.AddRule(() => dummy.Foo,
                               () =>
                               {
                                   firstRuleExecuted = true;
                                   return RuleResult.Invalid("Error1");
                               });
            validation.AddRule(() => dummy.Foo,
                               () =>
                               {
                                   secondRuleExecuted = true;
                                   return RuleResult.Invalid("Error2");
                               });

            // ACT

            validation.ValidateAll();

            // VERIFY

            Assert.True(firstRuleExecuted, "First rule must have been executed");
            Assert.False(secondRuleExecuted, "Second rule should not have been executed because first rule failed.");
        }
        public void RemoveRule_ThereAreTwoFailedRules_RemoveOne_ResultChangedShouldBeFiredWithNewResultStillInvalid()
        {
            // ARRANGE
            var dummy = new DummyViewModel();

            var validation = new ValidationHelper();

            validation.AddRule(() => dummy.Foo, () => RuleResult.Invalid("error2"));
            var invalidRule = validation.AddRule(() => dummy.Foo, () => RuleResult.Invalid("error"));

            var validationResult = validation.ValidateAll();

            Assert.False(validationResult.IsValid);

            bool resultChangedEventFired = false;

            validation.ResultChanged += (sender, args) =>
            {
                Assert.Equal(PropertyName.For(() => dummy.Foo), args.Target);
                Assert.False(args.NewResult.IsValid);

                resultChangedEventFired = true;
            };

            // ACT
            validation.RemoveRule(invalidRule);

            // VERIFY
            Assert.True(resultChangedEventFired);
        }
        public void RemoveRule_ThisRuleHadValidationError_ErrorGetsRemovedAlso()
        {
            // ARRANGE
            var validation = new ValidationHelper();

            validation.AddRule(RuleResult.Valid);
            var invalidRule = validation.AddRule(() => RuleResult.Invalid("error"));

            var validationResult = validation.ValidateAll();

            Assert.False(validationResult.IsValid);

            // ACT
            validation.RemoveRule(invalidRule);

            validationResult = validation.GetResult();

            // VERIFY
            Assert.True(validationResult.IsValid);
        }
        private void SetupValidation()
        {
            var validationRules = new ValidationHelper();

            // Simple properties
            validationRules.AddRule(() => StringProperty,
                                    () => { return RuleResult.Assert(!string.IsNullOrEmpty(StringProperty), "StringProperty cannot be null or empty string"); });

            validationRules.AddRule(() => IntProperty,
                                    () => { return RuleResult.Assert(IntProperty > 0, "IntProperty should be greater than zero."); });

            // Dependant properties
            validationRules.AddRule(() => RangeStart,
                                    () => RangeEnd,
                                    () =>
                                    {
                                        return RuleResult.Assert(RangeEnd > RangeStart, "RangeEnd must be grater than RangeStart");
                                    });

            // Long-running validation (simulates call to a web service or something)
            validationRules.AddRule(
                () => StringProperty2,
                () =>
                {
                    if (SyncValidationRuleExecutedAsyncroniouslyDelegate != null)
                    {
                        SyncValidationRuleExecutedAsyncroniouslyDelegate();
                    }

                    return RuleResult.Assert(!string.IsNullOrEmpty(StringProperty2), "StringProperty2 cannot be null or empty string");
                });

            Validation = validationRules;
            DataErrorInfoValidationAdapter = new NotifyDataErrorInfoAdapter(Validation);
        }
		public void SyncValidation_RuleThrowsException_ExceptionIsPropogated()
		{
			// ARRANGE
			var validator = new ValidationHelper();

			validator.AddRule(() =>
			{
				throw new InvalidOperationException("Test");
			});

			// ACT & VERIFY
			Assert.Throws<ValidationException>(validator.ValidateAllAsync());
		}