package org.robobinding.viewattribute.property;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.robobinding.attribute.Attributes.aValueModelAttribute;
import static org.robobinding.viewattribute.MockBindingContextBuilder.aBindingContextWithProperty;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.robobinding.BindingContext;
import org.robobinding.attribute.ValueModelAttribute;
import org.robobinding.property.AbstractValueModel;
import org.robobinding.property.ValueModel;
import org.robobinding.util.RandomValues;
import org.robobinding.viewattribute.ValueModelUtils;
import org.robobinding.widgetaddon.ViewAddOn;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import android.view.View;
/**
*
* @since 1.0
* @version $Revision: 1.0 $
* @author Cheng Wei
*/
@Config(manifest=Config.NONE)
@RunWith(RobolectricTestRunner.class)
public class TwoWayBindingPropertyTest {
private static final String PROPERTY_NAME = "property2";
private View view;
private ViewAddOn viewAddOn;
private TwoWayPropertyViewAttributeSpy viewAttributeSpy;
@Before
public void setUp() {
view = Mockito.mock(View.class);
viewAddOn = Mockito.mock(ViewAddOn.class);
viewAttributeSpy = new TwoWayPropertyViewAttributeSpy();
}
@Test
public void givenABoundProperty_whenUpdateValueModel_thenViewIsSynchronized() {
ValueModel<Integer> valueModel = ValueModelUtils.create(-1);
aBoundProperty(valueModel);
Integer newValue = RandomValues.anyInteger();
valueModel.setValue(newValue);
assertThat(viewAttributeSpy.viewValue, is(newValue));
}
private TwoWayBindingProperty aBoundProperty(ValueModel<Integer> valueModel) {
ValueModelAttribute attribute = aValueModelAttribute(PROPERTY_NAME);
TwoWayBindingProperty bindingProperty = new TwoWayBindingProperty(view, viewAddOn, viewAttributeSpy, attribute);
BindingContext bindingContext = aBindingContextWithProperty(PROPERTY_NAME, valueModel);
bindingProperty.performBind(bindingContext);
return bindingProperty;
}
@Test
public void givenABoundProperty_whenUpdateValueModel_thenShouldNotReceiveAReturnUpdateFromView() {
ValueModelSpy valueModel = new ValueModelSpy(0);
aBoundProperty(valueModel);
Integer newValue = RandomValues.anyInteger();
valueModel.setValue(newValue);
assertThat(valueModel.updateCount, is(1));
}
@Test
public void givenABoundProperty_whenTheViewIsUpdated_thenValueModelShouldBeUpdated() {
ValueModel<Integer> valueModel = ValueModelUtils.create(-1);
aBoundProperty(valueModel);
Integer newValue = RandomValues.anyInteger();
viewAttributeSpy.simulateViewUpdate(newValue);
assertThat(valueModel.getValue(), is(newValue));
}
@Test
public void givenABoundProperty_whenTheViewIsUpdated_thenViewShouldNotReceiveAFurtherUpdate() {
ValueModel<Integer> valueModel = ValueModelUtils.create(-1);
aBoundProperty(valueModel);
Integer newValue = RandomValues.anyInteger();
viewAttributeSpy.simulateViewUpdate(newValue);
assertThat(viewAttributeSpy.viewUpdateNotificationCount, is(0));
}
@Test
public void givenABoundProperty_whenValueModelIsUpdated_thenViewShouldReceiveOnlyASingleUpdate() {
ValueModel<Integer> valueModel = ValueModelUtils.create(-1);
aBoundProperty(valueModel);
Integer newValue = RandomValues.anyInteger();
valueModel.setValue(newValue);
assertThat(viewAttributeSpy.viewUpdateNotificationCount, is(1));
}
@Test
public void givenABoundPropertyOfAlwaysRestoringValue_whenTheViewIsUpdated_thenViewShouldReceiveAnUpdateWithRestoredValue() {
ValueModel<Integer> valueModel = new AlwaysRestoreValueModel();
aBoundProperty(valueModel);
Integer newValue = RandomValues.anyInteger();
viewAttributeSpy.simulateViewUpdate(newValue);
assertThat(viewAttributeSpy.viewUpdateNotificationCount, is(1));
assertThat(viewAttributeSpy.viewValue, is(AlwaysRestoreValueModel.ALWAYS_RESTORE_VALUE));
}
public static class AlwaysRestoreValueModel extends AbstractValueModel<Integer> {
private static final int ALWAYS_RESTORE_VALUE = 888888888;
public AlwaysRestoreValueModel() {
super(ALWAYS_RESTORE_VALUE);
}
@Override
public void setValue(Integer newValue) {
super.setValue(newValue);
if (newValue != ALWAYS_RESTORE_VALUE) {
this.value = ALWAYS_RESTORE_VALUE;
fireValueChange();
}
}
}
public static class ValueModelSpy extends AbstractValueModel<Integer> {
int updateCount;
public ValueModelSpy(int value) {
super(value);
updateCount = 0;
}
@Override
public void setValue(Integer newValue) {
updateCount++;
super.setValue(newValue);
}
}
}