package com.vaadin.v7.tests.server.component.textfield; import java.util.HashMap; import java.util.Map; import org.easymock.EasyMock; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import com.vaadin.v7.data.Property.ValueChangeEvent; import com.vaadin.v7.data.util.ObjectProperty; import com.vaadin.v7.tests.server.component.abstractfield.AbstractFieldValueChangeTestBase; import com.vaadin.v7.ui.AbstractField; import com.vaadin.v7.ui.TextField; /** * Check that the value change listener for a text field is triggered exactly * once when setting the value, at the correct time. * * See <a href="http://dev.vaadin.com/ticket/4394">Ticket 4394</a>. */ public class TextFieldValueChangeTest extends AbstractFieldValueChangeTestBase<String> { @Before public void setUp() { super.setUp(new TextField()); } /** * Case where the text field only uses its internal buffer, no external * property data source. */ @Test public void testNoDataSource() { getField().setPropertyDataSource(null); expectValueChangeFromSetValueNotCommit(); } @Override protected void setValue(AbstractField<String> field) { Map<String, Object> variables = new HashMap<String, Object>(); variables.put("text", "newValue"); ((TextField) field).changeVariables(field, variables); } /** * Test that field propagates value change events originating from property, * but don't fire value change events twice if value has only changed once. * * * TODO make test field type agnostic (eg. combobox) */ @Test public void testValueChangeEventPropagationWithReadThrough() { ObjectProperty<String> property = new ObjectProperty<String>(""); getField().setPropertyDataSource(property); // defaults, buffering off getField().setBuffered(false); // Expectations and start test getListener().valueChange(EasyMock.isA(ValueChangeEvent.class)); EasyMock.replay(getListener()); // Add listener and set the value -> should end up in listener once getField().addListener(getListener()); property.setValue("Foo"); // Ensure listener was called once EasyMock.verify(getListener()); // get value should not fire value change again Object value = getField().getValue(); Assert.assertEquals("Foo", value); // Ensure listener still has been called only once EasyMock.verify(getListener()); } /** * Value change events from property should not propagate if read through is * false. Execpt when the property is being set. * * TODO make test field type agnostic (eg. combobox) */ @Test public void testValueChangePropagationWithReadThroughOff() { final String initialValue = "initial"; ObjectProperty<String> property = new ObjectProperty<String>( initialValue); // set buffering getField().setBuffered(true); // Value change should only happen once, when setting the property, // further changes via property should not cause value change listener // in field to be notified getListener().valueChange(EasyMock.isA(ValueChangeEvent.class)); EasyMock.replay(getListener()); getField().addListener(getListener()); getField().setPropertyDataSource(property); // Ensure listener was called once EasyMock.verify(getListener()); // modify property value, should not fire value change in field as the // read buffering is on (read through == false) property.setValue("Foo"); // Ensure listener still has been called only once EasyMock.verify(getListener()); // get value should not fire value change again Object value = getField().getValue(); // field value should be different from the original value and current // proeprty value boolean isValueEqualToInitial = value.equals(initialValue); Assert.assertTrue(isValueEqualToInitial); // Ensure listener still has been called only once EasyMock.verify(getListener()); } }