11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package javafx.beans.property;
27
28 import com.sun.javafx.binding.ExpressionHelperUtility;
29 import java.util.Arrays;
30 import java.util.List;
31 import static org.junit.Assert.assertEquals;
32 import org.junit.Before;
33 import org.junit.Ignore;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.junit.runners.Parameterized;
37
38 @RunWith(Parameterized.class)
39 public class PropertyBaseTest<T> {
40
41 @FunctionalInterface
42 public interface PropertyFactory<T> {
43 public Property<T> createProperty();
44 }
45
46 public static class Factory<T> {
47
48 private PropertyFactory<T> propertyFactory;
49 private PropertyFactory<T> observableFactory;
50 private T value;
51
52 public Factory(PropertyFactory<T> propertyFactory,
53 PropertyFactory<T> observableFactory, T value)
54 {
55 this.propertyFactory = propertyFactory;
56 this.observableFactory = observableFactory;
57 this.value = value;
58 }
59
60 public Property<T> createProperty() {
61 return propertyFactory.createProperty();
62 }
63
64 public Property<T> createObservable() {
65 return observableFactory.createProperty();
66 }
67
68 public T getValue() {
69 return value;
70 }
71 }
72
73 @Parameterized.Parameters
74 public static List<Object[]> data() {
75 return Arrays.asList(new Object[][] {
76 // primitive binding
77 // Property->Listener->Value
78 { new Factory(() -> new SimpleBooleanProperty(), () -> new SimpleBooleanProperty(), true) },
79 { new Factory(() -> new SimpleDoubleProperty(), () -> new SimpleDoubleProperty(), 1.0) },
80 { new Factory(() -> new SimpleFloatProperty(), () -> new SimpleFloatProperty(), 1.0f) },
81 { new Factory(() -> new SimpleIntegerProperty(), () -> new SimpleIntegerProperty(), 1) },
82 { new Factory(() -> new SimpleLongProperty(), () -> new SimpleLongProperty(), 1L) },
83 // generic with wrapper
84 // Property->Listener->Binding->BindingHelperObserver->Value
85 { new Factory(() -> new SimpleBooleanProperty(), () -> new SimpleObjectProperty<>(), true) },
86 { new Factory(() -> new SimpleDoubleProperty(), () -> new SimpleObjectProperty<>(), 1.0) },
87 { new Factory(() -> new SimpleFloatProperty(), () -> new SimpleObjectProperty<>(), 1.0f) },
88 { new Factory(() -> new SimpleIntegerProperty(), () -> new SimpleObjectProperty<>(), 1) },
89 { new Factory(() -> new SimpleLongProperty(), () -> new SimpleObjectProperty<>(), 1L) },
90 // generic
91 // Property->Listener->Value
92 { new Factory(() -> new SimpleObjectProperty(), () -> new SimpleObjectProperty<>(), new Object()) },
93 { new Factory(() -> new SimpleStringProperty(), () -> new SimpleObjectProperty<>(), "1") },
94 // the same as generic
95 { new Factory(() -> new SimpleStringProperty(), () -> new SimpleStringProperty(), "1") },
96 });
97 }
98
99 public PropertyBaseTest(Factory<T> factory) {
100 this.factory = factory;
101 }
102
103 @Before
104 public void setUp() {
105 property = factory.createProperty();
106 observable = factory.createObservable();
107 value = factory.getValue();
108 }
109
123 observable.setValue(value);
124 assertEquals(0, ExpressionHelperUtility.getInvalidationListeners(observable).size());
125 }
126
127 @Test
128 public void testTrimAfterGC() {
129 Property<T> p1 = factory.createProperty();
130 Property<T> p2 = factory.createProperty();
131 p1.bind(observable); // creates SingleInvalidation
132 p2.bind(observable); // creates Generic with 2 listeners
133 assertEquals(2, ExpressionHelperUtility.getInvalidationListeners(observable).size());
134
135 p1 = null;
136 p2 = null;
137 System.gc();
138
139 property.bind(observable); // calls trim
140 assertEquals(1, ExpressionHelperUtility.getInvalidationListeners(observable).size());
141 }
142
143 @Ignore("8130458")
144 @Test
145 public void testUnbindGenericWrapper() {
146 property.bind(observable);
147 assertEquals(1, ExpressionHelperUtility.getInvalidationListeners(observable).size());
148
149 property.unbind(); // should unbind wrapper from observable
150 assertEquals(0, ExpressionHelperUtility.getInvalidationListeners(observable).size());
151 }
152 }
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package javafx.beans.property;
27
28 import com.sun.javafx.binding.ExpressionHelperUtility;
29 import java.util.Arrays;
30 import java.util.List;
31 import javafx.beans.value.ObservableNumberValue;
32 import javafx.beans.value.ObservableValue;
33 import javafx.beans.value.ObservableValueBase;
34 import static org.junit.Assert.assertEquals;
35 import org.junit.Before;
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 import org.junit.runners.Parameterized;
39
40 @RunWith(Parameterized.class)
41 public class PropertyBaseTest<T> {
42
43 @FunctionalInterface
44 public interface PropertyFactory<T> {
45 public Property<T> createProperty();
46 }
47
48 public static class Factory<T> {
49
50 private PropertyFactory<T> propertyFactory;
51 private PropertyFactory<T> observableFactory;
52 private T value;
53
54 public Factory(PropertyFactory<T> propertyFactory,
55 PropertyFactory<T> observableFactory, T value)
56 {
57 this.propertyFactory = propertyFactory;
58 this.observableFactory = observableFactory;
59 this.value = value;
60 }
61
62 public Property<T> createProperty() {
63 return propertyFactory.createProperty();
64 }
65
66 public Property<T> createObservable() {
67 return observableFactory.createProperty();
68 }
69
70 public T getValue() {
71 return value;
72 }
73 }
74
75 private static class NumberPropertyMock extends ObservableValueBase<Number>
76 implements ObservableNumberValue, Property<Number>
77 {
78 private Number value = 0;
79
80 @Override public int intValue() { return value.intValue(); }
81 @Override public long longValue() { return value.longValue(); }
82 @Override public float floatValue() { return value.floatValue(); }
83 @Override public double doubleValue() { return value.doubleValue(); }
84 @Override public Number getValue() { return value; }
85 @Override public void setValue(Number value) {
86 this.value = value;
87 fireValueChangedEvent();
88 }
89
90 @Override public void bind(ObservableValue<? extends Number> observable) {}
91 @Override public void unbind() {}
92 @Override public boolean isBound() { return false; }
93 @Override public void bindBidirectional(Property<Number> other) {}
94 @Override public void unbindBidirectional(Property<Number> other) {}
95
96 @Override public Object getBean() { return null; }
97 @Override public String getName() { return ""; }
98 }
99
100 @Parameterized.Parameters
101 public static List<Object[]> data() {
102 return Arrays.asList(new Object[][] {
103 // primitive binding
104 // Property->Listener->Value
105 { new Factory(() -> new SimpleBooleanProperty(), () -> new SimpleBooleanProperty(), true) },
106 { new Factory(() -> new SimpleDoubleProperty(), () -> new SimpleDoubleProperty(), 1.0) },
107 { new Factory(() -> new SimpleFloatProperty(), () -> new SimpleFloatProperty(), 1.0f) },
108 { new Factory(() -> new SimpleIntegerProperty(), () -> new SimpleIntegerProperty(), 1) },
109 { new Factory(() -> new SimpleLongProperty(), () -> new SimpleLongProperty(), 1L) },
110 // generic with wrapper
111 // Property->Listener->Binding->BindingHelperObserver->Value
112 { new Factory(() -> new SimpleBooleanProperty(), () -> new SimpleObjectProperty<>(), true) },
113 { new Factory(() -> new SimpleDoubleProperty(), () -> new SimpleObjectProperty<>(), 1.0) },
114 { new Factory(() -> new SimpleDoubleProperty(), () -> new NumberPropertyMock(), 1.0) },
115 { new Factory(() -> new SimpleFloatProperty(), () -> new SimpleObjectProperty<>(), 1.0f) },
116 { new Factory(() -> new SimpleFloatProperty(), () -> new NumberPropertyMock(), 1.0f) },
117 { new Factory(() -> new SimpleIntegerProperty(), () -> new SimpleObjectProperty<>(), 1) },
118 { new Factory(() -> new SimpleIntegerProperty(), () -> new NumberPropertyMock(), 1) },
119 { new Factory(() -> new SimpleLongProperty(), () -> new SimpleObjectProperty<>(), 1L) },
120 { new Factory(() -> new SimpleLongProperty(), () -> new NumberPropertyMock(), 1L) },
121 // generic
122 // Property->Listener->Value
123 { new Factory(() -> new SimpleObjectProperty(), () -> new SimpleObjectProperty<>(), new Object()) },
124 { new Factory(() -> new SimpleStringProperty(), () -> new SimpleObjectProperty<>(), "1") },
125 // the same as generic
126 { new Factory(() -> new SimpleStringProperty(), () -> new SimpleStringProperty(), "1") },
127 });
128 }
129
130 public PropertyBaseTest(Factory<T> factory) {
131 this.factory = factory;
132 }
133
134 @Before
135 public void setUp() {
136 property = factory.createProperty();
137 observable = factory.createObservable();
138 value = factory.getValue();
139 }
140
154 observable.setValue(value);
155 assertEquals(0, ExpressionHelperUtility.getInvalidationListeners(observable).size());
156 }
157
158 @Test
159 public void testTrimAfterGC() {
160 Property<T> p1 = factory.createProperty();
161 Property<T> p2 = factory.createProperty();
162 p1.bind(observable); // creates SingleInvalidation
163 p2.bind(observable); // creates Generic with 2 listeners
164 assertEquals(2, ExpressionHelperUtility.getInvalidationListeners(observable).size());
165
166 p1 = null;
167 p2 = null;
168 System.gc();
169
170 property.bind(observable); // calls trim
171 assertEquals(1, ExpressionHelperUtility.getInvalidationListeners(observable).size());
172 }
173
174 @Test
175 public void testUnbindGenericWrapper() {
176 property.bind(observable);
177 assertEquals(1, ExpressionHelperUtility.getInvalidationListeners(observable).size());
178
179 property.unbind(); // should unbind wrapper from observable
180 assertEquals(0, ExpressionHelperUtility.getInvalidationListeners(observable).size());
181 }
182 }
|