public void ShouldSupportDelayedViewModelInitialization() { var view = new TestView { NameErrorLabel = string.Empty, NameErrorContainer = { Text = string.Empty } }; 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.Empty(view.NameErrorLabel); Assert.Empty(view.NameErrorContainer.Text); const string errorMessage = "Name shouldn't be empty."; var viewModel = new TestViewModel(); viewModel.ValidationRule(x => x.Name, x => !string.IsNullOrWhiteSpace(x), errorMessage); view.ViewModel = viewModel; Assert.NotEmpty(view.NameErrorLabel); Assert.NotEmpty(view.NameErrorContainer.Text); Assert.Equal(errorMessage, view.NameErrorLabel); Assert.Equal(errorMessage, view.NameErrorContainer.Text); }
public void ShouldDetachAndDisposeTheComponentWhenValidationHelperDisposes() { const string nameErrorMessage = "Name shouldn't be empty."; const string name2ErrorMessage = "Name shouldn't be empty."; var view = new TestView(new TestViewModel { Name = string.Empty }); var nameRule = view.ViewModel.ValidationRule( viewModel => viewModel.Name, name => !string.IsNullOrWhiteSpace(name), nameErrorMessage); var name2Rule = view.ViewModel.ValidationRule( viewModel => viewModel.Name2, name => !string.IsNullOrWhiteSpace(name), name2ErrorMessage); 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.Name2, x => x.Name2ErrorLabel); Assert.Equal(2, view.ViewModel.ValidationContext.Validations.Count); Assert.False(view.ViewModel.ValidationContext.IsValid); Assert.Equal(nameErrorMessage, view.NameErrorLabel); Assert.Equal(name2ErrorMessage, view.Name2ErrorLabel); nameRule.Dispose(); Assert.Equal(1, view.ViewModel.ValidationContext.Validations.Count); Assert.False(view.ViewModel.ValidationContext.IsValid); Assert.Empty(view.NameErrorLabel); Assert.Equal(name2ErrorMessage, view.Name2ErrorLabel); name2Rule.Dispose(); Assert.Equal(0, view.ViewModel.ValidationContext.Validations.Count); Assert.True(view.ViewModel.ValidationContext.IsValid); Assert.Empty(view.NameErrorLabel); Assert.Empty(view.Name2ErrorLabel); view.ViewModel.ValidationRule( viewModel => viewModel.Name, name => !string.IsNullOrWhiteSpace(name), nameErrorMessage); Assert.Equal(1, view.ViewModel.ValidationContext.Validations.Count); Assert.False(view.ViewModel.ValidationContext.IsValid); Assert.Equal(nameErrorMessage, view.NameErrorLabel); Assert.Empty(view.Name2ErrorLabel); }
public void ShouldSupportBindingTwoValidationsForOneProperty() { const int minimumLength = 5; var minimumLengthErrorMessage = $"Minimum length is {minimumLength}"; var view = new TestView(new TestViewModel { Name = "some" }); view.ViewModel.ValidationRule( vm => vm.Name, s => !string.IsNullOrEmpty(s), "Name is required."); view.ViewModel.ValidationRule( vm => vm.Name, s => s.Length > minimumLength, s => minimumLengthErrorMessage); view.Bind(view.ViewModel, vm => vm.Name, v => v.NameLabel); view.BindValidation(view.ViewModel, vm => vm.Name, v => v.NameErrorLabel); view.ViewModel.Name = "som"; Assert.False(view.ViewModel.ValidationContext.IsValid); Assert.Equal(2, view.ViewModel.ValidationContext.Validations.Count); // Checks if second validation error message is shown Assert.Equal(minimumLengthErrorMessage, view.NameErrorLabel); }
public void ShouldSupportBindingModelObservableValidationHelperProperties() { const string namesShouldMatchMessage = "Names should match."; var view = new TestView(new TestViewModel { Name = "Bingo", Name2 = "Bongo" }); view.ViewModel.NameRule = view .ViewModel .ValidationRule( vm => vm.Name2, view.ViewModel.WhenAnyValue(x => x.Name, x => x.Name2, (name, name2) => name == name2), namesShouldMatchMessage); view.Bind(view.ViewModel, vm => vm.Name, v => v.NameLabel); view.Bind(view.ViewModel, vm => vm.Name2, v => v.Name2Label); view.BindValidation(view.ViewModel, vm => vm.NameRule, v => v.NameErrorLabel); Assert.False(view.ViewModel.ValidationContext.IsValid); Assert.Single(view.ViewModel.ValidationContext.Validations); Assert.Equal(namesShouldMatchMessage, view.NameErrorLabel); view.ViewModel.Name = "Bongo"; view.ViewModel.Name2 = "Bongo"; Assert.True(view.ViewModel.ValidationContext.IsValid); Assert.Single(view.ViewModel.ValidationContext.Validations); Assert.Empty(view.NameErrorLabel); }
public void ShouldSupportBindingValidationHelperProperties() { const string nameErrorMessage = "Name should not be empty."; var view = new TestView(new TestViewModel { Name = string.Empty }); view.ViewModel.NameRule = view .ViewModel .ValidationRule( viewModelProperty => viewModelProperty.Name, s => !string.IsNullOrEmpty(s), nameErrorMessage); view.Bind(view.ViewModel, vm => vm.Name, v => v.NameLabel); view.BindValidation(view.ViewModel, vm => vm.NameRule, v => v.NameErrorLabel); Assert.False(view.ViewModel.ValidationContext.IsValid); Assert.Single(view.ViewModel.ValidationContext.Validations); Assert.Equal(nameErrorMessage, view.NameErrorLabel); view.ViewModel.Name = "Jonathan"; Assert.True(view.ViewModel.ValidationContext.IsValid); Assert.Empty(view.NameErrorLabel); view.ViewModel.Name = string.Empty; Assert.False(view.ViewModel.ValidationContext.IsValid); Assert.Equal(nameErrorMessage, view.NameErrorLabel); }
public void ShouldSupportBindingToValidationContextWrappedInValidationHelper() { const string nameValidationError = "Name should not be empty."; var view = new TestView(new TestViewModel { Name = string.Empty }); var outerContext = new ValidationContext(ImmediateScheduler.Instance); var validation = new BasePropertyValidation <TestViewModel, string>( view.ViewModel, vm => vm.Name, name => !string.IsNullOrWhiteSpace(name), nameValidationError); outerContext.Add(validation); view.ViewModel.NameRule = new ValidationHelper(outerContext); view.Bind(view.ViewModel, vm => vm.Name, v => v.NameLabel); view.BindValidation(view.ViewModel, vm => vm.NameRule, v => v.NameErrorLabel); Assert.False(view.ViewModel.NameRule.IsValid); Assert.NotEmpty(view.NameErrorLabel); Assert.Equal(nameValidationError, view.NameErrorLabel); view.ViewModel.Name = "Jotaro"; Assert.True(view.ViewModel.NameRule.IsValid); Assert.Empty(view.NameErrorLabel); }
public void RegisterValidationsWithDifferentLambdaNameWorksTest() { 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, viewModelProperty => viewModelProperty.Name, s => !string.IsNullOrEmpty(s), s => $"Name {s} isn't valid"); // Add validations viewModel.ValidationContext.Add(firstValidation); // View bindings view.Bind(view.ViewModel, vm => vm.Name, v => v.NameLabel); // This was throwing exception due to naming problems with lambdas expressions view.BindValidation( view.ViewModel, vm => vm.Name, v => v.NameErrorLabel); Assert.True(viewModel.ValidationContext.IsValid); Assert.Equal(1, viewModel.ValidationContext.Validations.Count); }
public void ValidationMessagesDefaultConcatenationTest() { var viewModel = new TestViewModel { Name = string.Empty }; var view = new TestView(viewModel); var nameValidation = new BasePropertyValidation <TestViewModel, string>( viewModel, viewModelProperty => viewModelProperty.Name, s => !string.IsNullOrEmpty(s), "Name should not be empty."); var name2Validation = new BasePropertyValidation <TestViewModel, string>( viewModel, viewModelProperty => viewModelProperty.Name2, s => !string.IsNullOrEmpty(s), "Name2 should not be empty."); viewModel.ValidationContext.Add(nameValidation); viewModel.ValidationContext.Add(name2Validation); view.Bind(view.ViewModel, vm => vm.Name, v => v.NameLabel); view.Bind(view.ViewModel, vm => vm.Name2, v => v.Name2Label); view.BindValidation(view.ViewModel, v => v.NameErrorLabel); Assert.False(viewModel.ValidationContext.IsValid); Assert.Equal(2, viewModel.ValidationContext.Validations.Count); Assert.NotEmpty(view.NameErrorLabel); Assert.Equal("Name should not be empty. Name2 should not be empty.", view.NameErrorLabel); }
public void ShouldSupportBindingTwoValidationsForOnePropertyToChainedViewProperties() { const int minimumLength = 5; var minimumLengthErrorMessage = $"Minimum length is {minimumLength}"; var viewModel = new TestViewModel { Name = "some" }; var view = new TestView(viewModel); // Define the validations. viewModel.ValidationRule( vm => vm.Name, s => !string.IsNullOrEmpty(s), "Name is required."); viewModel.ValidationRule( vm => vm.Name, s => s.Length > minimumLength, minimumLengthErrorMessage); // Define view bindings. view.Bind(view.ViewModel, vm => vm.Name, v => v.NameLabel); view.BindValidation(view.ViewModel, vm => vm.Name, v => v.NameErrorContainer.Text); Assert.False(viewModel.ValidationContext.IsValid); Assert.Equal(2, viewModel.ValidationContext.Validations.Count); Assert.Equal(minimumLengthErrorMessage, view.NameErrorContainer.Text); }
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 ShouldSupportObservableValidationRuleOverloads() { var view = new TestView(new TestViewModel { Name = "Foo", Name2 = "Bar" }); var namesAreEqual = view .ViewModel .WhenAnyValue( state => state.Name, state => state.Name2, (name, name2) => new { Name = name, Name2 = name2 }); view.ViewModel.ValidationRule( state => state.Name, namesAreEqual, state => state.Name == state.Name2, state => $"{state.Name} != {state.Name2}."); view.ViewModel.ValidationRule( state => state.Name2, namesAreEqual, state => state.Name == state.Name2, state => $"{state.Name2} != {state.Name}."); view.ViewModel.ValidationRule( namesAreEqual.Select(names => names.Name == names.Name2), "Names should be equal."); view.ViewModel.ValidationRule( namesAreEqual, state => state.Name == state.Name2, state => $"{state.Name} should equal {state.Name2}."); view.Bind(view.ViewModel, x => x.Name, x => x.NameLabel); view.Bind(view.ViewModel, x => x.Name2, x => x.Name2Label); view.BindValidation(view.ViewModel, x => x.NameErrorLabel); Assert.False(view.ViewModel.ValidationContext.IsValid); Assert.Equal(4, view.ViewModel.ValidationContext.Validations.Count); Assert.NotEmpty(view.NameErrorLabel); Assert.Equal("Foo != Bar. Bar != Foo. Names should be equal. Foo should equal Bar.", view.NameErrorLabel); view.ViewModel.Name = "Foo"; view.ViewModel.Name2 = "Foo"; Assert.True(view.ViewModel.ValidationContext.IsValid); Assert.Equal(4, view.ViewModel.ValidationContext.Validations.Count); Assert.Empty(view.NameErrorLabel); }
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 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 ComplexValidationRulesShouldBeBoundToView() { const string errorMessage = "Both inputs should be the same"; var view = new TestView(new TestViewModel { Name = "Josuke Hikashikata", Name2 = "Jotaro Kujo" }); view.ViewModel.ValidationRule( m => m.Name, m => m.WhenAnyValue(x => x.Name, x => x.Name2, (name, name2) => name == name2), (vm, isValid) => isValid ? string.Empty : errorMessage); view.BindValidation(view.ViewModel, x => x.Name, x => x.NameErrorLabel); Assert.NotEmpty(view.NameErrorLabel); Assert.Equal(errorMessage, view.NameErrorLabel); }
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 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); }