|
|
@@ -8,16 +8,20 @@ import static org.junit.Assert.assertNotNull; |
|
|
|
import static org.junit.Assert.assertNull; |
|
|
|
import static org.junit.Assert.assertSame; |
|
|
|
import static org.junit.Assert.assertTrue; |
|
|
|
import static org.junit.Assert.fail; |
|
|
|
|
|
|
|
import java.util.Locale; |
|
|
|
import java.util.Objects; |
|
|
|
import java.util.concurrent.atomic.AtomicBoolean; |
|
|
|
import java.util.concurrent.atomic.AtomicInteger; |
|
|
|
import java.util.concurrent.atomic.AtomicReference; |
|
|
|
import java.util.stream.Stream; |
|
|
|
|
|
|
|
import org.junit.Assert; |
|
|
|
import org.junit.Before; |
|
|
|
import org.junit.Test; |
|
|
|
import org.junit.Rule; |
|
|
|
import org.junit.rules.ExpectedException; |
|
|
|
|
|
|
|
import com.vaadin.data.Binder.Binding; |
|
|
|
import com.vaadin.data.Binder.BindingBuilder; |
|
|
@@ -31,9 +35,17 @@ import com.vaadin.tests.data.bean.Person; |
|
|
|
import com.vaadin.tests.data.bean.Sex; |
|
|
|
import com.vaadin.ui.TextField; |
|
|
|
import org.apache.commons.lang.StringUtils; |
|
|
|
import org.hamcrest.CoreMatchers; |
|
|
|
|
|
|
|
public class BinderTest extends BinderTestBase<Binder<Person>, Person> { |
|
|
|
|
|
|
|
@Rule |
|
|
|
/* |
|
|
|
* transient to avoid interfering with serialization tests that capture a |
|
|
|
* test instance in a closure |
|
|
|
*/ |
|
|
|
public transient ExpectedException exceptionRule = ExpectedException.none(); |
|
|
|
|
|
|
|
@Before |
|
|
|
public void setUp() { |
|
|
|
binder = new Binder<>(); |
|
|
@@ -333,7 +345,7 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> { |
|
|
|
binder.setBean(namelessPerson); |
|
|
|
|
|
|
|
assertTrue(nullTextField.isEmpty()); |
|
|
|
assertEquals(null, namelessPerson.getFirstName()); |
|
|
|
assertEquals("null", namelessPerson.getFirstName()); |
|
|
|
|
|
|
|
// Change value, see that textfield is not empty and bean is updated. |
|
|
|
nullTextField.setValue(""); |
|
|
@@ -525,7 +537,7 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> { |
|
|
|
binding.bind(Person::getFirstName, Person::setFirstName); |
|
|
|
binder.setBean(item); |
|
|
|
assertNull(textField.getErrorMessage()); |
|
|
|
assertEquals(0, invokes.get()); |
|
|
|
assertEquals(1, invokes.get()); |
|
|
|
|
|
|
|
textField.setValue(" "); |
|
|
|
ErrorMessage errorMessage = textField.getErrorMessage(); |
|
|
@@ -533,7 +545,7 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> { |
|
|
|
assertEquals("Input is required.", |
|
|
|
errorMessage.getFormattedHtmlMessage()); |
|
|
|
// validation is done for all changed bindings once. |
|
|
|
assertEquals(1, invokes.get()); |
|
|
|
assertEquals(2, invokes.get()); |
|
|
|
|
|
|
|
textField.setValue("value"); |
|
|
|
assertNull(textField.getErrorMessage()); |
|
|
@@ -582,7 +594,7 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> { |
|
|
|
|
|
|
|
binder.setBean(item); |
|
|
|
assertNull(textField.getErrorMessage()); |
|
|
|
assertEquals(0, invokes.get()); |
|
|
|
assertEquals(1, invokes.get()); |
|
|
|
|
|
|
|
textField.setValue(" "); |
|
|
|
ErrorMessage errorMessage = textField.getErrorMessage(); |
|
|
@@ -590,7 +602,7 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> { |
|
|
|
assertEquals("Input required.", |
|
|
|
errorMessage.getFormattedHtmlMessage()); |
|
|
|
// validation is done for all changed bindings once. |
|
|
|
assertEquals(1, invokes.get()); |
|
|
|
assertEquals(2, invokes.get()); |
|
|
|
|
|
|
|
textField.setValue("value"); |
|
|
|
assertNull(textField.getErrorMessage()); |
|
|
@@ -1099,12 +1111,12 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> { |
|
|
|
|
|
|
|
binder.setBean(item); |
|
|
|
ageField.setValue("3"); |
|
|
|
Assert.assertEquals(infoMessage, |
|
|
|
assertEquals(infoMessage, |
|
|
|
ageField.getComponentError().getFormattedHtmlMessage()); |
|
|
|
Assert.assertEquals(ErrorLevel.INFO, |
|
|
|
assertEquals(ErrorLevel.INFO, |
|
|
|
ageField.getComponentError().getErrorLevel()); |
|
|
|
|
|
|
|
Assert.assertEquals(3, item.getAge()); |
|
|
|
assertEquals(3, item.getAge()); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
@@ -1246,4 +1258,118 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> { |
|
|
|
|
|
|
|
nameField.setValue("Foo"); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void nonSymetricValue_setBean_writtenToBean() { |
|
|
|
binder.bind(nameField, Person::getLastName, Person::setLastName); |
|
|
|
|
|
|
|
assertNull(item.getLastName()); |
|
|
|
|
|
|
|
binder.setBean(item); |
|
|
|
|
|
|
|
assertEquals("", item.getLastName()); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void nonSymmetricValue_readBean_beanNotTouched() { |
|
|
|
binder.bind(nameField, Person::getLastName, Person::setLastName); |
|
|
|
binder.addValueChangeListener( |
|
|
|
event -> fail("No value change event should be fired")); |
|
|
|
|
|
|
|
assertNull(item.getLastName()); |
|
|
|
|
|
|
|
binder.readBean(item); |
|
|
|
|
|
|
|
assertNull(item.getLastName()); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void symetricValue_setBean_beanNotUpdated() { |
|
|
|
binder.bind(nameField, Person::getFirstName, Person::setFirstName); |
|
|
|
|
|
|
|
binder.setBean(new Person() { |
|
|
|
@Override |
|
|
|
public String getFirstName() { |
|
|
|
return "First"; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public void setFirstName(String firstName) { |
|
|
|
fail("Setter should not be called"); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void nullRejetingField_nullValue_wrappedExceptionMentionsNullRepresentation() { |
|
|
|
TextField field = createNullAnd42RejectingFieldWithEmptyValue(""); |
|
|
|
|
|
|
|
Binder<AtomicReference<Integer>> binder = createIntegerConverterBinder( |
|
|
|
field); |
|
|
|
|
|
|
|
exceptionRule.expect(IllegalStateException.class); |
|
|
|
exceptionRule.expectMessage("null representation"); |
|
|
|
exceptionRule.expectCause(CoreMatchers.isA(NullPointerException.class)); |
|
|
|
|
|
|
|
binder.readBean(new AtomicReference<>()); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
public void nullRejetingField_otherRejectedValue_originalExceptionIsThrown() { |
|
|
|
TextField field = createNullAnd42RejectingFieldWithEmptyValue(""); |
|
|
|
|
|
|
|
Binder<AtomicReference<Integer>> binder = createIntegerConverterBinder( |
|
|
|
field); |
|
|
|
|
|
|
|
exceptionRule.expect(IllegalArgumentException.class); |
|
|
|
exceptionRule.expectMessage("42"); |
|
|
|
|
|
|
|
binder.readBean(new AtomicReference<>(Integer.valueOf(42))); |
|
|
|
} |
|
|
|
|
|
|
|
@Test(expected = NullPointerException.class) |
|
|
|
public void nullAcceptingField_nullValue_originalExceptionIsThrown() { |
|
|
|
/* |
|
|
|
* Edge case with a field that throws for null but has null as the empty |
|
|
|
* value. This is most likely the case if the field doesn't explicitly |
|
|
|
* reject null values but is instead somehow broken so that any value is |
|
|
|
* rejected. |
|
|
|
*/ |
|
|
|
TextField field = createNullAnd42RejectingFieldWithEmptyValue(null); |
|
|
|
|
|
|
|
Binder<AtomicReference<Integer>> binder = createIntegerConverterBinder( |
|
|
|
field); |
|
|
|
|
|
|
|
binder.readBean(new AtomicReference<>(null)); |
|
|
|
} |
|
|
|
|
|
|
|
private TextField createNullAnd42RejectingFieldWithEmptyValue( |
|
|
|
String emptyValue) { |
|
|
|
return new TextField() { |
|
|
|
@Override |
|
|
|
public void setValue(String value) { |
|
|
|
if (value == null) { |
|
|
|
throw new NullPointerException("Null value"); |
|
|
|
} else if ("42".equals(value)) { |
|
|
|
throw new IllegalArgumentException("42 is not allowed"); |
|
|
|
} |
|
|
|
super.setValue(value); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public String getEmptyValue() { |
|
|
|
return emptyValue; |
|
|
|
} |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
private Binder<AtomicReference<Integer>> createIntegerConverterBinder( |
|
|
|
TextField field) { |
|
|
|
Binder<AtomicReference<Integer>> binder = new Binder<>(); |
|
|
|
binder.forField(field) |
|
|
|
.withConverter(new StringToIntegerConverter("Must have number")) |
|
|
|
.bind(AtomicReference::get, AtomicReference::set); |
|
|
|
return binder; |
|
|
|
} |
|
|
|
} |