summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Anisimov <denis@vaadin.com>2016-08-18 09:46:14 +0300
committerVaadin Code Review <review@vaadin.com>2016-08-18 08:09:43 +0000
commit78c6ab1852f18b142390b8852e5c10e1f017dd8f (patch)
tree1fb7bad65d1ded3e7b2095630a412294d4b446fe
parent97e4ef4aa5bd56ca46ac477c1be33d44411aca17 (diff)
downloadvaadin-framework-78c6ab1852f18b142390b8852e5c10e1f017dd8f.tar.gz
vaadin-framework-78c6ab1852f18b142390b8852e5c10e1f017dd8f.zip
Binding.validate() should fire a validation status event (#134).
Change-Id: I2121ec8f90ffcdf2fdfa02bf99084b539b27180e
-rw-r--r--server/src/main/java/com/vaadin/data/Binder.java4
-rw-r--r--server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java52
-rw-r--r--server/src/test/java/com/vaadin/data/BinderTest.java66
3 files changed, 119 insertions, 3 deletions
diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java
index 4230bd379a..d4501955d6 100644
--- a/server/src/main/java/com/vaadin/data/Binder.java
+++ b/server/src/main/java/com/vaadin/data/Binder.java
@@ -485,6 +485,7 @@ public class Binder<BEAN> implements Serializable {
FIELDVALUE fieldValue = field.getValue();
Result<TARGET> dataValue = converterValidatorChain.convertToModel(
fieldValue, ((AbstractComponent) field).getLocale());
+ fireStatusChangeEvent(dataValue);
return dataValue;
}
@@ -554,7 +555,7 @@ public class Binder<BEAN> implements Serializable {
return newBinding;
}
- private void fireStatusChangeEvent(Result<?> result) {
+ private void fireStatusChangeEvent(Result<TARGET> result) {
ValidationStatusChangeEvent event = new ValidationStatusChangeEvent(
getField(),
result.isError() ? ValidationStatus.ERROR
@@ -716,7 +717,6 @@ public class Binder<BEAN> implements Serializable {
List<ValidationError<?>> resultErrors = new ArrayList<>();
for (BindingImpl<BEAN, ?, ?> binding : bindings) {
Result<?> result = binding.validate();
- binding.fireStatusChangeEvent(result);
result.ifError(errorMessage -> resultErrors
.add(new ValidationError<>(binding.field, errorMessage)));
}
diff --git a/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java b/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java
index 053f4756c4..a50e06d10f 100644
--- a/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java
+++ b/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java
@@ -256,7 +256,7 @@ public class BinderBookOfVaadinTest {
}
@Test
- public void crossFieldValidation() {
+ public void crossFieldValidation_validateUsingBinder() {
Binder<Trip> binder = new Binder<>();
PopupDateField departing = new PopupDateField("Departing");
PopupDateField returning = new PopupDateField("Returning");
@@ -311,6 +311,56 @@ public class BinderBookOfVaadinTest {
}
@Test
+ public void crossFieldValidation_validateUsingBinding() {
+ 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);
+
+ Result<Date> result = returnBinding.validate();
+ Assert.assertFalse(result.isError());
+ Assert.assertNull(departing.getComponentError());
+
+ // update returning => validation is done against this field
+ returning.setValue(past);
+ result = returnBinding.validate();
+
+ Assert.assertTrue(result.isError());
+ Assert.assertNotNull(returning.getComponentError());
+
+ // set correct value back
+ returning.setValue(before);
+ result = returnBinding.validate();
+
+ Assert.assertFalse(result.isError());
+ Assert.assertNull(departing.getComponentError());
+
+ // update departing => validation is done because of listener added
+ departing.setValue(after);
+ result = returnBinding.validate();
+
+ Assert.assertTrue(result.isError());
+ Assert.assertNotNull(returning.getComponentError());
+ }
+
+ @Test
public void withStatusLabelExample() {
Label emailStatus = new Label();
diff --git a/server/src/test/java/com/vaadin/data/BinderTest.java b/server/src/test/java/com/vaadin/data/BinderTest.java
index a4f8f83425..fddae9ac99 100644
--- a/server/src/test/java/com/vaadin/data/BinderTest.java
+++ b/server/src/test/java/com/vaadin/data/BinderTest.java
@@ -461,6 +461,25 @@ public class BinderTest {
}
@Test
+ public void bindingWithStatusChangeHandler_defaultStatusChangeHandlerIsReplaced() {
+ Binding<Person, String, String> binding = binder.forField(nameField)
+ .withValidator(notEmpty).withStatusChangeHandler(evt -> {
+ });
+ binding.bind(Person::getFirstName, Person::setLastName);
+
+ Assert.assertNull(nameField.getComponentError());
+
+ nameField.setValue("");
+
+ // First validation fails => should be event with ERROR status and
+ // message
+ binding.validate();
+
+ // default behavior should update component error for the nameField
+ Assert.assertNull(nameField.getComponentError());
+ }
+
+ @Test
public void withStatusLabel_labelIsUpdatedAccordingStatus() {
Label label = new Label();
@@ -488,6 +507,33 @@ public class BinderTest {
}
@Test
+ public void bindingWithStatusLabel_labelIsUpdatedAccordingStatus() {
+ Label label = new Label();
+
+ Binding<Person, String, String> binding = binder.forField(nameField)
+ .withValidator(notEmpty).withStatusLabel(label);
+ binding.bind(Person::getFirstName, Person::setLastName);
+
+ nameField.setValue("");
+
+ // First validation fails => should be event with ERROR status and
+ // message
+ binding.validate();
+
+ Assert.assertTrue(label.isVisible());
+ Assert.assertEquals("Value cannot be empty", label.getValue());
+
+ nameField.setValue("foo");
+
+ // Second validation succeeds => should be event with OK status and
+ // no message
+ binding.validate();
+
+ Assert.assertFalse(label.isVisible());
+ Assert.assertEquals("", label.getValue());
+ }
+
+ @Test
public void withStatusLabel_defaultStatusChangeHandlerIsReplaced() {
Label label = new Label();
@@ -507,6 +553,26 @@ public class BinderTest {
Assert.assertNull(nameField.getComponentError());
}
+ @Test
+ public void bindingWithStatusLabel_defaultStatusChangeHandlerIsReplaced() {
+ Label label = new Label();
+
+ Binding<Person, String, String> binding = binder.forField(nameField)
+ .withValidator(notEmpty).withStatusLabel(label);
+ binding.bind(Person::getFirstName, Person::setLastName);
+
+ Assert.assertNull(nameField.getComponentError());
+
+ nameField.setValue("");
+
+ // First validation fails => should be event with ERROR status and
+ // message
+ binding.validate();
+
+ // default behavior should update component error for the nameField
+ Assert.assertNull(nameField.getComponentError());
+ }
+
@Test(expected = IllegalStateException.class)
public void withStatusChangeHandler_addAfterBound() {
Binding<Person, String, String> binding = binder.forField(nameField)