< prev index next >
modules/base/src/test/java/com/sun/javafx/binding/BidirectionalBindingTest.java
Print this page
rev 9213 : 8089557: bindBidirection works for ReadOnly*Wrapper incorrectly
@@ -23,205 +23,213 @@
* questions.
*/
package com.sun.javafx.binding;
-import javafx.beans.InvalidationListener;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
-import javafx.beans.value.ChangeListener;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection;
+import javafx.beans.value.ObservableValue;
import static org.junit.Assert.*;
-import org.junit.Rule;
-import org.junit.rules.ExpectedException;
@RunWith(Parameterized.class)
public class BidirectionalBindingTest<T> {
- private static final float EPSILON_FLOAT = 1e-5f;
- private static final double EPSILON_DOUBLE = 1e-10;
+ @FunctionalInterface
+ public static interface PropertyFactory<T> {
+ Property<T> createProperty();
+ }
+
+ public static class Factory<T> {
- public static interface Functions<S> {
- PropertyMock<S> create();
- void bind(PropertyMock<S> obj1, PropertyMock<S> obj2);
- void unbind(PropertyMock<S> obj1, PropertyMock<S> obj2);
- BidirectionalBinding createBindingDirectly(PropertyMock<S> op1, PropertyMock<S> op2);
- void check(S expected, S actual);
- }
-
- private final Functions<T> func;
- private final T[] v;
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- private PropertyMock<T> op1;
- private PropertyMock<T> op2;
- private PropertyMock<T> op3;
- private PropertyMock<T> op4;
-
- public BidirectionalBindingTest(Functions<T> func, T[] v) {
- this.op1 = func.create();
- this.op2 = func.create();
- this.op3 = func.create();
- this.op4 = func.create();
- this.func = func;
- this.v = v;
+ private PropertyFactory<T> propertyFactory;
+ private T[] values;
+ public Factory(PropertyFactory<T> propertyFactory, T[] values) {
+ this.propertyFactory = propertyFactory;
+ this.values = values;
+ }
+ public Property<T> createProperty() {
+ return propertyFactory.createProperty();
+ }
+ public T[] getValues() {
+ return values;
+ }
+ }
+
+ private Factory<T> factory;
+ private Property<T> op1;
+ private Property<T> op2;
+ private Property<T> op3;
+ private Property<T> op4;
+ private T[] v;
+
+ public BidirectionalBindingTest(Factory<T> factory) {
+ this.factory = factory;
}
@Before
public void setUp() {
+ op1 = factory.createProperty();
+ op2 = factory.createProperty();
+ op3 = factory.createProperty();
+ op4 = factory.createProperty();
+ v = factory.getValues();
op1.setValue(v[0]);
op2.setValue(v[1]);
}
@Test
public void testBind() {
- func.bind(op1, op2);
+ Bindings.bindBidirectional(op1, op2);
+ Bindings.bindBidirectional(op1, op2);
System.gc(); // making sure we did not not overdo weak references
- func.check(v[1], op1.getValue());
- func.check(v[1], op2.getValue());
+ assertEquals(v[1], op1.getValue());
+ assertEquals(v[1], op2.getValue());
op1.setValue(v[2]);
- func.check(v[2], op1.getValue());
- func.check(v[2], op2.getValue());
+ assertEquals(v[2], op1.getValue());
+ assertEquals(v[2], op2.getValue());
op2.setValue(v[3]);
- func.check(v[3], op1.getValue());
- func.check(v[3], op2.getValue());
+ assertEquals(v[3], op1.getValue());
+ assertEquals(v[3], op2.getValue());
}
@Test
public void testUnbind() {
// unbind non-existing binding => no-op
- func.unbind(op1, op2);
+ Bindings.unbindBidirectional(op1, op2);
// unbind properties of different beans
- func.bind(op1, op2);
+ Bindings.bindBidirectional(op1, op2);
System.gc(); // making sure we did not not overdo weak references
- func.check(v[1], op1.getValue());
- func.check(v[1], op2.getValue());
+ assertEquals(v[1], op1.getValue());
+ assertEquals(v[1], op2.getValue());
- func.unbind(op1, op2);
+ Bindings.unbindBidirectional(op1, op2);
System.gc();
- func.check(v[1], op1.getValue());
- func.check(v[1], op2.getValue());
+ assertEquals(v[1], op1.getValue());
+ assertEquals(v[1], op2.getValue());
op1.setValue(v[2]);
- func.check(v[2], op1.getValue());
- func.check(v[1], op2.getValue());
+ assertEquals(v[2], op1.getValue());
+ assertEquals(v[1], op2.getValue());
op2.setValue(v[3]);
- func.check(v[2], op1.getValue());
- func.check(v[3], op2.getValue());
+ assertEquals(v[2], op1.getValue());
+ assertEquals(v[3], op2.getValue());
}
@Test
public void testChaining() {
op3.setValue(v[2]);
- func.bind(op1, op2);
- func.bind(op2, op3);
+ Bindings.bindBidirectional(op1, op2);
+ Bindings.bindBidirectional(op2, op3);
System.gc(); // making sure we did not not overdo weak references
- func.check(v[2], op1.getValue());
- func.check(v[2], op2.getValue());
- func.check(v[2], op3.getValue());
+ assertEquals(v[2], op1.getValue());
+ assertEquals(v[2], op2.getValue());
+ assertEquals(v[2], op3.getValue());
op1.setValue(v[3]);
- func.check(v[3], op1.getValue());
- func.check(v[3], op2.getValue());
- func.check(v[3], op3.getValue());
+ assertEquals(v[3], op1.getValue());
+ assertEquals(v[3], op2.getValue());
+ assertEquals(v[3], op3.getValue());
op2.setValue(v[0]);
- func.check(v[0], op1.getValue());
- func.check(v[0], op2.getValue());
- func.check(v[0], op3.getValue());
+ assertEquals(v[0], op1.getValue());
+ assertEquals(v[0], op2.getValue());
+ assertEquals(v[0], op3.getValue());
op3.setValue(v[1]);
- func.check(v[1], op1.getValue());
- func.check(v[1], op2.getValue());
- func.check(v[1], op3.getValue());
+ assertEquals(v[1], op1.getValue());
+ assertEquals(v[1], op2.getValue());
+ assertEquals(v[1], op3.getValue());
// now unbind
- func.unbind(op1, op2);
+ Bindings.unbindBidirectional(op1, op2);
System.gc(); // making sure we did not not overdo weak references
- func.check(v[1], op1.getValue());
- func.check(v[1], op2.getValue());
- func.check(v[1], op3.getValue());
+ assertEquals(v[1], op1.getValue());
+ assertEquals(v[1], op2.getValue());
+ assertEquals(v[1], op3.getValue());
op1.setValue(v[2]);
- func.check(v[2], op1.getValue());
- func.check(v[1], op2.getValue());
- func.check(v[1], op3.getValue());
+ assertEquals(v[2], op1.getValue());
+ assertEquals(v[1], op2.getValue());
+ assertEquals(v[1], op3.getValue());
op2.setValue(v[3]);
- func.check(v[2], op1.getValue());
- func.check(v[3], op2.getValue());
- func.check(v[3], op3.getValue());
+ assertEquals(v[2], op1.getValue());
+ assertEquals(v[3], op2.getValue());
+ assertEquals(v[3], op3.getValue());
op3.setValue(v[0]);
- func.check(v[2], op1.getValue());
- func.check(v[0], op2.getValue());
- func.check(v[0], op3.getValue());
+ assertEquals(v[2], op1.getValue());
+ assertEquals(v[0], op2.getValue());
+ assertEquals(v[0], op3.getValue());
+ }
+
+ private int getListenerCount(ObservableValue<T> v) {
+ return ExpressionHelperUtility.getChangeListeners(v).size();
}
@Test
public void testWeakReferencing() {
- func.bind(op1, op2);
- assertEquals(1, op1.getListenerCount());
- assertEquals(1, op2.getListenerCount());
+ Bindings.bindBidirectional(op1, op2);
+
+ assertEquals(1, getListenerCount(op1));
+ assertEquals(1, getListenerCount(op2));
op1 = null;
System.gc();
op2.setValue(v[2]);
- assertEquals(0, op2.getListenerCount());
+ assertEquals(0, getListenerCount(op2));
- func.bind(op2, op3);
- assertEquals(1, op2.getListenerCount());
- assertEquals(1, op3.getListenerCount());
+ Bindings.bindBidirectional(op2, op3);
+ assertEquals(1, getListenerCount(op2));
+ assertEquals(1, getListenerCount(op3));
op3 = null;
System.gc();
op2.setValue(v[0]);
- assertEquals(0, op2.getListenerCount());
+ assertEquals(0, getListenerCount(op2));
}
@Test
public void testHashCode() {
- final int hc1 = func.createBindingDirectly(op1, op2).hashCode();
- final int hc2 = func.createBindingDirectly(op2, op1).hashCode();
+ final int hc1 = BidirectionalBinding.bind(op1, op2).hashCode();
+ final int hc2 = BidirectionalBinding.bind(op2, op1).hashCode();
assertEquals(hc1, hc2);
}
-
@Test
public void testEquals() {
- final BidirectionalBinding golden = func.createBindingDirectly(op1, op2);
+ final BidirectionalBinding golden = BidirectionalBinding.bind(op1, op2);
assertTrue(golden.equals(golden));
assertFalse(golden.equals(null));
assertFalse(golden.equals(op1));
- assertTrue(golden.equals(func.createBindingDirectly(op1, op2)));
- assertTrue(golden.equals(func.createBindingDirectly(op2, op1)));
- assertFalse(golden.equals(func.createBindingDirectly(op1, op3)));
- assertFalse(golden.equals(func.createBindingDirectly(op3, op1)));
- assertFalse(golden.equals(func.createBindingDirectly(op3, op2)));
- assertFalse(golden.equals(func.createBindingDirectly(op2, op3)));
+ assertTrue(golden.equals(BidirectionalBinding.bind(op1, op2)));
+ assertTrue(golden.equals(BidirectionalBinding.bind(op2, op1)));
+ assertFalse(golden.equals(BidirectionalBinding.bind(op1, op3)));
+ assertFalse(golden.equals(BidirectionalBinding.bind(op3, op1)));
+ assertFalse(golden.equals(BidirectionalBinding.bind(op3, op2)));
+ assertFalse(golden.equals(BidirectionalBinding.bind(op2, op3)));
}
@Test
public void testEqualsWithGCedProperty() {
- final BidirectionalBinding binding1 = func.createBindingDirectly(op1, op2);
- final BidirectionalBinding binding2 = func.createBindingDirectly(op1, op2);
- final BidirectionalBinding binding3 = func.createBindingDirectly(op2, op1);
- final BidirectionalBinding binding4 = func.createBindingDirectly(op2, op1);
+ final BidirectionalBinding binding1 = BidirectionalBinding.bind(op1, op2);
+ final BidirectionalBinding binding2 = BidirectionalBinding.bind(op1, op2);
+ final BidirectionalBinding binding3 = BidirectionalBinding.bind(op2, op1);
+ final BidirectionalBinding binding4 = BidirectionalBinding.bind(op2, op1);
op1 = null;
System.gc();
assertTrue(binding1.equals(binding1));
assertFalse(binding1.equals(binding2));
@@ -232,41 +240,41 @@
assertFalse(binding3.equals(binding4));
}
@Test(expected=NullPointerException.class)
public void testBind_Null_X() {
- func.bind(null, op2);
+ Bindings.bindBidirectional(null, op2);
}
@Test(expected=NullPointerException.class)
public void testBind_X_Null() {
- func.bind(op1, null);
+ Bindings.bindBidirectional(op1, null);
}
@Test(expected=IllegalArgumentException.class)
public void testBind_X_Self() {
- func.bind(op1, op1);
+ Bindings.bindBidirectional(op1, op1);
}
@Test(expected=NullPointerException.class)
public void testUnbind_Null_X() {
- func.unbind(null, op2);
+ Bindings.unbindBidirectional(null, op2);
}
@Test(expected=NullPointerException.class)
public void testUnbind_X_Null() {
- func.unbind(op1, null);
+ Bindings.unbindBidirectional(op1, null);
}
@Test(expected=IllegalArgumentException.class)
public void testUnbind_X_Self() {
- func.unbind(op1, op1);
+ Bindings.unbindBidirectional(op1, op1);
}
@Test
public void testBrokenBind() {
- func.bind(op1, op2);
+ Bindings.bindBidirectional(op1, op2);
op1.bind(op3);
assertEquals(op3.getValue(), op1.getValue());
assertEquals(op2.getValue(), op1.getValue());
op2.setValue(v[2]);
@@ -274,11 +282,11 @@
assertEquals(op2.getValue(), op1.getValue());
}
@Test
public void testDoubleBrokenBind() {
- func.bind(op1, op2);
+ Bindings.bindBidirectional(op1, op2);
op1.bind(op3);
op4.setValue(v[0]);
op2.bind(op4);
assertEquals(op4.getValue(), op2.getValue());
@@ -301,348 +309,22 @@
final Long[] longData = new Long[] {9823984L, 2908934L, -234234L, 9089234L};
final Object[] objectData = new Object[] {new Object(), new Object(), new Object(), new Object()};
final String[] stringData = new String[] {"A", "B", "C", "D"};
return Arrays.asList(new Object[][] {
- // boolean
- {
- new Functions<Boolean>() {
- @Override
- public PropertyMock<Boolean> create() {
- return new BooleanPropertyMock();
- }
- @Override
- public void bind(PropertyMock<Boolean> op1, PropertyMock<Boolean> op2) {
- Bindings.bindBidirectional(op1, op2);
- }
- @Override
- public void unbind(PropertyMock<Boolean> op1, PropertyMock<Boolean> op2) {
- Bindings.unbindBidirectional(op1, op2);
- }
- @Override
- public BidirectionalBinding createBindingDirectly(PropertyMock<Boolean> op1, PropertyMock<Boolean> op2) {
- return BidirectionalBinding.bind(op1, op2);
- }
- @Override
- public void check(Boolean expected, Boolean actual) {
- assertEquals(expected, actual);
- }
- },
- booleanData
- },
- // double
- {
- new Functions<Number>() {
- @Override
- public PropertyMock<Number> create() {
- return new DoublePropertyMock();
- }
- @Override
- public void bind(PropertyMock<Number> op1, PropertyMock<Number> op2) {
- Bindings.bindBidirectional(op1, op2);
- }
- @Override
- public void unbind(PropertyMock<Number> op1, PropertyMock<Number> op2) {
- Bindings.unbindBidirectional(op1, op2);
- }
- @Override
- public BidirectionalBinding createBindingDirectly(PropertyMock<Number> op1, PropertyMock<Number> op2) {
- return BidirectionalBinding.bind(op1, op2);
- }
- @Override
- public void check(Number expected, Number actual) {
- assertEquals(expected.doubleValue(), actual.doubleValue(), EPSILON_DOUBLE);
- }
- },
- doubleData
- },
- // float
- {
- new Functions<Number>() {
- @Override
- public PropertyMock<Number> create() {
- return new FloatPropertyMock();
- }
- @Override
- public void bind(PropertyMock<Number> op1, PropertyMock<Number> op2) {
- Bindings.bindBidirectional(op1, op2);
- }
- @Override
- public void unbind(PropertyMock<Number> op1, PropertyMock<Number> op2) {
- Bindings.unbindBidirectional(op1, op2);
- }
- @Override
- public BidirectionalBinding createBindingDirectly(PropertyMock<Number> op1, PropertyMock<Number> op2) {
- return BidirectionalBinding.bind(op1, op2);
- }
- @Override
- public void check(Number expected, Number actual) {
- assertEquals(expected.floatValue(), actual.floatValue(), EPSILON_FLOAT);
- }
- },
- floatData
- },
- // integer
- {
- new Functions<Number>() {
- @Override
- public PropertyMock<Number> create() {
- return new IntegerPropertyMock();
- }
- @Override
- public void bind(PropertyMock<Number> op1, PropertyMock<Number> op2) {
- Bindings.bindBidirectional(op1, op2);
- }
- @Override
- public void unbind(PropertyMock<Number> op1, PropertyMock<Number> op2) {
- Bindings.unbindBidirectional(op1, op2);
- }
- @Override
- public BidirectionalBinding createBindingDirectly(PropertyMock<Number> op1, PropertyMock<Number> op2) {
- return BidirectionalBinding.bind(op1, op2);
- }
- @Override
- public void check(Number expected, Number actual) {
- assertEquals(expected.intValue(), actual.intValue());
- }
- },
- integerData
- },
- // long
- {
- new Functions<Number>() {
- @Override
- public PropertyMock<Number> create() {
- return new LongPropertyMock();
- }
- @Override
- public void bind(PropertyMock<Number> op1, PropertyMock<Number> op2) {
- Bindings.bindBidirectional(op1, op2);
- }
- @Override
- public void unbind(PropertyMock<Number> op1, PropertyMock<Number> op2) {
- Bindings.unbindBidirectional(op1, op2);
- }
- @Override
- public BidirectionalBinding createBindingDirectly(PropertyMock<Number> op1, PropertyMock<Number> op2) {
- return BidirectionalBinding.bind(op1, op2);
- }
- @Override
- public void check(Number expected, Number actual) {
- assertEquals(expected.longValue(), actual.longValue());
- }
- },
- longData
- },
- // object
- {
- new Functions<Object>() {
- @Override
- public PropertyMock<Object> create() {
- return new ObjectPropertyMock<Object>();
- }
- @Override
- public void bind(PropertyMock<Object> op1, PropertyMock<Object> op2) {
- Bindings.bindBidirectional(op1, op2);
- }
- @Override
- public void unbind(PropertyMock<Object> op1, PropertyMock<Object> op2) {
- Bindings.unbindBidirectional(op1, op2);
- }
- @Override
- public BidirectionalBinding createBindingDirectly(PropertyMock<Object> op1, PropertyMock<Object> op2) {
- return BidirectionalBinding.bind(op1, op2);
- }
- @Override
- public void check(Object expected, Object actual) {
- assertEquals(expected, actual);
- }
- },
- objectData
- },
- // string
- {
- new Functions<String>() {
- @Override
- public PropertyMock<String> create() {
- return new StringPropertyMock();
- }
- @Override
- public void bind(PropertyMock<String> op1, PropertyMock<String> op2) {
- Bindings.bindBidirectional(op1, op2);
- }
- @Override
- public void unbind(PropertyMock<String> op1, PropertyMock<String> op2) {
- Bindings.unbindBidirectional(op1, op2);
- }
- @Override
- public BidirectionalBinding createBindingDirectly(PropertyMock<String> op1, PropertyMock<String> op2) {
- return BidirectionalBinding.bind(op1, op2);
- }
- @Override
- public void check(String expected, String actual) {
- assertEquals(expected, actual);
- }
- },
- stringData
- },
+ { new Factory(() -> new SimpleBooleanProperty(), booleanData) },
+ { new Factory(() -> new SimpleDoubleProperty(), doubleData) },
+ { new Factory(() -> new SimpleFloatProperty(), floatData) },
+ { new Factory(() -> new SimpleIntegerProperty(), integerData) },
+ { new Factory(() -> new SimpleLongProperty(), longData) },
+ { new Factory(() -> new SimpleObjectProperty<>(), objectData) },
+ { new Factory(() -> new SimpleStringProperty(), stringData) },
+ { new Factory(() -> new ReadOnlyBooleanWrapper(), booleanData) },
+ { new Factory(() -> new ReadOnlyDoubleWrapper(), doubleData) },
+ { new Factory(() -> new ReadOnlyFloatWrapper(), floatData) },
+ { new Factory(() -> new ReadOnlyIntegerWrapper(), integerData) },
+ { new Factory(() -> new ReadOnlyLongWrapper(), longData) },
+ { new Factory(() -> new ReadOnlyObjectWrapper<>(), objectData) },
+ { new Factory(() -> new ReadOnlyStringWrapper(), stringData) },
});
}
-
- private interface PropertyMock<T> extends Property<T> {
- int getListenerCount();
- }
-
- private static class BooleanPropertyMock extends SimpleBooleanProperty implements PropertyMock<Boolean> {
-
- private int listenerCount = 0;
-
- @Override
- public int getListenerCount() {
- return listenerCount;
- }
-
- @Override
- public void addListener(ChangeListener<? super Boolean> listener) {
- super.addListener(listener);
- listenerCount++;
- }
-
- @Override
- public void removeListener(ChangeListener<? super Boolean> listener) {
- super.removeListener(listener);
- listenerCount--;
- }
- }
-
- private static class DoublePropertyMock extends SimpleDoubleProperty implements PropertyMock<Number> {
-
- private int listenerCount = 0;
-
- @Override
- public int getListenerCount() {
- return listenerCount;
- }
-
- @Override
- public void addListener(ChangeListener<? super Number> listener) {
- super.addListener(listener);
- listenerCount++;
- }
-
- @Override
- public void removeListener(ChangeListener<? super Number> listener) {
- super.removeListener(listener);
- listenerCount--;
- }
- }
-
- private static class FloatPropertyMock extends SimpleFloatProperty implements PropertyMock<Number> {
-
- private int listenerCount = 0;
-
- @Override
- public int getListenerCount() {
- return listenerCount;
- }
-
- @Override
- public void addListener(ChangeListener<? super Number> listener) {
- super.addListener(listener);
- listenerCount++;
- }
-
- @Override
- public void removeListener(ChangeListener<? super Number> listener) {
- super.removeListener(listener);
- listenerCount--;
- }
- }
-
- private static class IntegerPropertyMock extends SimpleIntegerProperty implements PropertyMock<Number> {
-
- private int listenerCount = 0;
-
- @Override
- public int getListenerCount() {
- return listenerCount;
- }
-
- @Override
- public void addListener(ChangeListener<? super Number> listener) {
- super.addListener(listener);
- listenerCount++;
- }
-
- @Override
- public void removeListener(ChangeListener<? super Number> listener) {
- super.removeListener(listener);
- listenerCount--;
- }
- }
-
- private static class LongPropertyMock extends SimpleLongProperty implements PropertyMock<Number> {
-
- private int listenerCount = 0;
-
- @Override
- public int getListenerCount() {
- return listenerCount;
- }
-
- @Override
- public void addListener(ChangeListener<? super Number> listener) {
- super.addListener(listener);
- listenerCount++;
- }
-
- @Override
- public void removeListener(ChangeListener<? super Number> listener) {
- super.removeListener(listener);
- listenerCount--;
- }
- }
-
- private static class ObjectPropertyMock<T> extends SimpleObjectProperty<T> implements PropertyMock<T> {
-
- private int listenerCount = 0;
-
- @Override
- public int getListenerCount() {
- return listenerCount;
- }
-
- @Override
- public void addListener(ChangeListener<? super T> listener) {
- super.addListener(listener);
- listenerCount++;
- }
-
- @Override
- public void removeListener(ChangeListener<? super T> listener) {
- super.removeListener(listener);
- listenerCount--;
- }
- }
-
- private static class StringPropertyMock extends SimpleStringProperty implements PropertyMock<String> {
-
- private int listenerCount = 0;
-
- @Override
- public int getListenerCount() {
- return listenerCount;
- }
-
- @Override
- public void addListener(ChangeListener<? super String> listener) {
- super.addListener(listener);
- listenerCount++;
- }
-
- @Override
- public void removeListener(ChangeListener<? super String> listener) {
- super.removeListener(listener);
- listenerCount--;
- }
- }
}
< prev index next >