/* * 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.concurrent.atomic.AtomicReference; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import com.vaadin.data.Binder.Binding; import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.data.converter.StringToIntegerConverter; import com.vaadin.tests.data.bean.Person; /** * @author Vaadin Ltd * */ public class BinderStatusChangeTest extends BinderTestBase<Binder<Person>, Person> { private AtomicReference<StatusChangeEvent> event; @Before public void setUp() { binder = new Binder<>(); item = new Person(); event = new AtomicReference<>(); } @Test public void bindBinding_unbound_eventWhenBoundEndnoEventsBeforeBound() { binder.addStatusChangeListener(this::statusChanged); BindingBuilder<Person, String> binding = binder.forField(nameField); nameField.setValue(""); Assert.assertNull(event.get()); binding.bind(Person::getFirstName, Person::setFirstName); verifyEvent(); } @Test public void bindBinder_unbound_singleEventWhenBound() { binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.setBean(item); verifyEvent(); } @Test public void removeBean_bound_singleEventWhenUnBound() { binder.setBean(item); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.removeBean(); verifyEvent(); } @Test public void removeBean_unbound_noEventWhenUnBound() { binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.removeBean(); Assert.assertNull(event.get()); } @Test public void setValue_bound_singleEventOnSetValue() { binder.forField(nameField).bind(Person::getFirstName, Person::setFirstName); binder.setBean(item); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); nameField.setValue("foo"); verifyEvent(); } @Test public void setValue_severalBoundFieldsAndBoundBinder_singleEventOnSetValue() { binder.forField(nameField).bind(Person::getFirstName, Person::setFirstName); binder.forField(ageField) .withConverter(new StringToIntegerConverter("")) .bind(Person::getAge, Person::setAge); binder.setBean(item); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); nameField.setValue("foo"); verifyEvent(); } @Test public void setInvalidValue_bound_singleEventOnSetValue() { binder.forField(nameField).withValidator(name -> false, "") .bind(Person::getFirstName, Person::setFirstName); binder.setBean(item); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); nameField.setValue("foo"); verifyEvent(true); } @Test public void setInvalidBean_bound_singleEventOnSetValue() { binder.forField(nameField).bind(Person::getFirstName, Person::setFirstName); binder.setBean(item); binder.withValidator(Validator.from(bean -> false, "")); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); nameField.setValue("foo"); verifyEvent(true); } @Test public void readBean_hasBindings_singleEventOnLoad() { binder.forField(nameField).bind(Person::getFirstName, Person::setFirstName); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.readBean(item); verifyEvent(); } @Test public void readBean_hasSeveralBindings_singleEventOnLoad() { binder.forField(nameField).bind(Person::getFirstName, Person::setFirstName); binder.forField(ageField) .withConverter(new StringToIntegerConverter("")) .bind(Person::getAge, Person::setAge); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.readBean(item); verifyEvent(); } @Test public void readBean_hasNoBindings_singleEvent() { binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.readBean(item); verifyEvent(); } @Test public void writeBean_hasNoBindings_singleEvent() throws ValidationException { binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.writeBean(item); verifyEvent(); } @Test public void writeBeanIfValid_hasNoBindings_singleEvent() { binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.writeBeanIfValid(item); verifyEvent(); } @Test public void writeBean_hasBindings_singleEvent() throws ValidationException { binder.forField(nameField).bind(Person::getFirstName, Person::setFirstName); binder.readBean(item); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.writeBean(item); verifyEvent(); } @Test public void writeBean_hasSeveralBindings_singleEvent() throws ValidationException { binder.forField(nameField).bind(Person::getFirstName, Person::setFirstName); binder.forField(ageField) .withConverter(new StringToIntegerConverter("")) .bind(Person::getAge, Person::setAge); binder.readBean(item); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.writeBean(item); verifyEvent(); } @Test public void writeBeanIfValid_hasBindings_singleEvent() { binder.forField(nameField).bind(Person::getFirstName, Person::setFirstName); binder.readBean(item); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.writeBeanIfValid(item); verifyEvent(); } @Test public void writeBeanIfValid_hasSeveralBindings_singleEvent() { binder.forField(nameField).bind(Person::getFirstName, Person::setFirstName); binder.forField(ageField) .withConverter(new StringToIntegerConverter("")) .bind(Person::getAge, Person::setAge); binder.readBean(item); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.writeBeanIfValid(item); verifyEvent(); } @Test public void writeBeanInvalidValue_hasBindings_singleEvent() { binder.forField(nameField).withValidator(name -> false, "") .bind(Person::getFirstName, Person::setFirstName); binder.readBean(item); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); try { binder.writeBean(item); } catch (ValidationException ignore) { } verifyEvent(true); } @Test public void writeBeanIfValid_invalidValueAndBinderHasBindings_singleEvent() { binder.forField(nameField).withValidator(name -> false, "") .bind(Person::getFirstName, Person::setFirstName); binder.readBean(item); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.writeBeanIfValid(item); verifyEvent(true); } @Test public void writeBeanIfValid_invalidValueAndBinderHasSeveralBindings_singleEvent() { binder.forField(nameField).withValidator(name -> false, "") .bind(Person::getFirstName, Person::setFirstName); binder.forField(ageField) .withConverter(new StringToIntegerConverter("")) .bind(Person::getAge, Person::setAge); binder.readBean(item); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.writeBeanIfValid(item); verifyEvent(true); } @Test public void writeBeanInvalidBean_hasBindings_singleEvent() { binder.forField(nameField).bind(Person::getFirstName, Person::setFirstName); binder.readBean(item); binder.withValidator(Validator.from(person -> false, "")); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); try { binder.writeBean(item); } catch (ValidationException ignore) { } verifyEvent(true); } @Test public void writeBeanIfValid_invalidBeanAndBinderHasBindings_singleEvent() { binder.forField(nameField).bind(Person::getFirstName, Person::setFirstName); binder.readBean(item); binder.withValidator(Validator.from(person -> false, "")); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.writeBeanIfValid(item); verifyEvent(true); } @Test public void writeValidBean_hasBindings_singleEvent() throws ValidationException { binder.forField(nameField).bind(Person::getFirstName, Person::setFirstName); binder.readBean(item); binder.withValidator(Validator.from(person -> true, "")); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.writeBean(item); verifyEvent(); } @Test public void writeBeanIfValid_validBeanAndBinderHasBindings_singleEvent() { binder.forField(nameField).bind(Person::getFirstName, Person::setFirstName); binder.readBean(item); binder.withValidator(Validator.from(person -> true, "")); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.writeBeanIfValid(item); verifyEvent(); } @Test public void validateBinder_noValidationErrors_statusEventWithoutErrors() { binder.forField(nameField).bind(Person::getFirstName, Person::setFirstName); binder.forField(ageField) .withConverter(new StringToIntegerConverter("")) .bind(Person::getAge, Person::setAge); binder.setBean(item); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.validate(); verifyEvent(); } @Test public void validateBinder_validationErrors_statusEventWithError() { binder.forField(nameField).withValidator(name -> false, "") .bind(Person::getFirstName, Person::setFirstName); binder.forField(ageField) .withConverter(new StringToIntegerConverter("")) .bind(Person::getAge, Person::setAge); binder.setBean(item); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binder.validate(); verifyEvent(true); } @Test public void validateBinding_noValidationErrors_statusEventWithoutErrors() { Binding<Person, String> binding = binder.forField(nameField) .bind(Person::getFirstName, Person::setFirstName); binder.forField(ageField) .withConverter(new StringToIntegerConverter("")) .bind(Person::getAge, Person::setAge); binder.setBean(item); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binding.validate(); verifyEvent(); } @Test public void validateBinding_validationErrors_statusEventWithError() { Binding<Person, String> binding = binder.forField(nameField) .withValidator(name -> false, "") .bind(Person::getFirstName, Person::setFirstName); binder.forField(ageField) .withConverter(new StringToIntegerConverter("")) .bind(Person::getAge, Person::setAge); binder.setBean(item); binder.addStatusChangeListener(this::statusChanged); Assert.assertNull(event.get()); binding.validate(); verifyEvent(true); } private void verifyEvent() { verifyEvent(false); } private void verifyEvent(boolean validationErrors) { StatusChangeEvent statusChangeEvent = event.get(); Assert.assertNotNull(statusChangeEvent); Assert.assertEquals(binder, statusChangeEvent.getBinder()); Assert.assertEquals(binder, statusChangeEvent.getSource()); Assert.assertEquals(validationErrors, statusChangeEvent.hasValidationErrors()); } private void statusChanged(StatusChangeEvent evt) { Assert.assertNull(event.get()); event.set(evt); } }