public void TwoValidationPropertiesInSamePropertyThrowsExceptionTest() { const string validName = "valid"; const int minimumLength = 5; var viewModel = new TestViewModel { Name = validName }; var view = new TestView(viewModel); var firstValidation = new BasePropertyValidation <TestViewModel, string>( viewModel, vm => vm.Name, s => !string.IsNullOrEmpty(s), s => $"Name {s} isn't valid"); var secondValidation = new BasePropertyValidation <TestViewModel, string>( viewModel, vm => vm.Name, s => s.Length > minimumLength, _ => $"Minimum length is {minimumLength}"); // Add validations viewModel.ValidationContext.Add(firstValidation); viewModel.ValidationContext.Add(secondValidation); // View bindings view.Bind(view.ViewModel, vm => vm.Name, v => v.NameLabel); // View validations bindings var ex = Assert.Throws <MultipleValidationNotSupportedException>(() => { return(view.BindValidation( view.ViewModel, vm => vm.Name, v => v.NameErrorLabel)); }); Assert.False(viewModel.ValidationContext.IsValid); Assert.Equal(2, viewModel.ValidationContext.Validations.Count); // Checks if second validation error message is shown var expectedError = $"Property {nameof(viewModel.Name)} has more than one validation rule associated. Consider using {nameof(ValidationBindingEx)} methods."; Assert.Equal(expectedError, ex.Message); }
public void ShouldBindValidationRuleEmittingValidationStates() { const StringComparison comparison = StringComparison.InvariantCulture; const string viewModelIsBlockedMessage = "View model is blocked."; const string nameErrorMessage = "Name shouldn't be empty."; var view = new TestView(new TestViewModel { Name = string.Empty }); using var isViewModelBlocked = new ReplaySubject <bool>(1); isViewModelBlocked.OnNext(true); // Create IObservable<IValidationState> var nameValidationState = view.ViewModel.WhenAnyValue( vm => vm.Name, name => (IValidationState) new CustomValidationState( !string.IsNullOrWhiteSpace(name), nameErrorMessage)); view.ViewModel.ValidationRule( viewModel => viewModel.Name, nameValidationState); var viewModelBlockedValidationState = isViewModelBlocked.Select(blocked => (IValidationState) new CustomValidationState(!blocked, viewModelIsBlockedMessage)); view.ViewModel.ValidationRule(viewModelBlockedValidationState); view.Bind(view.ViewModel, x => x.Name, x => x.NameLabel); view.BindValidation(view.ViewModel, x => x.Name, x => x.NameErrorLabel); view.BindValidation(view.ViewModel, x => x.NameErrorContainer.Text); Assert.Equal(2, view.ViewModel.ValidationContext.Validations.Count); Assert.False(view.ViewModel.ValidationContext.IsValid); Assert.Contains(nameErrorMessage, view.NameErrorLabel, comparison); Assert.Contains(viewModelIsBlockedMessage, view.NameErrorContainer.Text, comparison); view.ViewModel.Name = "Qwerty"; isViewModelBlocked.OnNext(false); Assert.Equal(2, view.ViewModel.ValidationContext.Validations.Count); Assert.True(view.ViewModel.ValidationContext.IsValid); Assert.DoesNotContain(nameErrorMessage, view.NameErrorLabel, comparison); Assert.DoesNotContain(viewModelIsBlockedMessage, view.NameErrorContainer.Text, comparison); }
public void RegisterValidationsWithDifferentLambdaNameWorksTest() { const string validName = "valid"; var view = new TestView(new TestViewModel { Name = validName }); view.ViewModel.ValidationRule( vm => vm.Name, s => !string.IsNullOrEmpty(s), s => $"Name {s} isn't valid"); view.Bind(view.ViewModel, vm => vm.Name, v => v.NameLabel); view.BindValidation(view.ViewModel, vm => vm.Name, v => v.NameErrorLabel); Assert.True(view.ViewModel.ValidationContext.IsValid); Assert.Single(view.ViewModel.ValidationContext.Validations); }
public void ShouldUpdateViewModelValidityWhenValidationHelpersDetach() { var view = new TestView(new TestViewModel { Name = string.Empty }); var nameRule = view.ViewModel.ValidationRule( viewModel => viewModel.Name, name => !string.IsNullOrWhiteSpace(name), "Name is empty."); var name2Rule = view.ViewModel.ValidationRule( viewModel => viewModel.Name2, name => !string.IsNullOrWhiteSpace(name), "Name2 is empty."); view.Bind(view.ViewModel, x => x.Name, x => x.NameLabel); view.BindValidation(view.ViewModel, x => x.NameErrorContainer.Text); Assert.Equal(2, view.ViewModel.ValidationContext.Validations.Count); Assert.False(view.ViewModel.ValidationContext.IsValid); Assert.Equal("Name is empty. Name2 is empty.", view.NameErrorContainer.Text); nameRule.Dispose(); Assert.Equal(1, view.ViewModel.ValidationContext.Validations.Count); Assert.False(view.ViewModel.ValidationContext.IsValid); Assert.Equal("Name2 is empty.", view.NameErrorContainer.Text); name2Rule.Dispose(); Assert.Equal(0, view.ViewModel.ValidationContext.Validations.Count); Assert.True(view.ViewModel.ValidationContext.IsValid); Assert.Empty(view.NameErrorContainer.Text); view.ViewModel.ValidationRule( viewModel => viewModel.Name, name => !string.IsNullOrWhiteSpace(name), "Name is empty."); Assert.Equal(1, view.ViewModel.ValidationContext.Validations.Count); Assert.False(view.ViewModel.ValidationContext.IsValid); Assert.Equal("Name is empty.", view.NameErrorContainer.Text); }
public void ShouldAllowUsingCustomFormatters() { const string validationConstant = "View model is invalid."; var view = new TestView(new TestViewModel { Name = string.Empty }); view.ViewModel.ValidationRule( vm => vm.Name, s => !string.IsNullOrEmpty(s), "Name should not be empty."); view.Bind(view.ViewModel, vm => vm.Name, v => v.NameLabel); view.BindValidation(view.ViewModel, v => v.NameErrorLabel, new ConstFormatter(validationConstant)); Assert.False(view.ViewModel.ValidationContext.IsValid); Assert.Equal(1, view.ViewModel.ValidationContext.Validations.Count); Assert.NotEmpty(view.NameErrorLabel); Assert.Equal(validationConstant, view.NameErrorLabel); }
public void ShouldSupportBindingTwoValidationsForOneProperty() { const int minimumLength = 5; var viewModel = new TestViewModel { Name = "some" }; var view = new TestView(viewModel); var firstValidation = new BasePropertyValidation <TestViewModel, string>( viewModel, vm => vm.Name, s => !string.IsNullOrEmpty(s), "Name is required."); var minimumLengthErrorMessage = $"Minimum length is {minimumLength}"; var secondValidation = new BasePropertyValidation <TestViewModel, string>( viewModel, vm => vm.Name, s => s.Length > minimumLength, s => minimumLengthErrorMessage); // Add validations viewModel.ValidationContext.Add(firstValidation); viewModel.ValidationContext.Add(secondValidation); // View bindings view.Bind(view.ViewModel, vm => vm.Name, v => v.NameLabel); // View validations bindings view.BindValidation(view.ViewModel, vm => vm.Name, v => v.NameErrorLabel); viewModel.Name = "som"; Assert.False(viewModel.ValidationContext.IsValid); Assert.Equal(2, viewModel.ValidationContext.Validations.Count); // Checks if second validation error message is shown Assert.Equal(minimumLengthErrorMessage, view.NameErrorLabel); }
public void ShouldUpdateValidationHelperBindingOnPropertyChange() { var view = new TestView(new TestViewModel { Name = string.Empty }); const string nameErrorMessage = "Name shouldn't be empty."; view.ViewModel.NameRule = view.ViewModel .ValidationRule( viewModel => viewModel.Name, name => !string.IsNullOrWhiteSpace(name), nameErrorMessage); view.Bind(view.ViewModel, x => x.Name, x => x.NameLabel); view.BindValidation(view.ViewModel, x => x.NameRule, x => x.NameErrorLabel); Assert.Equal(1, view.ViewModel.ValidationContext.Validations.Count); Assert.False(view.ViewModel.ValidationContext.IsValid); Assert.Equal(nameErrorMessage, view.NameErrorLabel); view.ViewModel.NameRule.Dispose(); view.ViewModel.NameRule = null; Assert.Equal(0, view.ViewModel.ValidationContext.Validations.Count); Assert.True(view.ViewModel.ValidationContext.IsValid); Assert.Empty(view.NameErrorLabel); const string secretMessage = "This is the secret message."; view.ViewModel.NameRule = view.ViewModel .ValidationRule( viewModel => viewModel.Name, name => !string.IsNullOrWhiteSpace(name), secretMessage); Assert.Equal(1, view.ViewModel.ValidationContext.Validations.Count); Assert.False(view.ViewModel.ValidationContext.IsValid); Assert.Equal(secretMessage, view.NameErrorLabel); }