diff options
Diffstat (limited to 'server/src/test')
3 files changed, 327 insertions, 180 deletions
diff --git a/server/src/test/java/com/vaadin/data/BeanBinderTest.java b/server/src/test/java/com/vaadin/data/BeanBinderTest.java index 1788c3a9e8..84a414edf1 100644 --- a/server/src/test/java/com/vaadin/data/BeanBinderTest.java +++ b/server/src/test/java/com/vaadin/data/BeanBinderTest.java @@ -163,9 +163,10 @@ public class BeanBinderTest { } private void assertInvalid(HasValue<?> field, String message) { - List<ValidationError<?>> errors = binder.validate(); + BinderValidationStatus<?> status = binder.validate(); + List<ValidationStatus<?>> errors = status.getFieldValidationErrors(); assertEquals(1, errors.size()); - assertSame(field, errors.get(0).getField().get()); - assertEquals(message, errors.get(0).getMessage()); + assertSame(field, errors.get(0).getField()); + assertEquals(message, errors.get(0).getMessage().get()); } } diff --git a/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java b/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java index 6861903132..d11a0ed6da 100644 --- a/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java +++ b/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java @@ -27,12 +27,14 @@ import org.junit.Before; import org.junit.Test; import com.vaadin.data.Binder.Binding; +import com.vaadin.data.ValidationStatus.Status; import com.vaadin.data.util.converter.Converter; import com.vaadin.data.util.converter.StringToIntegerConverter; import com.vaadin.data.validator.EmailValidator; import com.vaadin.server.AbstractErrorMessage; import com.vaadin.ui.Button; import com.vaadin.ui.Label; +import com.vaadin.ui.Notification; import com.vaadin.ui.PopupDateField; import com.vaadin.ui.Slider; import com.vaadin.ui.TextField; @@ -140,6 +142,30 @@ public class BinderBookOfVaadinTest { } @Test + public void loadingFromBusinessObjects() { + // this test is just to make sure the code snippet in the book compiles + binder.load(new BookPerson(1969, 50000)); + + BinderValidationStatus<BookPerson> status = binder.validate(); + + if (status.hasErrors()) { + Notification.show("Validation error count: " + + status.getValidationErrors().size()); + } + } + + @Test + public void handlingCheckedException() { + // another test just to verify that book examples actually compile + try { + binder.save(new BookPerson(2000, 50000)); + } catch (ValidationException e) { + Notification.show("Validation error count: " + + e.getValidationErrors().size()); + } + } + + @Test public void simpleEmailValidator() { binder.forField(field) // Explicit validator instance @@ -148,16 +174,16 @@ public class BinderBookOfVaadinTest { .bind(BookPerson::getEmail, BookPerson::setEmail); field.setValue("not-email"); - List<ValidationError<?>> errors = binder.validate(); - Assert.assertEquals(1, errors.size()); + BinderValidationStatus<?> status = binder.validate(); + Assert.assertEquals(1, status.getFieldValidationErrors().size()); Assert.assertEquals("This doesn't look like a valid email address", - errors.get(0).getMessage()); + status.getFieldValidationErrors().get(0).getMessage().get()); Assert.assertEquals("This doesn't look like a valid email address", ((AbstractErrorMessage) field.getErrorMessage()).getMessage()); field.setValue("abc@vaadin.com"); - errors = binder.validate(); - Assert.assertEquals(0, errors.size()); + status = binder.validate(); + Assert.assertEquals(0, status.getBeanValidationErrors().size()); Assert.assertNull(field.getErrorMessage()); } @@ -170,16 +196,16 @@ public class BinderBookOfVaadinTest { .bind(BookPerson::getLastName, BookPerson::setLastName); field.setValue("a"); - List<ValidationError<?>> errors = binder.validate(); - Assert.assertEquals(1, errors.size()); + BinderValidationStatus<?> status = binder.validate(); + Assert.assertEquals(1, status.getFieldValidationErrors().size()); Assert.assertEquals("Last name must contain at least three characters", - errors.get(0).getMessage()); + status.getFieldValidationErrors().get(0).getMessage().get()); Assert.assertEquals("Last name must contain at least three characters", ((AbstractErrorMessage) field.getErrorMessage()).getMessage()); field.setValue("long last name"); - errors = binder.validate(); - Assert.assertEquals(0, errors.size()); + status = binder.validate(); + Assert.assertEquals(0, status.getFieldValidationErrors().size()); Assert.assertNull(field.getErrorMessage()); } @@ -194,25 +220,25 @@ public class BinderBookOfVaadinTest { .bind(BookPerson::getEmail, BookPerson::setEmail); field.setValue("not-email"); - List<ValidationError<?>> errors = binder.validate(); + BinderValidationStatus<?> status = binder.validate(); // Only one error per field should be reported - Assert.assertEquals(1, errors.size()); + Assert.assertEquals(1, status.getFieldValidationErrors().size()); Assert.assertEquals("This doesn't look like a valid email address", - errors.get(0).getMessage()); + status.getFieldValidationErrors().get(0).getMessage().get()); Assert.assertEquals("This doesn't look like a valid email address", ((AbstractErrorMessage) field.getErrorMessage()).getMessage()); field.setValue("abc@vaadin.com"); - errors = binder.validate(); - Assert.assertEquals(1, errors.size()); + status = binder.validate(); + Assert.assertEquals(1, status.getFieldValidationErrors().size()); Assert.assertEquals("Only acme.com email addresses are allowed", - errors.get(0).getMessage()); + status.getFieldValidationErrors().get(0).getMessage().get()); Assert.assertEquals("Only acme.com email addresses are allowed", ((AbstractErrorMessage) field.getErrorMessage()).getMessage()); field.setValue("abc@acme.com"); - errors = binder.validate(); - Assert.assertEquals(0, errors.size()); + status = binder.validate(); + Assert.assertEquals(0, status.getFieldValidationErrors().size()); Assert.assertNull(field.getErrorMessage()); } @@ -296,32 +322,32 @@ public class BinderBookOfVaadinTest { departing.setValue(before); returning.setValue(after); - List<ValidationError<?>> errors = binder.validate(); - Assert.assertTrue(errors.isEmpty()); + BinderValidationStatus<Trip> status = binder.validate(); + Assert.assertTrue(status.getBeanValidationErrors().isEmpty()); Assert.assertNull(departing.getComponentError()); Assert.assertNull(returning.getComponentError()); // update returning => validation is done against this field returning.setValue(past); - errors = binder.validate(); + status = binder.validate(); - Assert.assertFalse(errors.isEmpty()); + Assert.assertFalse(status.getFieldValidationErrors().isEmpty()); Assert.assertNotNull(returning.getComponentError()); Assert.assertNull(departing.getComponentError()); // set correct value back returning.setValue(before); - errors = binder.validate(); + status = binder.validate(); - Assert.assertTrue(errors.isEmpty()); + Assert.assertTrue(status.getFieldValidationErrors().isEmpty()); Assert.assertNull(departing.getComponentError()); Assert.assertNull(returning.getComponentError()); // update departing => validation is done because of listener added departing.setValue(after); - errors = binder.validate(); + status = binder.validate(); - Assert.assertFalse(errors.isEmpty()); + Assert.assertFalse(status.getFieldValidationErrors().isEmpty()); Assert.assertNotNull(returning.getComponentError()); Assert.assertNull(departing.getComponentError()); @@ -351,7 +377,7 @@ public class BinderBookOfVaadinTest { departing.setValue(before); returning.setValue(after); - Result<Date> result = returnBinding.validate(); + ValidationStatus<Date> result = returnBinding.validate(); Assert.assertFalse(result.isError()); Assert.assertNull(departing.getComponentError()); @@ -402,17 +428,16 @@ public class BinderBookOfVaadinTest { @Test public void withBindingStatusChangeHandlerExample() { Label nameStatus = new Label(); - AtomicReference<ValidationStatusChangeEvent> event = new AtomicReference<>(); + AtomicReference<ValidationStatus<?>> statusCapture = new AtomicReference<>(); String msg = "Full name must contain at least three characters"; binder.forField(field).withValidator(name -> name.length() >= 3, msg) - .withStatusChangeHandler(statusChange -> { + .withStatusHandler(statusChange -> { nameStatus.setValue(statusChange.getMessage().orElse("")); // Only show the label when validation has failed - boolean error = statusChange - .getStatus() == ValidationStatus.ERROR; + boolean error = statusChange.getStatus() == Status.ERROR; nameStatus.setVisible(error); - event.set(statusChange); + statusCapture.set(statusChange); }).bind(BookPerson::getLastName, BookPerson::setLastName); field.setValue("aa"); @@ -420,22 +445,22 @@ public class BinderBookOfVaadinTest { Assert.assertTrue(nameStatus.isVisible()); Assert.assertEquals(msg, nameStatus.getValue()); - Assert.assertNotNull(event.get()); - ValidationStatusChangeEvent evt = event.get(); - Assert.assertEquals(ValidationStatus.ERROR, evt.getStatus()); - Assert.assertEquals(msg, evt.getMessage().get()); - Assert.assertEquals(field, evt.getSource()); + Assert.assertNotNull(statusCapture.get()); + ValidationStatus<?> status = statusCapture.get(); + Assert.assertEquals(Status.ERROR, status.getStatus()); + Assert.assertEquals(msg, status.getMessage().get()); + Assert.assertEquals(field, status.getField()); field.setValue("foo"); binder.validate(); Assert.assertFalse(nameStatus.isVisible()); Assert.assertEquals("", nameStatus.getValue()); - Assert.assertNotNull(event.get()); - evt = event.get(); - Assert.assertEquals(ValidationStatus.OK, evt.getStatus()); - Assert.assertFalse(evt.getMessage().isPresent()); - Assert.assertEquals(field, evt.getSource()); + Assert.assertNotNull(statusCapture.get()); + status = statusCapture.get(); + Assert.assertEquals(Status.OK, status.getStatus()); + Assert.assertFalse(status.getMessage().isPresent()); + Assert.assertEquals(field, status.getField()); } @Test @@ -495,17 +520,18 @@ public class BinderBookOfVaadinTest { .bind(BookPerson::getYearOfBirth, BookPerson::setYearOfBirth); yearOfBirthField.setValue("abc"); - Assert.assertEquals("Doesn't look like a year", - binder.validate().get(0).getMessage()); + Assert.assertEquals("Doesn't look like a year", binder.validate() + .getFieldValidationErrors().get(0).getMessage().get()); yearOfBirthField.setValue("abcd"); - Assert.assertEquals("Must enter a number", - binder.validate().get(0).getMessage()); + Assert.assertEquals("Must enter a number", binder.validate() + .getFieldValidationErrors().get(0).getMessage().get()); yearOfBirthField.setValue("1200"); Assert.assertEquals("Person must be born in the 20th century", - binder.validate().get(0).getMessage()); + binder.validate().getFieldValidationErrors().get(0).getMessage() + .get()); yearOfBirthField.setValue("1950"); - Assert.assertTrue(binder.validate().isEmpty()); + Assert.assertFalse(binder.validate().hasErrors()); BookPerson person = new BookPerson(1500, 12); binder.save(person); Assert.assertEquals(1950, person.getYearOfBirth()); @@ -546,15 +572,17 @@ public class BinderBookOfVaadinTest { binder.bind(p); yearOfBirthField.setValue("abc"); - Assert.assertEquals("Please enter a number", - binder.validate().get(0).getMessage()); + Assert.assertTrue(binder.validate().hasErrors()); + Assert.assertEquals("Please enter a number", binder.validate() + .getFieldValidationErrors().get(0).getMessage().get()); yearOfBirthField.setValue("123"); - Assert.assertTrue(binder.validate().isEmpty()); + Assert.assertTrue(binder.validate().isOk()); p.setYearOfBirth(12500); binder.load(p); Assert.assertEquals("12500", yearOfBirthField.getValue()); + Assert.assertTrue(binder.validate().isOk()); } @Test @@ -582,25 +610,30 @@ public class BinderBookOfVaadinTest { // first bean validator fails and passes error message to status label yearOfBirth.setValue("2001"); - List<ValidationError<?>> errors = binder.validate(); - Assert.assertEquals(1, errors.size()); - Assert.assertEquals(errors.get(0).getMessage(), message); + BinderValidationStatus<?> status = binder.validate(); + Assert.assertEquals(0, status.getFieldValidationErrors().size()); + Assert.assertEquals(1, status.getBeanValidationErrors().size()); + Assert.assertEquals( + status.getBeanValidationErrors().get(0).getMessage().get(), + message); Assert.assertEquals(message, formStatusLabel.getValue()); // value is correct, status label is cleared yearOfBirth.setValue("1999"); - errors = binder.validate(); - Assert.assertEquals(0, errors.size()); + status = binder.validate(); + Assert.assertFalse(status.hasErrors()); Assert.assertEquals("", formStatusLabel.getValue()); // both bean validators fail, should be two error messages chained yearOfBirth.setValue("2000"); - errors = binder.validate(); - Assert.assertEquals(2, errors.size()); + status = binder.validate(); + Assert.assertEquals(2, status.getBeanValidationResults().size()); + Assert.assertEquals(0, status.getFieldValidationErrors().size()); + Assert.assertEquals(2, status.getBeanValidationErrors().size()); // only first error is shown Assert.assertEquals(message, formStatusLabel.getValue()); @@ -612,21 +645,17 @@ public class BinderBookOfVaadinTest { BinderStatusHandler defaultHandler = binder.getStatusHandler(); - binder.setStatusHandler(results -> { - String errorMessage = results.stream() - // Ignore confirmation messages - .filter(BinderResult::isError) - // Ignore messages that belong to a specific field - .filter(error -> !error.getField().isPresent()) - // Create a string out of the remaining messages - .map(Result::getMessage).map(o -> o.get()) - .collect(Collectors.joining("\n")); - + binder.setStatusHandler(status -> { + // create an error message on failed bean level validations + List<Result<?>> errors = status.getBeanValidationErrors(); + String errorMessage = errors.stream().map(Result::getMessage) + .map(o -> o.get()).collect(Collectors.joining("\n")); + // show error in a label formStatusLabel.setValue(errorMessage); formStatusLabel.setVisible(!errorMessage.isEmpty()); // Let the default handler show messages for each field - defaultHandler.accept(results); + defaultHandler.accept(status); }); final String bindingMessage = "uneven"; @@ -648,34 +677,41 @@ public class BinderBookOfVaadinTest { // first binding validation fails, no bean level validation is done yearOfBirth.setValue("2001"); - List<ValidationError<?>> errors = binder.validate(); - Assert.assertEquals(1, errors.size()); - Assert.assertEquals(errors.get(0).getMessage(), bindingMessage); + BinderValidationStatus<?> status = binder.validate(); + Assert.assertEquals(1, status.getFieldValidationErrors().size()); + Assert.assertEquals(bindingMessage, + status.getFieldValidationErrors().get(0).getMessage().get()); Assert.assertEquals("", formStatusLabel.getValue()); // first bean validator fails and passes error message to status label yearOfBirth.setValue("2002"); - errors = binder.validate(); - Assert.assertEquals(1, errors.size()); - Assert.assertEquals(errors.get(0).getMessage(), message); + status = binder.validate(); + Assert.assertEquals(0, status.getFieldValidationErrors().size()); + Assert.assertEquals(1, status.getBeanValidationErrors().size()); + Assert.assertEquals(message, + status.getBeanValidationErrors().get(0).getMessage().get()); Assert.assertEquals(message, formStatusLabel.getValue()); // value is correct, status label is cleared yearOfBirth.setValue("1998"); - errors = binder.validate(); - Assert.assertEquals(0, errors.size()); + status = binder.validate(); + Assert.assertTrue(status.isOk()); + Assert.assertFalse(status.hasErrors()); + Assert.assertEquals(0, status.getFieldValidationErrors().size()); + Assert.assertEquals(0, status.getBeanValidationErrors().size()); Assert.assertEquals("", formStatusLabel.getValue()); // both bean validators fail, should be two error messages chained yearOfBirth.setValue("2000"); - errors = binder.validate(); - Assert.assertEquals(2, errors.size()); + status = binder.validate(); + Assert.assertEquals(0, status.getFieldValidationErrors().size()); + Assert.assertEquals(2, status.getBeanValidationErrors().size()); Assert.assertEquals(message + "\n" + message2, formStatusLabel.getValue()); diff --git a/server/src/test/java/com/vaadin/data/BinderTest.java b/server/src/test/java/com/vaadin/data/BinderTest.java index 4b69fdf50e..0a82b527bb 100644 --- a/server/src/test/java/com/vaadin/data/BinderTest.java +++ b/server/src/test/java/com/vaadin/data/BinderTest.java @@ -5,17 +5,15 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; import java.util.List; -import java.util.Optional; -import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Collectors; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import com.vaadin.data.Binder.Binding; +import com.vaadin.data.ValidationStatus.Status; import com.vaadin.data.util.converter.Converter; import com.vaadin.data.validator.NotEmptyValidator; import com.vaadin.server.AbstractErrorMessage; @@ -27,6 +25,8 @@ import com.vaadin.ui.TextField; public class BinderTest { + private static final String EMPTY_ERROR_MESSAGE = "Value cannot be empty"; + private static class StatusBean { private String status; @@ -48,7 +48,7 @@ public class BinderTest { Person p = new Person(); Validator<String> notEmpty = Validator.from(val -> !val.isEmpty(), - "Value cannot be empty"); + EMPTY_ERROR_MESSAGE); Converter<String, Integer> stringToInteger = Converter.from( Integer::valueOf, String::valueOf, e -> "Value must be a number"); Validator<Integer> notNegative = Validator.from(x -> x >= 0, @@ -327,18 +327,17 @@ public class BinderTest { binder.save(person); Assert.fail(); } catch (ValidationException exception) { - List<ValidationError<?>> validationErrors = exception - .getValidationError(); + List<ValidationStatus<?>> validationErrors = exception + .getFieldValidationErrors(); Assert.assertEquals(2, validationErrors.size()); - ValidationError<?> error = validationErrors.get(0); - Assert.assertEquals(nameField, error.getField().get()); - Assert.assertEquals(msg, error.getMessage()); - Assert.assertEquals("", error.getValue()); + ValidationStatus<?> error = validationErrors.get(0); + Assert.assertEquals(nameField, error.getField()); + Assert.assertEquals(msg, error.getMessage().get()); error = validationErrors.get(1); - Assert.assertEquals(ageField, error.getField().get()); - Assert.assertEquals("Value must be positive", error.getMessage()); - Assert.assertEquals(ageField.getValue(), error.getValue()); + Assert.assertEquals(ageField, error.getField()); + Assert.assertEquals("Value must be positive", + error.getMessage().get()); } } @@ -375,9 +374,9 @@ public class BinderTest { public void validate_notBound_noErrors() { Binder<Person> binder = new Binder<>(); - List<ValidationError<?>> errors = binder.validate(); + BinderValidationStatus<Person> status = binder.validate(); - Assert.assertTrue(errors.isEmpty()); + Assert.assertTrue(status.isOk()); } @Test @@ -388,9 +387,9 @@ public class BinderTest { Person::setFirstName); nameField.setComponentError(new UserError("")); - List<ValidationError<?>> errors = binder.validate(); + BinderValidationStatus<Person> status = binder.validate(); - Assert.assertTrue(errors.isEmpty()); + Assert.assertTrue(status.isOk()); Assert.assertNull(nameField.getComponentError()); } @@ -411,19 +410,19 @@ public class BinderTest { binding.withValidator(value -> false, msg2); binding.bind(Person::getFirstName, Person::setFirstName); - List<ValidationError<?>> errors = binder.validate(); + BinderValidationStatus<Person> status = binder.validate(); + List<ValidationStatus<?>> errors = status.getFieldValidationErrors(); Assert.assertEquals(1, errors.size()); - Set<String> errorMessages = errors.stream() - .map(ValidationError::getMessage).collect(Collectors.toSet()); - Assert.assertTrue(errorMessages.contains(msg1)); + ValidationStatus<?> validationStatus = errors.stream().findFirst() + .get(); + String msg = validationStatus.getMessage().get(); + Assert.assertEquals(msg1, msg); + + HasValue<?> field = validationStatus.getField(); - Set<?> fields = errors.stream().map(ValidationError::getField) - .filter(Optional::isPresent).map(Optional::get) - .collect(Collectors.toSet()); - Assert.assertEquals(1, fields.size()); - Assert.assertTrue(fields.contains(nameField)); + Assert.assertEquals(nameField, field); ErrorMessage componentError = nameField.getComponentError(); Assert.assertNotNull(componentError); @@ -490,19 +489,25 @@ public class BinderTest { ageField.setValue(""); assertEquals(32, p.getAge()); - assertValidationErrors(binder.validate(), "Value cannot be empty"); + assertValidationErrors(binder.validate(), EMPTY_ERROR_MESSAGE); } private void assertValidationErrors( - List<ValidationError<?>> validationErrors, + List<ValidationStatus<?>> validationErrors, String... errorMessages) { Assert.assertEquals(errorMessages.length, validationErrors.size()); for (int i = 0; i < errorMessages.length; i++) { Assert.assertEquals(errorMessages[i], - validationErrors.get(i).getMessage()); + validationErrors.get(i).getMessage().get()); } } + private void assertValidationErrors(BinderValidationStatus<Person> status, + String... errorMessages) { + assertValidationErrors(status.getFieldValidationErrors(), + errorMessages); + } + @Test public void convertToModelConversionFails() { bindAgeWithValidatorConverterValidator(); @@ -571,11 +576,11 @@ public class BinderTest { @Test public void bindingWithStatusChangeHandler_handlerGetsEvents() { - AtomicReference<ValidationStatusChangeEvent> event = new AtomicReference<>(); + AtomicReference<ValidationStatus<?>> statusCapture = new AtomicReference<>(); Binding<Person, String, String> binding = binder.forField(nameField) - .withValidator(notEmpty).withStatusChangeHandler(evt -> { - Assert.assertNull(event.get()); - event.set(evt); + .withValidator(notEmpty).withStatusHandler(evt -> { + Assert.assertNull(statusCapture.get()); + statusCapture.set(evt); }); binding.bind(Person::getFirstName, Person::setFirstName); @@ -585,30 +590,30 @@ public class BinderTest { // message binder.validate(); - Assert.assertNotNull(event.get()); - ValidationStatusChangeEvent evt = event.get(); - Assert.assertEquals(ValidationStatus.ERROR, evt.getStatus()); - Assert.assertEquals("Value cannot be empty", evt.getMessage().get()); - Assert.assertEquals(nameField, evt.getSource()); + Assert.assertNotNull(statusCapture.get()); + ValidationStatus<?> evt = statusCapture.get(); + Assert.assertEquals(Status.ERROR, evt.getStatus()); + Assert.assertEquals(EMPTY_ERROR_MESSAGE, evt.getMessage().get()); + Assert.assertEquals(nameField, evt.getField()); nameField.setValue("foo"); - event.set(null); + statusCapture.set(null); // Second validation succeeds => should be event with OK status and // no message binder.validate(); - evt = event.get(); + evt = statusCapture.get(); Assert.assertNotNull(evt); - Assert.assertEquals(ValidationStatus.OK, evt.getStatus()); + Assert.assertEquals(Status.OK, evt.getStatus()); Assert.assertFalse(evt.getMessage().isPresent()); - Assert.assertEquals(nameField, evt.getSource()); + Assert.assertEquals(nameField, evt.getField()); } @Test public void bindingWithStatusChangeHandler_defaultStatusChangeHandlerIsReplaced() { Binding<Person, String, String> binding = binder.forField(nameField) - .withValidator(notEmpty).withStatusChangeHandler(evt -> { + .withValidator(notEmpty).withStatusHandler(evt -> { }); binding.bind(Person::getFirstName, Person::setFirstName); @@ -639,7 +644,7 @@ public class BinderTest { binding.validate(); Assert.assertTrue(label.isVisible()); - Assert.assertEquals("Value cannot be empty", label.getValue()); + Assert.assertEquals(EMPTY_ERROR_MESSAGE, label.getValue()); nameField.setValue("foo"); @@ -677,7 +682,7 @@ public class BinderTest { .withValidator(notEmpty); binding.bind(Person::getFirstName, Person::setFirstName); - binding.withStatusChangeHandler(evt -> Assert.fail()); + binding.withStatusHandler(evt -> Assert.fail()); } @Test(expected = IllegalStateException.class) @@ -697,7 +702,7 @@ public class BinderTest { Binding<Person, String, String> binding = binder.forField(nameField); - binding.withStatusChangeHandler(event -> { + binding.withStatusHandler(event -> { }); binding.withStatusLabel(label); @@ -711,7 +716,7 @@ public class BinderTest { binding.withStatusLabel(label); - binding.withStatusChangeHandler(event -> { + binding.withStatusHandler(event -> { }); } @@ -720,10 +725,10 @@ public class BinderTest { Binding<Person, String, String> binding = binder.forField(nameField); - binding.withStatusChangeHandler(event -> { + binding.withStatusHandler(event -> { }); - binding.withStatusChangeHandler(event -> { + binding.withStatusHandler(event -> { }); } @@ -738,9 +743,9 @@ public class BinderTest { Person person = new Person(); binder.bind(person); - List<ValidationError<?>> errors = binder.validate(); - Assert.assertEquals(1, errors.size()); - Assert.assertFalse(errors.get(0).getField().isPresent()); + List<ValidationStatus<?>> errors = binder.validate() + .getFieldValidationErrors(); + Assert.assertEquals(0, errors.size()); } @Test @@ -756,12 +761,12 @@ public class BinderTest { Person person = new Person(); binder.bind(person); - List<ValidationError<?>> errors = binder.validate(); + List<ValidationStatus<?>> errors = binder.validate() + .getFieldValidationErrors(); Assert.assertEquals(1, errors.size()); - ValidationError<?> error = errors.get(0); - Assert.assertEquals(msg, error.getMessage()); - Assert.assertTrue(error.getField().isPresent()); - Assert.assertEquals(nameField.getValue(), error.getValue()); + ValidationStatus<?> error = errors.get(0); + Assert.assertEquals(msg, error.getMessage().get()); + Assert.assertEquals(nameField, error.getField()); } @Test @@ -778,14 +783,14 @@ public class BinderTest { Person person = new Person(); binder.bind(person); - List<ValidationError<?>> errors = binder.validate(); + List<ValidationStatus<?>> errors = binder.validate() + .getFieldValidationErrors(); Assert.assertEquals(1, errors.size()); - ValidationError<?> error = errors.get(0); + ValidationStatus<?> error = errors.get(0); - Assert.assertEquals(msg1, error.getMessage()); - Assert.assertEquals(nameField, error.getField().get()); - Assert.assertEquals(nameField.getValue(), error.getValue()); + Assert.assertEquals(msg1, error.getMessage().get()); + Assert.assertEquals(nameField, error.getField()); } @Test @@ -799,8 +804,8 @@ public class BinderTest { Person person = new Person(); binder.bind(person); - List<ValidationError<?>> errors = binder.validate(); - Assert.assertEquals(0, errors.size()); + Assert.assertFalse(binder.validate().hasErrors()); + Assert.assertTrue(binder.validate().isOk()); } @Test @@ -863,15 +868,105 @@ public class BinderTest { } @Test - public void binderWithStatusChangeHandler_handlerGetsEvents() { - AtomicReference<List<BinderResult<?, ?>>> resultsCapture = new AtomicReference<>(); + public void binderWithStatusHandler_fieldValidationNoBeanValidation_handlerGetsStatusUpdates() { + AtomicReference<BinderValidationStatus<?>> statusCapture = new AtomicReference<>(); binder.forField(nameField).withValidator(notEmpty) - .withStatusChangeHandler(evt -> { + .withStatusHandler(evt -> { Assert.fail( "Using a custom status change handler so no change should end up here"); }).bind(Person::getFirstName, Person::setFirstName); binder.forField(ageField).withConverter(stringToInteger) - .withValidator(notNegative).withStatusChangeHandler(evt -> { + .withValidator(notNegative).withStatusHandler(evt -> { + Assert.fail( + "Using a custom status change handler so no change should end up here"); + }).bind(Person::getAge, Person::setAge); + + binder.setStatusHandler(r -> { + statusCapture.set(r); + }); + binder.bind(p); + Assert.assertNull(nameField.getComponentError()); + + nameField.setValue(""); + ageField.setValue("5"); + + // First binding validation fails => should be result with ERROR status + // and message + BinderValidationStatus<Person> status2 = binder.validate(); + BinderValidationStatus<?> status = statusCapture.get(); + Assert.assertSame(status2, status); + + Assert.assertNull(nameField.getComponentError()); + + List<ValidationStatus<?>> bindingStatuses = status + .getFieldValidationStatuses(); + Assert.assertNotNull(bindingStatuses); + Assert.assertEquals(1, status.getFieldValidationErrors().size()); + Assert.assertEquals(2, bindingStatuses.size()); + + ValidationStatus<?> r = bindingStatuses.get(0); + Assert.assertTrue(r.isError()); + Assert.assertEquals(EMPTY_ERROR_MESSAGE, r.getMessage().get()); + Assert.assertEquals(nameField, r.getField()); + + r = bindingStatuses.get(1); + Assert.assertFalse(r.isError()); + Assert.assertFalse(r.getMessage().isPresent()); + Assert.assertEquals(ageField, r.getField()); + + Assert.assertEquals(0, status.getBeanValidationResults().size()); + Assert.assertEquals(0, status.getBeanValidationErrors().size()); + + nameField.setValue("foo"); + ageField.setValue(""); + + statusCapture.set(null); + // Second validation succeeds => should be result with OK status and + // no message, and error result for age + binder.validate(); + + status = statusCapture.get(); + bindingStatuses = status.getFieldValidationStatuses(); + Assert.assertEquals(1, status.getFieldValidationErrors().size()); + Assert.assertEquals(2, bindingStatuses.size()); + + r = bindingStatuses.get(0); + Assert.assertFalse(r.isError()); + Assert.assertFalse(r.getMessage().isPresent()); + Assert.assertEquals(nameField, r.getField()); + + r = bindingStatuses.get(1); + Assert.assertTrue(r.isError()); + Assert.assertEquals("Value must be a number", r.getMessage().get()); + Assert.assertEquals(ageField, r.getField()); + + Assert.assertEquals(0, status.getBeanValidationResults().size()); + Assert.assertEquals(0, status.getBeanValidationErrors().size()); + + statusCapture.set(null); + // binding validations pass, binder validation fails + ageField.setValue("0"); + binder.validate(); + + status = statusCapture.get(); + bindingStatuses = status.getFieldValidationStatuses(); + Assert.assertEquals(0, status.getFieldValidationErrors().size()); + Assert.assertEquals(2, bindingStatuses.size()); + + Assert.assertEquals(0, status.getBeanValidationResults().size()); + Assert.assertEquals(0, status.getBeanValidationErrors().size()); + } + + @Test + public void binderWithStatusHandler_fieldAndBeanLevelValidation_handlerGetsStatusUpdates() { + AtomicReference<BinderValidationStatus<?>> statusCapture = new AtomicReference<>(); + binder.forField(nameField).withValidator(notEmpty) + .withStatusHandler(evt -> { + Assert.fail( + "Using a custom status change handler so no change should end up here"); + }).bind(Person::getFirstName, Person::setFirstName); + binder.forField(ageField).withConverter(stringToInteger) + .withValidator(notNegative).withStatusHandler(evt -> { Assert.fail( "Using a custom status change handler so no change should end up here"); }).bind(Person::getAge, Person::setAge); @@ -881,7 +976,7 @@ public class BinderTest { : Result.error("Need first name and age")); binder.setStatusHandler(r -> { - resultsCapture.set(r); + statusCapture.set(r); }); binder.bind(p); Assert.assertNull(nameField.getComponentError()); @@ -891,65 +986,78 @@ public class BinderTest { // First binding validation fails => should be result with ERROR status // and message - binder.validate(); + BinderValidationStatus<Person> status2 = binder.validate(); + BinderValidationStatus<?> status = statusCapture.get(); + Assert.assertSame(status2, status); Assert.assertNull(nameField.getComponentError()); - List<BinderResult<?, ?>> results = resultsCapture.get(); - Assert.assertNotNull(results); - Assert.assertEquals(2, results.size()); + List<ValidationStatus<?>> bindingStatuses = status + .getFieldValidationStatuses(); + Assert.assertNotNull(bindingStatuses); + Assert.assertEquals(1, status.getFieldValidationErrors().size()); + Assert.assertEquals(2, bindingStatuses.size()); - BinderResult<?, ?> r = results.get(0); + ValidationStatus<?> r = bindingStatuses.get(0); Assert.assertTrue(r.isError()); - Assert.assertEquals("Value cannot be empty", r.getMessage().get()); - Assert.assertEquals(nameField, r.getField().get()); + Assert.assertEquals(EMPTY_ERROR_MESSAGE, r.getMessage().get()); + Assert.assertEquals(nameField, r.getField()); - r = results.get(1); + r = bindingStatuses.get(1); Assert.assertFalse(r.isError()); Assert.assertFalse(r.getMessage().isPresent()); - Assert.assertEquals(ageField, r.getField().get()); + Assert.assertEquals(ageField, r.getField()); + + Assert.assertEquals(0, status.getBeanValidationResults().size()); + Assert.assertEquals(0, status.getBeanValidationErrors().size()); nameField.setValue("foo"); ageField.setValue(""); - resultsCapture.set(null); + statusCapture.set(null); // Second validation succeeds => should be result with OK status and // no message, and error result for age binder.validate(); - results = resultsCapture.get(); - Assert.assertNotNull(results); - Assert.assertEquals(2, results.size()); + status = statusCapture.get(); + bindingStatuses = status.getFieldValidationStatuses(); + Assert.assertEquals(1, status.getFieldValidationErrors().size()); + Assert.assertEquals(2, bindingStatuses.size()); - r = results.get(0); + r = bindingStatuses.get(0); Assert.assertFalse(r.isError()); Assert.assertFalse(r.getMessage().isPresent()); - Assert.assertEquals(nameField, r.getField().get()); + Assert.assertEquals(nameField, r.getField()); - r = results.get(1); + r = bindingStatuses.get(1); Assert.assertTrue(r.isError()); Assert.assertEquals("Value must be a number", r.getMessage().get()); - Assert.assertEquals(ageField, r.getField().get()); + Assert.assertEquals(ageField, r.getField()); + + Assert.assertEquals(0, status.getBeanValidationResults().size()); + Assert.assertEquals(0, status.getBeanValidationErrors().size()); - resultsCapture.set(null); + statusCapture.set(null); // binding validations pass, binder validation fails ageField.setValue("0"); binder.validate(); - results = resultsCapture.get(); - Assert.assertNotNull(results); - Assert.assertEquals(1, results.size()); + status = statusCapture.get(); + bindingStatuses = status.getFieldValidationStatuses(); + Assert.assertEquals(0, status.getFieldValidationErrors().size()); + Assert.assertEquals(2, bindingStatuses.size()); - r = results.get(0); - Assert.assertTrue(r.isError()); - Assert.assertTrue(r.getMessage().isPresent()); - Assert.assertFalse(r.getField().isPresent()); + Assert.assertEquals(1, status.getBeanValidationResults().size()); + Assert.assertEquals(1, status.getBeanValidationErrors().size()); + + Assert.assertEquals("Need first name and age", + status.getBeanValidationErrors().get(0).getMessage().get()); } @Test public void binderWithStatusChangeHandler_defaultStatusChangeHandlerIsReplaced() { Binding<Person, String, String> binding = binder.forField(nameField) - .withValidator(notEmpty).withStatusChangeHandler(evt -> { + .withValidator(notEmpty).withStatusHandler(evt -> { }); binding.bind(Person::getFirstName, Person::setFirstName); @@ -991,7 +1099,7 @@ public class BinderTest { .withValidator(notEmpty); binding.bind(Person::getFirstName, Person::setFirstName); - binding.withStatusChangeHandler(evt -> Assert.fail()); + binding.withStatusHandler(evt -> Assert.fail()); } @Test(expected = IllegalStateException.class) @@ -1038,7 +1146,7 @@ public class BinderTest { @Test public void binderWithStatusChangeHandler_replaceHandler() { - AtomicReference<List<BinderResult<?, ?>>> capture = new AtomicReference<>(); + AtomicReference<BinderValidationStatus<?>> capture = new AtomicReference<>(); Binding<Person, String, String> binding = binder.forField(nameField); binding.bind(Person::getFirstName, Person::setFirstName); @@ -1054,9 +1162,11 @@ public class BinderTest { nameField.setValue("foo"); binder.validate(); - List<BinderResult<?, ?>> results = capture.get(); + List<ValidationStatus<?>> results = capture.get() + .getFieldValidationStatuses(); Assert.assertNotNull(results); Assert.assertEquals(1, results.size()); + Assert.assertFalse(results.get(0).isError()); } @Test |