From 2fd7e13c421114963762ee2e2832cbda6520efa6 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Thu, 12 Jan 2017 09:22:50 +0200 Subject: Integrate BeanBinder functionality into Binder (#8096) * Integrate BeanBinder functionality into Binder --- .../vaadin/data/BeanBinderInstanceFieldTest.java | 387 -------------------- .../com/vaadin/data/BeanBinderPropertySetTest.java | 52 +++ .../test/java/com/vaadin/data/BeanBinderTest.java | 39 +-- .../com/vaadin/data/BinderBookOfVaadinTest.java | 4 +- .../vaadin/data/BinderCustomPropertySetTest.java | 144 ++++++++ .../com/vaadin/data/BinderInstanceFieldTest.java | 388 +++++++++++++++++++++ .../src/test/java/com/vaadin/data/BinderTest.java | 9 +- .../src/test/java/com/vaadin/data/Jsr303Test.java | 3 +- 8 files changed, 601 insertions(+), 425 deletions(-) delete mode 100644 server/src/test/java/com/vaadin/data/BeanBinderInstanceFieldTest.java create mode 100644 server/src/test/java/com/vaadin/data/BeanBinderPropertySetTest.java create mode 100644 server/src/test/java/com/vaadin/data/BinderCustomPropertySetTest.java create mode 100644 server/src/test/java/com/vaadin/data/BinderInstanceFieldTest.java (limited to 'server/src/test/java') diff --git a/server/src/test/java/com/vaadin/data/BeanBinderInstanceFieldTest.java b/server/src/test/java/com/vaadin/data/BeanBinderInstanceFieldTest.java deleted file mode 100644 index 9ed2e8edda..0000000000 --- a/server/src/test/java/com/vaadin/data/BeanBinderInstanceFieldTest.java +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.data; - -import java.time.LocalDate; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.annotations.PropertyId; -import com.vaadin.data.converter.StringToIntegerConverter; -import com.vaadin.data.validator.StringLengthValidator; -import com.vaadin.tests.data.bean.Person; -import com.vaadin.ui.AbstractField; -import com.vaadin.ui.AbstractTextField; -import com.vaadin.ui.DateField; -import com.vaadin.ui.FormLayout; -import com.vaadin.ui.TextField; - -/** - * Unit tests for {@link BeanBinder#bindInstanceFields(Object)} method. - * - * @author Vaadin Ltd - * - */ -public class BeanBinderInstanceFieldTest { - - public static class BindAllFields extends FormLayout { - private TextField firstName; - private DateField birthDate; - } - - public static class BindFieldsUsingAnnotation extends FormLayout { - @PropertyId("firstName") - private TextField nameField; - - @PropertyId("birthDate") - private DateField birthDateField; - } - - public static class BindOnlyOneField extends FormLayout { - private TextField firstName; - private TextField noFieldInPerson; - } - - public static class BindNoHasValueField extends FormLayout { - private String firstName; - } - - public static class BindGenericField extends FormLayout { - private CustomField firstName; - } - - public static class BindGenericWrongTypeParameterField extends FormLayout { - private CustomField firstName; - } - - public static class BindWrongTypeParameterField extends FormLayout { - private IntegerTextField firstName; - } - - public static class BindGeneric extends FormLayout { - private CustomField firstName; - } - - public static class BindRaw extends FormLayout { - private CustomField firstName; - } - - public static class BindAbstract extends FormLayout { - private AbstractTextField firstName; - } - - public static class BindNonInstantiatableType extends FormLayout { - private NoDefaultCtor firstName; - } - - public static class BindComplextHierarchyGenericType extends FormLayout { - private ComplexHierarchy firstName; - } - - public static class NoDefaultCtor extends TextField { - public NoDefaultCtor(int arg) { - } - } - - public static class IntegerTextField extends CustomField { - - } - - public static class ComplexHierarchy extends Generic { - - } - - public static class Generic extends ComplexGeneric { - - } - - public static class ComplexGeneric extends CustomField { - - } - - public static class CustomField extends AbstractField { - - private T value; - - @Override - public T getValue() { - return value; - } - - @Override - protected void doSetValue(T value) { - this.value = value; - } - - } - - @Test - public void bindInstanceFields_bindAllFields() { - BindAllFields form = new BindAllFields(); - BeanBinder binder = new BeanBinder<>(Person.class); - binder.bindInstanceFields(form); - - Person person = new Person(); - person.setFirstName("foo"); - person.setBirthDate(LocalDate.now()); - - binder.setBean(person); - - Assert.assertEquals(person.getFirstName(), form.firstName.getValue()); - Assert.assertEquals(person.getBirthDate(), form.birthDate.getValue()); - - form.firstName.setValue("bar"); - form.birthDate.setValue(person.getBirthDate().plusDays(345)); - - Assert.assertEquals(form.firstName.getValue(), person.getFirstName()); - Assert.assertEquals(form.birthDate.getValue(), person.getBirthDate()); - } - - @Test - public void bindInstanceFields_bindOnlyOneFields() { - BindOnlyOneField form = new BindOnlyOneField(); - BeanBinder binder = new BeanBinder<>(Person.class); - binder.bindInstanceFields(form); - - Person person = new Person(); - person.setFirstName("foo"); - - binder.setBean(person); - - Assert.assertEquals(person.getFirstName(), form.firstName.getValue()); - - Assert.assertNull(form.noFieldInPerson); - - form.firstName.setValue("bar"); - - Assert.assertEquals(form.firstName.getValue(), person.getFirstName()); - } - - @Test - public void bindInstanceFields_bindNotHasValueField_fieldIsNull() { - BindNoHasValueField form = new BindNoHasValueField(); - BeanBinder binder = new BeanBinder<>(Person.class); - binder.bindInstanceFields(form); - - Person person = new Person(); - person.setFirstName("foo"); - - binder.setBean(person); - - Assert.assertNull(form.firstName); - } - - @Test - public void bindInstanceFields_genericField() { - BindGenericField form = new BindGenericField(); - BeanBinder binder = new BeanBinder<>(Person.class); - binder.bindInstanceFields(form); - - Person person = new Person(); - person.setFirstName("foo"); - - binder.setBean(person); - - Assert.assertEquals(person.getFirstName(), form.firstName.getValue()); - - form.firstName.setValue("bar"); - - Assert.assertEquals(form.firstName.getValue(), person.getFirstName()); - } - - @Test(expected = IllegalStateException.class) - public void bindInstanceFields_genericFieldWithWrongTypeParameter() { - BindGenericWrongTypeParameterField form = new BindGenericWrongTypeParameterField(); - BeanBinder binder = new BeanBinder<>(Person.class); - binder.bindInstanceFields(form); - } - - @Test(expected = IllegalStateException.class) - public void bindInstanceFields_generic() { - BindGeneric form = new BindGeneric<>(); - BeanBinder binder = new BeanBinder<>(Person.class); - binder.bindInstanceFields(form); - } - - @Test(expected = IllegalStateException.class) - public void bindInstanceFields_rawFieldType() { - BindRaw form = new BindRaw(); - BeanBinder binder = new BeanBinder<>(Person.class); - binder.bindInstanceFields(form); - } - - @Test(expected = IllegalStateException.class) - public void bindInstanceFields_abstractFieldType() { - BindAbstract form = new BindAbstract(); - BeanBinder binder = new BeanBinder<>(Person.class); - binder.bindInstanceFields(form); - } - - @Test(expected = IllegalStateException.class) - public void bindInstanceFields_noInstantiatableFieldType() { - BindNonInstantiatableType form = new BindNonInstantiatableType(); - BeanBinder binder = new BeanBinder<>(Person.class); - binder.bindInstanceFields(form); - } - - @Test(expected = IllegalStateException.class) - public void bindInstanceFields_wrongFieldType() { - BindWrongTypeParameterField form = new BindWrongTypeParameterField(); - BeanBinder binder = new BeanBinder<>(Person.class); - binder.bindInstanceFields(form); - } - - @Test - public void bindInstanceFields_complexGenericHierarchy() { - BindComplextHierarchyGenericType form = new BindComplextHierarchyGenericType(); - BeanBinder binder = new BeanBinder<>(Person.class); - binder.bindInstanceFields(form); - - Person person = new Person(); - person.setFirstName("foo"); - - binder.setBean(person); - - Assert.assertEquals(person.getFirstName(), form.firstName.getValue()); - - form.firstName.setValue("bar"); - - Assert.assertEquals(form.firstName.getValue(), person.getFirstName()); - } - - @Test - public void bindInstanceFields_bindNotHasValueField_fieldIsNotReplaced() { - BindNoHasValueField form = new BindNoHasValueField(); - BeanBinder binder = new BeanBinder<>(Person.class); - - String name = "foo"; - form.firstName = name; - - binder.bindInstanceFields(form); - - Person person = new Person(); - person.setFirstName("foo"); - - binder.setBean(person); - - Assert.assertEquals(name, form.firstName); - } - - @Test - public void bindInstanceFields_bindAllFieldsUsingAnnotations() { - BindFieldsUsingAnnotation form = new BindFieldsUsingAnnotation(); - BeanBinder binder = new BeanBinder<>(Person.class); - binder.bindInstanceFields(form); - - Person person = new Person(); - person.setFirstName("foo"); - person.setBirthDate(LocalDate.now()); - - binder.setBean(person); - - Assert.assertEquals(person.getFirstName(), form.nameField.getValue()); - Assert.assertEquals(person.getBirthDate(), - form.birthDateField.getValue()); - - form.nameField.setValue("bar"); - form.birthDateField.setValue(person.getBirthDate().plusDays(345)); - - Assert.assertEquals(form.nameField.getValue(), person.getFirstName()); - Assert.assertEquals(form.birthDateField.getValue(), - person.getBirthDate()); - } - - @Test - public void bindInstanceFields_bindNotBoundFieldsOnly_customBindingIsNotReplaced() { - BindAllFields form = new BindAllFields(); - BeanBinder binder = new BeanBinder<>(Person.class); - - TextField name = new TextField(); - form.firstName = name; - binder.forField(form.firstName) - .withValidator( - new StringLengthValidator("Name is invalid", 3, 10)) - .bind("firstName"); - - binder.bindInstanceFields(form); - - Person person = new Person(); - String personName = "foo"; - person.setFirstName(personName); - person.setBirthDate(LocalDate.now()); - - binder.setBean(person); - - Assert.assertEquals(person.getFirstName(), form.firstName.getValue()); - Assert.assertEquals(person.getBirthDate(), form.birthDate.getValue()); - // the instance is not overridden - Assert.assertEquals(name, form.firstName); - - form.firstName.setValue("aa"); - form.birthDate.setValue(person.getBirthDate().plusDays(345)); - - Assert.assertEquals(personName, person.getFirstName()); - Assert.assertEquals(form.birthDate.getValue(), person.getBirthDate()); - - Assert.assertFalse(binder.validate().isOk()); - } - - @Test - public void bindInstanceFields_fieldsAreConfigured_customBindingIsNotReplaced() { - BindOnlyOneField form = new BindOnlyOneField(); - BeanBinder binder = new BeanBinder<>(Person.class); - - TextField name = new TextField(); - form.firstName = name; - binder.forField(form.firstName) - .withValidator( - new StringLengthValidator("Name is invalid", 3, 10)) - .bind("firstName"); - TextField ageField = new TextField(); - form.noFieldInPerson = ageField; - binder.forField(form.noFieldInPerson) - .withConverter(new StringToIntegerConverter("")) - .bind(Person::getAge, Person::setAge); - - binder.bindInstanceFields(form); - - Person person = new Person(); - String personName = "foo"; - int age = 11; - person.setFirstName(personName); - person.setAge(age); - - binder.setBean(person); - - Assert.assertEquals(person.getFirstName(), form.firstName.getValue()); - Assert.assertEquals(String.valueOf(person.getAge()), - form.noFieldInPerson.getValue()); - // the instances are not overridden - Assert.assertEquals(name, form.firstName); - Assert.assertEquals(ageField, form.noFieldInPerson); - - form.firstName.setValue("aa"); - age += 56; - form.noFieldInPerson.setValue(String.valueOf(age)); - - Assert.assertEquals(personName, person.getFirstName()); - Assert.assertEquals(form.noFieldInPerson.getValue(), - String.valueOf(person.getAge())); - - Assert.assertFalse(binder.validate().isOk()); - } -} diff --git a/server/src/test/java/com/vaadin/data/BeanBinderPropertySetTest.java b/server/src/test/java/com/vaadin/data/BeanBinderPropertySetTest.java new file mode 100644 index 0000000000..d11541fb0c --- /dev/null +++ b/server/src/test/java/com/vaadin/data/BeanBinderPropertySetTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.data; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.data.provider.bov.Person; + +public class BeanBinderPropertySetTest { + @Test + public void testSerializeDeserialize() throws Exception { + BinderPropertyDefinition definition = BeanBinderPropertySet + .get(Person.class).getProperty("born") + .orElseThrow(RuntimeException::new); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(bos); + out.writeObject(definition); + out.flush(); + + ObjectInputStream inputStream = new ObjectInputStream( + new ByteArrayInputStream(bos.toByteArray())); + + BinderPropertyDefinition deserializedDefinition = (BinderPropertyDefinition) inputStream + .readObject(); + + ValueProvider getter = deserializedDefinition.getGetter(); + Person person = new Person("Milennial", 2000); + Integer age = (Integer) getter.apply(person); + + Assert.assertEquals(Integer.valueOf(2000), age); + } +} diff --git a/server/src/test/java/com/vaadin/data/BeanBinderTest.java b/server/src/test/java/com/vaadin/data/BeanBinderTest.java index 3433aee1a8..6bd53044b7 100644 --- a/server/src/test/java/com/vaadin/data/BeanBinderTest.java +++ b/server/src/test/java/com/vaadin/data/BeanBinderTest.java @@ -3,23 +3,19 @@ package com.vaadin.data; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; -import java.lang.reflect.Method; import java.util.List; import java.util.Set; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import com.vaadin.data.BeanBinder.BeanBindingBuilder; -import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.data.converter.StringToIntegerConverter; import com.vaadin.tests.data.bean.BeanToValidate; import com.vaadin.ui.CheckBoxGroup; import com.vaadin.ui.TextField; public class BeanBinderTest - extends BinderTestBase, BeanToValidate> { + extends BinderTestBase, BeanToValidate> { private enum TestEnum { } @@ -52,7 +48,7 @@ public class BeanBinderTest @Before public void setUp() { - binder = new BeanBinder<>(BeanToValidate.class); + binder = new Binder<>(BeanToValidate.class); item = new BeanToValidate(); item.setFirstname("Johannes"); item.setAge(32); @@ -60,11 +56,10 @@ public class BeanBinderTest @Test public void bindInstanceFields_parameters_type_erased() { - BeanBinder otherBinder = new BeanBinder<>(TestBean.class); + Binder otherBinder = new Binder<>(TestBean.class); TestClass testClass = new TestClass(); otherBinder.forField(testClass.number) - .withConverter(new StringToIntegerConverter("")) - .bind("number"); + .withConverter(new StringToIntegerConverter("")).bind("number"); // Should correctly bind the enum field without throwing otherBinder.bindInstanceFields(testClass); @@ -72,7 +67,7 @@ public class BeanBinderTest @Test public void bindInstanceFields_automatically_binds_incomplete_forMemberField_bindings() { - BeanBinder otherBinder = new BeanBinder<>(TestBean.class); + Binder otherBinder = new Binder<>(TestBean.class); TestClass testClass = new TestClass(); otherBinder.forMemberField(testClass.number) @@ -87,7 +82,7 @@ public class BeanBinderTest @Test(expected = IllegalStateException.class) public void bindInstanceFields_does_not_automatically_bind_incomplete_forField_bindings() { - BeanBinder otherBinder = new BeanBinder<>(TestBean.class); + Binder otherBinder = new Binder<>(TestBean.class); TestClass testClass = new TestClass(); otherBinder.forField(testClass.number) @@ -100,7 +95,7 @@ public class BeanBinderTest @Test(expected = IllegalStateException.class) public void incomplete_forMemberField_bindings() { - BeanBinder otherBinder = new BeanBinder<>(TestBean.class); + Binder otherBinder = new Binder<>(TestBean.class); TestClass testClass = new TestClass(); otherBinder.forMemberField(testClass.number) @@ -262,24 +257,4 @@ public class BeanBinderTest assertSame(field, errors.get(0).getField()); assertEquals(message, errors.get(0).getMessage().get()); } - - @Test - public void beanBindingChainingMethods() { - Method[] methods = BeanBindingBuilder.class.getMethods(); - for (int i = 0; i < methods.length; i++) { - Method method = methods[i]; - try { - Method actualMethod = BeanBindingBuilder.class.getMethod( - method.getName(), method.getParameterTypes()); - - Assert.assertNotSame( - actualMethod + " should be overridden in " - + BeanBindingBuilder.class - + " with more specific return type ", - BindingBuilder.class, actualMethod.getReturnType()); - } catch (NoSuchMethodException | SecurityException e) { - throw new RuntimeException(e); - } - } - } } diff --git a/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java b/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java index f1d226bf20..7d2e6bd304 100644 --- a/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java +++ b/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java @@ -461,7 +461,7 @@ public class BinderBookOfVaadinTest { @Test public void binder_saveIfValid() { - BeanBinder binder = new BeanBinder<>(BookPerson.class); + Binder binder = new Binder<>(BookPerson.class); // Phone or email has to be specified for the bean Validator phoneOrEmail = Validator.from( @@ -585,7 +585,7 @@ public class BinderBookOfVaadinTest { public void withBinderStatusLabelExample() { Label formStatusLabel = new Label(); - BeanBinder binder = new BeanBinder<>(BookPerson.class); + Binder binder = new Binder<>(BookPerson.class); binder.setStatusLabel(formStatusLabel); diff --git a/server/src/test/java/com/vaadin/data/BinderCustomPropertySetTest.java b/server/src/test/java/com/vaadin/data/BinderCustomPropertySetTest.java new file mode 100644 index 0000000000..3d85084bc6 --- /dev/null +++ b/server/src/test/java/com/vaadin/data/BinderCustomPropertySetTest.java @@ -0,0 +1,144 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.data; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Stream; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.data.Binder.BindingBuilder; +import com.vaadin.server.Setter; +import com.vaadin.ui.TextField; + +public class BinderCustomPropertySetTest { + public static class MapPropertyDefinition + implements BinderPropertyDefinition, String> { + + private MapPropertySet propertySet; + private String name; + + public MapPropertyDefinition(MapPropertySet propertySet, String name) { + this.propertySet = propertySet; + this.name = name; + } + + @Override + public ValueProvider, String> getGetter() { + return map -> map.get(name); + } + + @Override + public Optional, String>> getSetter() { + return Optional.of((map, value) -> { + if (value == null) { + map.remove(name); + } else { + map.put(name, value); + } + }); + } + + @Override + public Class getType() { + return String.class; + } + + @Override + public BindingBuilder, String> beforeBind( + BindingBuilder, String> originalBuilder) { + return originalBuilder; + } + + @Override + public String getName() { + return name; + } + + @Override + public BinderPropertySet> getPropertySet() { + return propertySet; + } + + } + + public static class MapPropertySet + implements BinderPropertySet> { + @Override + public Stream, ?>> getProperties() { + return Stream.of("one", "two", "three").map(this::createProperty); + } + + @Override + public Optional, ?>> getProperty( + String name) { + return Optional.of(createProperty(name)); + } + + private BinderPropertyDefinition, ?> createProperty( + String name) { + return new MapPropertyDefinition(this, name); + } + } + + public static class InstanceFields { + private TextField one; + private TextField another; + } + + @Test + public void testBindByString() { + TextField field = new TextField(); + Map map = new HashMap<>(); + Binder> binder = Binder + .withPropertySet(new MapPropertySet()); + + binder.bind(field, "key"); + binder.setBean(map); + + field.setValue("value"); + Assert.assertEquals( + "Field value should propagate to the corresponding key in the map", + "value", map.get("key")); + } + + @Test + public void testBindInstanceFields() { + Map map = new HashMap<>(); + Binder> binder = Binder + .withPropertySet(new MapPropertySet()); + InstanceFields instanceFields = new InstanceFields(); + + binder.bindInstanceFields(instanceFields); + + Assert.assertNotNull( + "Field corresponding to supported property name should be bound", + instanceFields.one); + Assert.assertNull( + "Field corresponding to unsupported property name should be ignored", + instanceFields.another); + + binder.setBean(map); + + instanceFields.one.setValue("value"); + Assert.assertEquals( + "Field value should propagate to the corresponding key in the map", + "value", map.get("one")); + } +} diff --git a/server/src/test/java/com/vaadin/data/BinderInstanceFieldTest.java b/server/src/test/java/com/vaadin/data/BinderInstanceFieldTest.java new file mode 100644 index 0000000000..de58be5e42 --- /dev/null +++ b/server/src/test/java/com/vaadin/data/BinderInstanceFieldTest.java @@ -0,0 +1,388 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.data; + +import java.time.LocalDate; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.annotations.PropertyId; +import com.vaadin.data.converter.StringToIntegerConverter; +import com.vaadin.data.validator.StringLengthValidator; +import com.vaadin.tests.data.bean.Person; +import com.vaadin.ui.AbstractField; +import com.vaadin.ui.AbstractTextField; +import com.vaadin.ui.DateField; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.TextField; + +public class BinderInstanceFieldTest { + + public static class BindAllFields extends FormLayout { + private TextField firstName; + private DateField birthDate; + } + + public static class BindFieldsUsingAnnotation extends FormLayout { + @PropertyId("firstName") + private TextField nameField; + + @PropertyId("birthDate") + private DateField birthDateField; + } + + public static class BindOnlyOneField extends FormLayout { + private TextField firstName; + private TextField noFieldInPerson; + } + + public static class BindNoHasValueField extends FormLayout { + private String firstName; + } + + public static class BindGenericField extends FormLayout { + private CustomField firstName; + } + + public static class BindGenericWrongTypeParameterField extends FormLayout { + private CustomField firstName; + } + + public static class BindWrongTypeParameterField extends FormLayout { + private IntegerTextField firstName; + } + + public static class BindGeneric extends FormLayout { + private CustomField firstName; + } + + public static class BindRaw extends FormLayout { + private CustomField firstName; + } + + public static class BindAbstract extends FormLayout { + private AbstractTextField firstName; + } + + public static class BindNonInstantiatableType extends FormLayout { + private NoDefaultCtor firstName; + } + + public static class BindComplextHierarchyGenericType extends FormLayout { + private ComplexHierarchy firstName; + } + + public static class NoDefaultCtor extends TextField { + public NoDefaultCtor(int arg) { + } + } + + public static class IntegerTextField extends CustomField { + + } + + public static class ComplexHierarchy extends Generic { + + } + + public static class Generic extends ComplexGeneric { + + } + + public static class ComplexGeneric extends CustomField { + + } + + public static class CustomField extends AbstractField { + + private T value; + + @Override + public T getValue() { + return value; + } + + @Override + protected void doSetValue(T value) { + this.value = value; + } + + } + + @Test + public void bindInstanceFields_bindAllFields() { + BindAllFields form = new BindAllFields(); + Binder binder = new Binder<>(Person.class); + binder.bindInstanceFields(form); + + Person person = new Person(); + person.setFirstName("foo"); + person.setBirthDate(LocalDate.now()); + + binder.setBean(person); + + Assert.assertEquals(person.getFirstName(), form.firstName.getValue()); + Assert.assertEquals(person.getBirthDate(), form.birthDate.getValue()); + + form.firstName.setValue("bar"); + form.birthDate.setValue(person.getBirthDate().plusDays(345)); + + Assert.assertEquals(form.firstName.getValue(), person.getFirstName()); + Assert.assertEquals(form.birthDate.getValue(), person.getBirthDate()); + } + + @Test(expected = IllegalStateException.class) + public void bind_instanceFields_noArgsConstructor() { + BindAllFields form = new BindAllFields(); + Binder binder = new Binder<>(); + binder.bindInstanceFields(form); + } + + @Test + public void bindInstanceFields_bindOnlyOneFields() { + BindOnlyOneField form = new BindOnlyOneField(); + Binder binder = new Binder<>(Person.class); + binder.bindInstanceFields(form); + + Person person = new Person(); + person.setFirstName("foo"); + + binder.setBean(person); + + Assert.assertEquals(person.getFirstName(), form.firstName.getValue()); + + Assert.assertNull(form.noFieldInPerson); + + form.firstName.setValue("bar"); + + Assert.assertEquals(form.firstName.getValue(), person.getFirstName()); + } + + @Test + public void bindInstanceFields_bindNotHasValueField_fieldIsNull() { + BindNoHasValueField form = new BindNoHasValueField(); + Binder binder = new Binder<>(Person.class); + binder.bindInstanceFields(form); + + Person person = new Person(); + person.setFirstName("foo"); + + binder.setBean(person); + + Assert.assertNull(form.firstName); + } + + @Test + public void bindInstanceFields_genericField() { + BindGenericField form = new BindGenericField(); + Binder binder = new Binder<>(Person.class); + binder.bindInstanceFields(form); + + Person person = new Person(); + person.setFirstName("foo"); + + binder.setBean(person); + + Assert.assertEquals(person.getFirstName(), form.firstName.getValue()); + + form.firstName.setValue("bar"); + + Assert.assertEquals(form.firstName.getValue(), person.getFirstName()); + } + + @Test(expected = IllegalStateException.class) + public void bindInstanceFields_genericFieldWithWrongTypeParameter() { + BindGenericWrongTypeParameterField form = new BindGenericWrongTypeParameterField(); + Binder binder = new Binder<>(Person.class); + binder.bindInstanceFields(form); + } + + @Test(expected = IllegalStateException.class) + public void bindInstanceFields_generic() { + BindGeneric form = new BindGeneric<>(); + Binder binder = new Binder<>(Person.class); + binder.bindInstanceFields(form); + } + + @Test(expected = IllegalStateException.class) + public void bindInstanceFields_rawFieldType() { + BindRaw form = new BindRaw(); + Binder binder = new Binder<>(Person.class); + binder.bindInstanceFields(form); + } + + @Test(expected = IllegalStateException.class) + public void bindInstanceFields_abstractFieldType() { + BindAbstract form = new BindAbstract(); + Binder binder = new Binder<>(Person.class); + binder.bindInstanceFields(form); + } + + @Test(expected = IllegalStateException.class) + public void bindInstanceFields_noInstantiatableFieldType() { + BindNonInstantiatableType form = new BindNonInstantiatableType(); + Binder binder = new Binder<>(Person.class); + binder.bindInstanceFields(form); + } + + @Test(expected = IllegalStateException.class) + public void bindInstanceFields_wrongFieldType() { + BindWrongTypeParameterField form = new BindWrongTypeParameterField(); + Binder binder = new Binder<>(Person.class); + binder.bindInstanceFields(form); + } + + @Test + public void bindInstanceFields_complexGenericHierarchy() { + BindComplextHierarchyGenericType form = new BindComplextHierarchyGenericType(); + Binder binder = new Binder<>(Person.class); + binder.bindInstanceFields(form); + + Person person = new Person(); + person.setFirstName("foo"); + + binder.setBean(person); + + Assert.assertEquals(person.getFirstName(), form.firstName.getValue()); + + form.firstName.setValue("bar"); + + Assert.assertEquals(form.firstName.getValue(), person.getFirstName()); + } + + @Test + public void bindInstanceFields_bindNotHasValueField_fieldIsNotReplaced() { + BindNoHasValueField form = new BindNoHasValueField(); + Binder binder = new Binder<>(Person.class); + + String name = "foo"; + form.firstName = name; + + binder.bindInstanceFields(form); + + Person person = new Person(); + person.setFirstName("foo"); + + binder.setBean(person); + + Assert.assertEquals(name, form.firstName); + } + + @Test + public void bindInstanceFields_bindAllFieldsUsingAnnotations() { + BindFieldsUsingAnnotation form = new BindFieldsUsingAnnotation(); + Binder binder = new Binder<>(Person.class); + binder.bindInstanceFields(form); + + Person person = new Person(); + person.setFirstName("foo"); + person.setBirthDate(LocalDate.now()); + + binder.setBean(person); + + Assert.assertEquals(person.getFirstName(), form.nameField.getValue()); + Assert.assertEquals(person.getBirthDate(), + form.birthDateField.getValue()); + + form.nameField.setValue("bar"); + form.birthDateField.setValue(person.getBirthDate().plusDays(345)); + + Assert.assertEquals(form.nameField.getValue(), person.getFirstName()); + Assert.assertEquals(form.birthDateField.getValue(), + person.getBirthDate()); + } + + @Test + public void bindInstanceFields_bindNotBoundFieldsOnly_customBindingIsNotReplaced() { + BindAllFields form = new BindAllFields(); + Binder binder = new Binder<>(Person.class); + + TextField name = new TextField(); + form.firstName = name; + binder.forField(form.firstName) + .withValidator( + new StringLengthValidator("Name is invalid", 3, 10)) + .bind("firstName"); + + binder.bindInstanceFields(form); + + Person person = new Person(); + String personName = "foo"; + person.setFirstName(personName); + person.setBirthDate(LocalDate.now()); + + binder.setBean(person); + + Assert.assertEquals(person.getFirstName(), form.firstName.getValue()); + Assert.assertEquals(person.getBirthDate(), form.birthDate.getValue()); + // the instance is not overridden + Assert.assertEquals(name, form.firstName); + + form.firstName.setValue("aa"); + form.birthDate.setValue(person.getBirthDate().plusDays(345)); + + Assert.assertEquals(personName, person.getFirstName()); + Assert.assertEquals(form.birthDate.getValue(), person.getBirthDate()); + + Assert.assertFalse(binder.validate().isOk()); + } + + @Test + public void bindInstanceFields_fieldsAreConfigured_customBindingIsNotReplaced() { + BindOnlyOneField form = new BindOnlyOneField(); + Binder binder = new Binder<>(Person.class); + + TextField name = new TextField(); + form.firstName = name; + binder.forField(form.firstName) + .withValidator( + new StringLengthValidator("Name is invalid", 3, 10)) + .bind("firstName"); + TextField ageField = new TextField(); + form.noFieldInPerson = ageField; + binder.forField(form.noFieldInPerson) + .withConverter(new StringToIntegerConverter("")) + .bind(Person::getAge, Person::setAge); + + binder.bindInstanceFields(form); + + Person person = new Person(); + String personName = "foo"; + int age = 11; + person.setFirstName(personName); + person.setAge(age); + + binder.setBean(person); + + Assert.assertEquals(person.getFirstName(), form.firstName.getValue()); + Assert.assertEquals(String.valueOf(person.getAge()), + form.noFieldInPerson.getValue()); + // the instances are not overridden + Assert.assertEquals(name, form.firstName); + Assert.assertEquals(ageField, form.noFieldInPerson); + + form.firstName.setValue("aa"); + age += 56; + form.noFieldInPerson.setValue(String.valueOf(age)); + + Assert.assertEquals(personName, person.getFirstName()); + Assert.assertEquals(form.noFieldInPerson.getValue(), + String.valueOf(person.getAge())); + + Assert.assertFalse(binder.validate().isOk()); + } +} diff --git a/server/src/test/java/com/vaadin/data/BinderTest.java b/server/src/test/java/com/vaadin/data/BinderTest.java index 6fe139b7ad..1994821db0 100644 --- a/server/src/test/java/com/vaadin/data/BinderTest.java +++ b/server/src/test/java/com/vaadin/data/BinderTest.java @@ -285,7 +285,7 @@ public class BinderTest extends BinderTestBase, Person> { @Test public void beanBinder_nullRepresentationIsNotDisabled() { - BeanBinder binder = new BeanBinder<>(Person.class); + Binder binder = new Binder<>(Person.class); binder.forField(nameField).bind("firstName"); Person person = new Person(); @@ -297,7 +297,7 @@ public class BinderTest extends BinderTestBase, Person> { @Test public void beanBinder_withConverter_nullRepresentationIsNotDisabled() { String customNullPointerRepresentation = "foo"; - BeanBinder binder = new BeanBinder<>(Person.class); + Binder binder = new Binder<>(Person.class); binder.forField(nameField) .withConverter(value -> value, value -> value == null ? customNullPointerRepresentation : value) @@ -426,4 +426,9 @@ public class BinderTest extends BinderTestBase, Person> { firstNameField.setValue(""); Assert.assertEquals(6, invokes.get()); } + + @Test(expected = IllegalStateException.class) + public void noArgsConstructor_stringBind_throws() { + binder.bind(new TextField(), "firstName"); + } } \ No newline at end of file diff --git a/server/src/test/java/com/vaadin/data/Jsr303Test.java b/server/src/test/java/com/vaadin/data/Jsr303Test.java index 016018a6b3..43b03feb97 100644 --- a/server/src/test/java/com/vaadin/data/Jsr303Test.java +++ b/server/src/test/java/com/vaadin/data/Jsr303Test.java @@ -84,8 +84,7 @@ public class Jsr303Test { public void execute() { Assert.assertFalse(BeanUtil.checkBeanValidationAvailable()); - BeanBinder binder = new BeanBinder<>( - BeanToValidate.class); + Binder binder = new Binder<>(BeanToValidate.class); BeanToValidate item = new BeanToValidate(); String name = "Johannes"; item.setFirstname(name); -- cgit v1.2.3