123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638 |
- package com.vaadin.data;
-
- import static org.junit.Assert.assertEquals;
- import static org.junit.Assert.assertFalse;
- 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 java.util.Locale;
- import java.util.Objects;
- import java.util.concurrent.atomic.AtomicInteger;
-
- import org.junit.Assert;
- import org.junit.Before;
- import org.junit.Test;
-
- import com.vaadin.data.Binder.BindingBuilder;
- import com.vaadin.data.converter.StringToIntegerConverter;
- import com.vaadin.data.validator.NotEmptyValidator;
- import com.vaadin.server.ErrorMessage;
- import com.vaadin.tests.data.bean.Person;
- import com.vaadin.tests.data.bean.Sex;
- import com.vaadin.ui.TextField;
-
- public class BinderTest extends BinderTestBase<Binder<Person>, Person> {
-
- @Before
- public void setUp() {
- binder = new Binder<>();
- item = new Person();
- item.setFirstName("Johannes");
- item.setAge(32);
- }
-
- @Test
- public void bindNullBean_noBeanPresent() {
- binder.setBean(item);
- assertNotNull(binder.getBean());
-
- binder.setBean(null);
- assertNull(binder.getBean());
- }
-
- @Test
- public void bindNullBean_FieldsAreCleared() {
- binder.forField(nameField).bind(Person::getFirstName,
- Person::setFirstName);
- binder.forField(ageField)
- .withConverter(new StringToIntegerConverter(""))
- .bind(Person::getAge, Person::setAge);
- binder.setBean(item);
- assertEquals("No name field value","Johannes", nameField.getValue());
- assertEquals("No age field value", "32", ageField.getValue());
-
- binder.setBean(null);
- assertEquals("Name field not empty", "", nameField.getValue());
- assertEquals("Age field not empty", "", ageField.getValue());
- }
-
- @Test
- public void clearForReadBean_boundFieldsAreCleared() {
- binder.forField(nameField).bind(Person::getFirstName,
- Person::setFirstName);
- binder.forField(ageField)
- .withConverter(new StringToIntegerConverter(""))
- .bind(Person::getAge, Person::setAge);
- binder.readBean(item);
-
- assertEquals("No name field value","Johannes", nameField.getValue());
- assertEquals("No age field value", "32", ageField.getValue());
-
- binder.readBean(null);
- assertEquals("Name field not empty", "", nameField.getValue());
- assertEquals("Age field not empty", "", ageField.getValue());
- }
-
- @Test
- public void clearReadOnlyField_shouldClearField() {
- binder.forField(nameField).bind(Person::getFirstName,
- Person::setFirstName);
-
- // Make name field read only
- nameField.setReadOnly(true);
-
- binder.setBean(item);
- assertEquals("No name field value", "Johannes", nameField.getValue());
-
- binder.setBean(null);
-
- assertEquals("ReadOnly field not empty","", nameField.getValue());
- }
-
- @Test
- public void clearBean_setsHasChangesToFalse() {
- binder.forField(nameField).bind(Person::getFirstName,
- Person::setFirstName);
-
- // Make name field read only
- nameField.setReadOnly(true);
-
- binder.readBean(item);
- assertEquals("No name field value", "Johannes", nameField.getValue());
- nameField.setValue("James");
-
- assertTrue("Binder did not have value changes", binder.hasChanges());
-
- binder.readBean(null);
-
- assertFalse("Binder has changes after clearing all fields",
- binder.hasChanges());
-
- }
-
- @Test
- public void clearReadOnlyBinder_shouldClearFields() {
- binder.forField(nameField).bind(Person::getFirstName,
- Person::setFirstName);
- binder.forField(ageField)
- .withConverter(new StringToIntegerConverter(""))
- .bind(Person::getAge, Person::setAge);
-
- binder.setReadOnly(true);
-
- binder.setBean(item);
-
- binder.setBean(null);
- assertEquals("ReadOnly name field not empty", "", nameField.getValue());
- assertEquals("ReadOnly age field not empty", "", ageField.getValue());
- }
-
- @Test(expected = NullPointerException.class)
- public void bindNullField_throws() {
- binder.forField(null);
- }
-
- @Test(expected = NullPointerException.class)
- public void bindNullGetter_throws() {
- binder.bind(nameField, null, Person::setFirstName);
- }
-
- @Test
- public void fieldBound_bindItem_fieldValueUpdated() {
- binder.forField(nameField).bind(Person::getFirstName,
- Person::setFirstName);
- binder.setBean(item);
- assertEquals("Johannes", nameField.getValue());
- }
-
- @Test
- public void fieldBoundWithShortcut_bindBean_fieldValueUpdated() {
- bindName();
- assertEquals("Johannes", nameField.getValue());
- }
-
- @Test
- public void beanBound_updateFieldValue_beanValueUpdated() {
- binder.setBean(item);
- binder.bind(nameField, Person::getFirstName, Person::setFirstName);
-
- assertEquals("Johannes", nameField.getValue());
- nameField.setValue("Artur");
- assertEquals("Artur", item.getFirstName());
- }
-
- @Test
- public void bound_getBean_returnsBoundBean() {
- assertNull(binder.getBean());
- binder.setBean(item);
- assertSame(item, binder.getBean());
- }
-
- @Test
- public void unbound_getBean_returnsNothing() {
- binder.setBean(item);
- binder.removeBean();
- assertNull(binder.getBean());
- }
-
- @Test
- public void bound_changeFieldValue_beanValueUpdated() {
- bindName();
- nameField.setValue("Henri");
- assertEquals("Henri", item.getFirstName());
- }
-
- @Test
- public void unbound_changeFieldValue_beanValueNotUpdated() {
- bindName();
- nameField.setValue("Henri");
- binder.removeBean();
- nameField.setValue("Aleksi");
- assertEquals("Henri", item.getFirstName());
- }
-
- @Test
- public void bindNullSetter_valueChangesIgnored() {
- binder.bind(nameField, Person::getFirstName, null);
- binder.setBean(item);
- nameField.setValue("Artur");
- assertEquals(item.getFirstName(), "Johannes");
- }
-
- @Test
- public void bound_bindToAnotherBean_stopsUpdatingOriginal() {
- bindName();
- nameField.setValue("Leif");
-
- Person p2 = new Person();
- p2.setFirstName("Marlon");
- binder.setBean(p2);
- assertEquals("Marlon", nameField.getValue());
- assertEquals("Leif", item.getFirstName());
- assertSame(p2, binder.getBean());
-
- nameField.setValue("Ilia");
- assertEquals("Ilia", p2.getFirstName());
- assertEquals("Leif", item.getFirstName());
- }
-
- @Test
- public void save_unbound_noChanges() throws ValidationException {
- Binder<Person> binder = new Binder<>();
- Person person = new Person();
-
- int age = 10;
- person.setAge(age);
-
- binder.writeBean(person);
-
- Assert.assertEquals(age, person.getAge());
- }
-
- @Test
- public void save_bound_beanIsUpdated() throws ValidationException {
- Binder<Person> binder = new Binder<>();
- binder.bind(nameField, Person::getFirstName, Person::setFirstName);
-
- Person person = new Person();
-
- String fieldValue = "bar";
- nameField.setValue(fieldValue);
-
- person.setFirstName("foo");
-
- binder.writeBean(person);
-
- Assert.assertEquals(fieldValue, person.getFirstName());
- }
-
- @Test
- public void load_bound_fieldValueIsUpdated() {
- binder.bind(nameField, Person::getFirstName, Person::setFirstName);
-
- Person person = new Person();
-
- String name = "bar";
- person.setFirstName(name);
- binder.readBean(person);
-
- Assert.assertEquals(name, nameField.getValue());
- }
-
- @Test
- public void load_unbound_noChanges() {
- nameField.setValue("");
-
- Person person = new Person();
-
- String name = "bar";
- person.setFirstName(name);
- binder.readBean(person);
-
- Assert.assertEquals("", nameField.getValue());
- }
-
- protected void bindName() {
- binder.bind(nameField, Person::getFirstName, Person::setFirstName);
- binder.setBean(item);
- }
-
- @Test
- public void binding_with_null_representation() {
- String nullRepresentation = "Some arbitrary text";
- String realName = "John";
- Person namelessPerson = new Person(null, "Doe", "", 25, Sex.UNKNOWN,
- null);
-
- binder.forField(nameField).withNullRepresentation(nullRepresentation)
- .bind(Person::getFirstName, Person::setFirstName);
-
- // Bind a person with null value and check that null representation is
- // used
- binder.setBean(namelessPerson);
- Assert.assertEquals(
- "Null value from bean was not converted to explicit null representation",
- nullRepresentation, nameField.getValue());
-
- // Verify that changes are applied to bean
- nameField.setValue(realName);
- Assert.assertEquals(
- "Bean was not correctly updated from a change in the field",
- realName, namelessPerson.getFirstName());
-
- // Verify conversion back to null
- nameField.setValue(nullRepresentation);
- Assert.assertEquals(
- "Two-way null representation did not change value back to null",
- null, namelessPerson.getFirstName());
- }
-
- @Test
- public void binding_with_default_null_representation() {
- TextField nullTextField = new TextField() {
- @Override
- public String getEmptyValue() {
- return "null";
- }
- };
-
- Person namelessPerson = new Person(null, "Doe", "", 25, Sex.UNKNOWN,
- null);
- binder.bind(nullTextField, Person::getFirstName, Person::setFirstName);
- binder.setBean(namelessPerson);
-
- assertTrue(nullTextField.isEmpty());
- Assert.assertEquals(null, namelessPerson.getFirstName());
-
- // Change value, see that textfield is not empty and bean is updated.
- nullTextField.setValue("");
- assertFalse(nullTextField.isEmpty());
- Assert.assertEquals("First name of person was not properly updated", "",
- namelessPerson.getFirstName());
-
- // Verify that default null representation does not map back to null
- nullTextField.setValue("null");
- assertTrue(nullTextField.isEmpty());
- Assert.assertEquals("Default one-way null representation failed.",
- "null", namelessPerson.getFirstName());
- }
-
- @Test
- public void binding_with_null_representation_value_not_null() {
- String nullRepresentation = "Some arbitrary text";
-
- binder.forField(nameField).withNullRepresentation(nullRepresentation)
- .bind(Person::getFirstName, Person::setFirstName);
-
- assertFalse("First name in item should not be null",
- Objects.isNull(item.getFirstName()));
- binder.setBean(item);
-
- Assert.assertEquals("Field value was not set correctly",
- item.getFirstName(), nameField.getValue());
- }
-
- @Test
- public void withConverter_disablesDefaulNullRepresentation() {
- Integer customNullConverter = 0;
- binder.forField(ageField).withNullRepresentation("foo")
- .withConverter(new StringToIntegerConverter(""))
- .withConverter(age -> age,
- age -> age == null ? customNullConverter : age)
- .bind(Person::getSalary, Person::setSalary);
- binder.setBean(item);
-
- Assert.assertEquals(customNullConverter.toString(),
- ageField.getValue());
-
- Integer salary = 11;
- ageField.setValue(salary.toString());
- Assert.assertEquals(11, salary.intValue());
- }
-
- @Test
- public void beanBinder_nullRepresentationIsNotDisabled() {
- Binder<Person> binder = new Binder<>(Person.class);
- binder.forField(nameField).bind("firstName");
-
- Person person = new Person();
- binder.setBean(person);
-
- Assert.assertEquals("", nameField.getValue());
- }
-
- @Test
- public void beanBinder_withConverter_nullRepresentationIsNotDisabled() {
- String customNullPointerRepresentation = "foo";
- Binder<Person> binder = new Binder<>(Person.class);
- binder.forField(nameField)
- .withConverter(value -> value, value -> value == null
- ? customNullPointerRepresentation : value)
- .bind("firstName");
-
- Person person = new Person();
- binder.setBean(person);
-
- Assert.assertEquals(customNullPointerRepresentation,
- nameField.getValue());
- }
-
- @Test
- public void withValidator_doesNotDisablesDefaulNullRepresentation() {
- String nullRepresentation = "foo";
- binder.forField(nameField).withNullRepresentation(nullRepresentation)
- .withValidator(new NotEmptyValidator<>(""))
- .bind(Person::getFirstName, Person::setFirstName);
- item.setFirstName(null);
- binder.setBean(item);
-
- Assert.assertEquals(nullRepresentation, nameField.getValue());
-
- String newValue = "bar";
- nameField.setValue(newValue);
- Assert.assertEquals(newValue, item.getFirstName());
- }
-
- @Test
- public void setRequired_withErrorMessage_fieldGetsRequiredIndicatorAndValidator() {
- TextField textField = new TextField();
- assertFalse(textField.isRequiredIndicatorVisible());
-
- BindingBuilder<Person, String> binding = binder.forField(textField);
- assertFalse(textField.isRequiredIndicatorVisible());
-
- binding.asRequired("foobar");
- assertTrue(textField.isRequiredIndicatorVisible());
-
- binding.bind(Person::getFirstName, Person::setFirstName);
- binder.setBean(item);
- Assert.assertNull(textField.getErrorMessage());
-
- textField.setValue(textField.getEmptyValue());
- ErrorMessage errorMessage = textField.getErrorMessage();
- Assert.assertNotNull(errorMessage);
- Assert.assertEquals("foobar", errorMessage.getFormattedHtmlMessage());
-
- textField.setValue("value");
- Assert.assertNull(textField.getErrorMessage());
- assertTrue(textField.isRequiredIndicatorVisible());
- }
-
- @Test
- public void setRequired_withErrorMessageProvider_fieldGetsRequiredIndicatorAndValidator() {
- TextField textField = new TextField();
- textField.setLocale(Locale.CANADA);
- assertFalse(textField.isRequiredIndicatorVisible());
-
- BindingBuilder<Person, String> binding = binder.forField(textField);
- assertFalse(textField.isRequiredIndicatorVisible());
- AtomicInteger invokes = new AtomicInteger();
-
- binding.asRequired(context -> {
- invokes.incrementAndGet();
- Assert.assertSame(Locale.CANADA, context.getLocale().get());
- return "foobar";
- });
- assertTrue(textField.isRequiredIndicatorVisible());
-
- binding.bind(Person::getFirstName, Person::setFirstName);
- binder.setBean(item);
- Assert.assertNull(textField.getErrorMessage());
- Assert.assertEquals(0, invokes.get());
-
- textField.setValue(textField.getEmptyValue());
- ErrorMessage errorMessage = textField.getErrorMessage();
- Assert.assertNotNull(errorMessage);
- Assert.assertEquals("foobar", errorMessage.getFormattedHtmlMessage());
- // validation is run twice, once for the field, then for all the fields
- // for cross field validation...
- Assert.assertEquals(2, invokes.get());
-
- textField.setValue("value");
- Assert.assertNull(textField.getErrorMessage());
- assertTrue(textField.isRequiredIndicatorVisible());
- }
-
- @Test
- public void validationStatusHandler_onlyRunForChangedField() {
- TextField firstNameField = new TextField();
- TextField lastNameField = new TextField();
-
- AtomicInteger invokes = new AtomicInteger();
-
- binder.forField(firstNameField)
- .withValidator(new NotEmptyValidator<>(""))
- .withValidationStatusHandler(
- validationStatus -> invokes.addAndGet(1))
- .bind(Person::getFirstName, Person::setFirstName);
- binder.forField(lastNameField)
- .withValidator(new NotEmptyValidator<>(""))
- .bind(Person::getLastName, Person::setLastName);
-
- binder.setBean(item);
- // setting the bean causes 2:
- Assert.assertEquals(2, invokes.get());
-
- lastNameField.setValue("");
- Assert.assertEquals(2, invokes.get());
-
- firstNameField.setValue("");
- Assert.assertEquals(3, invokes.get());
-
- binder.removeBean();
- Person person = new Person();
- person.setFirstName("a");
- person.setLastName("a");
- binder.readBean(person);
- // reading from a bean causes 2:
- Assert.assertEquals(5, invokes.get());
-
- lastNameField.setValue("");
- Assert.assertEquals(5, invokes.get());
-
- firstNameField.setValue("");
- Assert.assertEquals(6, invokes.get());
- }
-
- @Test(expected = IllegalStateException.class)
- public void noArgsConstructor_stringBind_throws() {
- binder.bind(new TextField(), "firstName");
- }
-
- @Test
- public void setReadOnly_unboundBinder() {
- binder.forField(nameField).bind(Person::getFirstName,
- Person::setFirstName);
-
- binder.forField(ageField);
-
- binder.setReadOnly(true);
-
- assertTrue(nameField.isReadOnly());
- assertFalse(ageField.isReadOnly());
-
- binder.setReadOnly(false);
-
- assertFalse(nameField.isReadOnly());
- assertFalse(ageField.isReadOnly());
- }
-
- @Test
- public void setReadOnly_boundBinder() {
- binder.forField(nameField).bind(Person::getFirstName,
- Person::setFirstName);
-
- binder.forField(ageField)
- .withConverter(new StringToIntegerConverter(""))
- .bind(Person::getAge, Person::setAge);
-
- binder.setBean(new Person());
-
- binder.setReadOnly(true);
-
- assertTrue(nameField.isReadOnly());
- assertTrue(ageField.isReadOnly());
-
- binder.setReadOnly(false);
-
- assertFalse(nameField.isReadOnly());
- assertFalse(ageField.isReadOnly());
- }
-
- @Test
- public void setReadOnly_binderLoadedByReadBean() {
- binder.forField(nameField).bind(Person::getFirstName,
- Person::setFirstName);
-
- binder.forField(ageField)
- .withConverter(new StringToIntegerConverter(""))
- .bind(Person::getAge, Person::setAge);
-
- binder.readBean(new Person());
-
- binder.setReadOnly(true);
-
- assertTrue(nameField.isReadOnly());
- assertTrue(ageField.isReadOnly());
-
- binder.setReadOnly(false);
-
- assertFalse(nameField.isReadOnly());
- assertFalse(ageField.isReadOnly());
- }
-
- @Test
- public void isValidTest_bound_binder() {
- binder.forField(nameField)
- .withValidator(
- Validator.from(
- name -> !name.equals("fail field validation"),
- ""))
- .bind(Person::getFirstName, Person::setFirstName);
-
- binder.withValidator(
- Validator.from(person -> !person.getFirstName()
- .equals("fail bean validation"), ""));
-
- binder.setBean(item);
-
- Assert.assertTrue(binder.isValid());
-
- nameField.setValue("fail field validation");
- Assert.assertFalse(binder.isValid());
-
- nameField.setValue("");
- Assert.assertTrue(binder.isValid());
-
- nameField.setValue("fail bean validation");
- Assert.assertFalse(binder.isValid());
- }
-
- @Test
- public void isValidTest_unbound_binder() {
- binder.forField(nameField)
- .withValidator(Validator.from(
- name -> !name.equals("fail field validation"), ""))
- .bind(Person::getFirstName, Person::setFirstName);
-
- Assert.assertTrue(binder.isValid());
-
- nameField.setValue("fail field validation");
- Assert.assertFalse(binder.isValid());
-
- nameField.setValue("");
- Assert.assertTrue(binder.isValid());
- }
-
- @Test(expected = IllegalStateException.class)
- public void isValidTest_unbound_binder_throws_with_bean_level_validation() {
- binder.forField(nameField).bind(Person::getFirstName,
- Person::setFirstName);
- binder.withValidator(Validator.from(
- person -> !person.getFirstName().equals("fail bean validation"),
- ""));
- binder.isValid();
- }
- }
|