diff options
author | Denis Anisimov <denis@vaadin.com> | 2016-08-16 16:09:35 +0300 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2016-08-17 07:48:06 +0000 |
commit | c91703aff22b3ef8adaf86afb82c50a344f1ab76 (patch) | |
tree | 672a3b62f755c23e70bb8e9e632339a9df8b3b24 | |
parent | a5575a9252f4e502624079c65c7080e741846692 (diff) | |
download | vaadin-framework-c91703aff22b3ef8adaf86afb82c50a344f1ab76.tar.gz vaadin-framework-c91703aff22b3ef8adaf86afb82c50a344f1ab76.zip |
Test that cross field validation works as expected (#33).
Test for cross field validation from Book of Vaadin.
Change-Id: Ida338bd79456332b3a359217ea7b9900a1408153
-rw-r--r-- | documentation/datamodel/datamodel-forms.asciidoc | 12 | ||||
-rw-r--r-- | server/src/main/java/com/vaadin/data/Binder.java | 14 | ||||
-rw-r--r-- | server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java | 70 |
3 files changed, 88 insertions, 8 deletions
diff --git a/documentation/datamodel/datamodel-forms.asciidoc b/documentation/datamodel/datamodel-forms.asciidoc index 3bea6f857c..8acbffdd7a 100644 --- a/documentation/datamodel/datamodel-forms.asciidoc +++ b/documentation/datamodel/datamodel-forms.asciidoc @@ -205,15 +205,13 @@ PopupDateField departing = new PopupDateField("Departing"); PopupDateField returning = new PopupDateField("Returning"); // Store return date binding so we can revalidate it later -FieldBinding<Trip, LocalDate> returnBinding = binder - .forField(returning) - .withValidator( - returnDate -> !returnDate.isBefore(departing.getValue()), - "Cannot return before departing") - .bind(Trip::getReturnDate, Trip::setReturnDate); +Binding<Trip, Date, Date> returnBinding = binder.forField(returning) + .withValidator(returnDate -> !returnDate.before(departing.getValue()), + "Cannot return before departing"); +returnBinding.bind(Trip::getReturnDate, Trip::setReturnDate); // Revalidate return date when departure date changes -departing.onChange(newValue -> returnBinding.validate()); +departing.addValueChangeListener(event -> returnBinding.validate()); ---- == Converting User Input diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java index 8c637118d6..5ce80d2c0b 100644 --- a/server/src/main/java/com/vaadin/data/Binder.java +++ b/server/src/main/java/com/vaadin/data/Binder.java @@ -262,6 +262,17 @@ public class Binder<BEAN> implements Serializable { */ public HasValue<FIELDVALUE> getField(); + /** + * Validates the field value and returns a {@code Result} instance + * representing the outcome of the validation. + * + * @see Binder#validate() + * @see Validator#apply(Object) + * + * @return the validation result. + */ + public Result<TARGET> validate(); + } /** @@ -372,7 +383,8 @@ public class Binder<BEAN> implements Serializable { .addValueChangeListener(e -> storeFieldValue(bean)); } - private Result<TARGET> validate() { + @Override + public Result<TARGET> validate() { FIELDVALUE fieldValue = field.getValue(); Result<TARGET> dataValue = converterValidatorChain.convertToModel( fieldValue, ((AbstractComponent) field).getLocale()); diff --git a/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java b/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java index 74cec124a6..6fcfe61ce3 100644 --- a/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java +++ b/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java @@ -15,6 +15,8 @@ */ package com.vaadin.data; +import java.util.Calendar; +import java.util.Date; import java.util.List; import org.junit.Assert; @@ -26,6 +28,7 @@ import com.vaadin.data.util.converter.StringToIntegerConverter; import com.vaadin.data.validator.EmailValidator; import com.vaadin.server.AbstractErrorMessage; import com.vaadin.ui.AbstractField; +import com.vaadin.ui.PopupDateField; import com.vaadin.ui.Slider; /** @@ -95,6 +98,18 @@ public class BinderBookOfVaadinTest { } + public static class Trip { + private Date returnDate; + + public Date getReturnDate() { + return returnDate; + } + + public void setReturnDate(Date returnDate) { + this.returnDate = returnDate; + } + } + private Binder<BookPerson> binder; private TextField field; @@ -238,4 +253,59 @@ public class BinderBookOfVaadinTest { yearOfBirthField.getComponentError().getFormattedHtmlMessage()); } + @Test + public void crossFieldValidation() { + Binder<Trip> binder = new Binder<>(); + PopupDateField departing = new PopupDateField("Departing"); + PopupDateField returning = new PopupDateField("Returning"); + + Binding<Trip, Date, Date> returnBinding = binder.forField(returning) + .withValidator( + returnDate -> !returnDate.before(departing.getValue()), + "Cannot return before departing"); + + returnBinding.bind(Trip::getReturnDate, Trip::setReturnDate); + departing.addValueChangeListener(event -> returnBinding.validate()); + + Calendar calendar = Calendar.getInstance(); + Date past = calendar.getTime(); + calendar.add(1, Calendar.DAY_OF_YEAR); + Date before = calendar.getTime(); + calendar.add(1, Calendar.DAY_OF_YEAR); + Date after = calendar.getTime(); + + departing.setValue(before); + returning.setValue(after); + + List<ValidationError<?>> errors = binder.validate(); + Assert.assertTrue(errors.isEmpty()); + Assert.assertNull(departing.getComponentError()); + Assert.assertNull(returning.getComponentError()); + + // update returning => validation is done against this field + returning.setValue(past); + errors = binder.validate(); + + Assert.assertFalse(errors.isEmpty()); + Assert.assertNotNull(returning.getComponentError()); + Assert.assertNull(departing.getComponentError()); + + // set correct value back + returning.setValue(before); + errors = binder.validate(); + + Assert.assertTrue(errors.isEmpty()); + Assert.assertNull(departing.getComponentError()); + Assert.assertNull(returning.getComponentError()); + + // update departing => validation is done because of listener added + departing.setValue(after); + errors = binder.validate(); + + Assert.assertFalse(errors.isEmpty()); + Assert.assertNotNull(returning.getComponentError()); + Assert.assertNull(departing.getComponentError()); + + } + } |