• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (C) 2010 Google Inc.
3   *
4   * Licensed under the Apache License, Version 2.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   * http://www.apache.org/licenses/LICENSE-2.0
9   *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package libcore.java.util.beans;
18  
19  import java.beans.IndexedPropertyChangeEvent;
20  import java.beans.PropertyChangeEvent;
21  import java.beans.PropertyChangeListener;
22  import java.beans.PropertyChangeListenerProxy;
23  import java.beans.PropertyChangeSupport;
24  import java.io.Serializable;
25  import java.util.ArrayList;
26  import java.util.Arrays;
27  import java.util.Collections;
28  import java.util.EventListener;
29  import java.util.List;
30  import junit.framework.TestCase;
31  import libcore.libcore.util.SerializationTester;
32  
33  public final class PropertyChangeSupportTest extends TestCase {
34  
testOldAndNewAreBothNull()35      public void testOldAndNewAreBothNull() {
36          Object bean = new Object();
37          PropertyChangeSupport support = new PropertyChangeSupport(bean);
38          EventLog listener = new EventLog();
39          support.addPropertyChangeListener(listener);
40  
41          PropertyChangeEvent nullToNull = new PropertyChangeEvent(bean, "a", null, null);
42          support.firePropertyChange(nullToNull);
43          assertEquals(Arrays.<PropertyChangeEvent>asList(nullToNull), listener.log);
44      }
45  
testOldAndNewAreTheSame()46      public void testOldAndNewAreTheSame() {
47          Object bean = new Object();
48          PropertyChangeSupport support = new PropertyChangeSupport(bean);
49          EventLog listener = new EventLog();
50          support.addPropertyChangeListener(listener);
51  
52          PropertyChangeEvent xToX = new PropertyChangeEvent(bean, "a", "x", new String("x"));
53          support.firePropertyChange(xToX);
54          assertEquals(Arrays.<PropertyChangeEvent>asList(), listener.log);
55      }
56  
testEventsFilteredByProxies()57      public void testEventsFilteredByProxies() {
58          Object bean = new Object();
59          PropertyChangeEvent eventA = new PropertyChangeEvent(bean, "a", false, true);
60          PropertyChangeEvent eventB = new PropertyChangeEvent(bean, "b", false, true);
61          PropertyChangeEvent eventC = new PropertyChangeEvent(bean, "c", false, true);
62  
63          PropertyChangeSupport support = new PropertyChangeSupport(bean);
64  
65          EventLog all = new EventLog();
66          support.addPropertyChangeListener(all);
67  
68          EventLog proxiedA = new EventLog();
69          support.addPropertyChangeListener(new PropertyChangeListenerProxy("a", proxiedA));
70  
71          EventLog addA = new EventLog();
72          support.addPropertyChangeListener("a", addA);
73  
74          EventLog addAProxiedB = new EventLog();
75          support.addPropertyChangeListener("a", new PropertyChangeListenerProxy("b", addAProxiedB));
76  
77          EventLog proxiedAB = new EventLog();
78          support.addPropertyChangeListener(new PropertyChangeListenerProxy(
79                  "a", new PropertyChangeListenerProxy("b", proxiedAB)));
80  
81          EventLog proxiedAA = new EventLog();
82          support.addPropertyChangeListener(new PropertyChangeListenerProxy("a",
83                  new PropertyChangeListenerProxy("a", proxiedAA)));
84  
85          EventLog proxiedAAC = new EventLog();
86          support.addPropertyChangeListener(new PropertyChangeListenerProxy("a",
87                  new PropertyChangeListenerProxy("a",
88                  new PropertyChangeListenerProxy("c", proxiedAAC))));
89  
90          support.firePropertyChange(eventA);
91          support.firePropertyChange(eventB);
92          support.firePropertyChange(eventC);
93  
94          assertEquals(Arrays.asList(eventA, eventB, eventC), all.log);
95          assertEquals(Arrays.asList(eventA), proxiedA.log);
96          assertEquals(Arrays.asList(eventA), addA.log);
97          assertEquals(Arrays.asList(eventA), addAProxiedB.log);
98          assertEquals(Arrays.asList(eventA), proxiedAB.log);
99          assertEquals(Arrays.asList(eventA), proxiedAA.log);
100          assertEquals(Arrays.asList(eventA), proxiedAAC.log);
101      }
102  
103      /**
104       * Test that we need to do our own equals() work to manually unwrap an
105       * arbitrary number of proxies.
106       */
testRemoveWithProxies()107      public void testRemoveWithProxies() {
108          Object bean = new Object();
109          PropertyChangeSupport support = new PropertyChangeSupport(bean);
110  
111          EventLog all = new EventLog();
112          support.addPropertyChangeListener(all);
113          assertEquals(1, support.getPropertyChangeListeners().length);
114  
115          EventLog proxiedA = new EventLog();
116          support.addPropertyChangeListener(new PropertyChangeListenerProxy("a", proxiedA));
117          assertEquals(2, support.getPropertyChangeListeners().length);
118  
119          EventLog addA = new EventLog();
120          support.addPropertyChangeListener("a", addA);
121          assertEquals(3, support.getPropertyChangeListeners().length);
122  
123          EventLog addAProxiedB = new EventLog();
124          support.addPropertyChangeListener("a", new PropertyChangeListenerProxy("b", addAProxiedB));
125          assertEquals(4, support.getPropertyChangeListeners().length);
126  
127          EventLog proxiedAB = new EventLog();
128          PropertyChangeListenerProxy proxyAB = new PropertyChangeListenerProxy(
129                  "a", new PropertyChangeListenerProxy("b", proxiedAB));
130          support.addPropertyChangeListener(proxyAB);
131          assertEquals(5, support.getPropertyChangeListeners().length);
132  
133          EventLog proxiedAAC = new EventLog();
134          support.addPropertyChangeListener(new PropertyChangeListenerProxy("a",
135                  new PropertyChangeListenerProxy("a",
136                          new PropertyChangeListenerProxy("c", proxiedAAC))));
137          assertEquals(6, support.getPropertyChangeListeners().length);
138  
139          support.removePropertyChangeListener(all);
140          assertEquals(5, support.getPropertyChangeListeners().length);
141          support.removePropertyChangeListener("a", proxiedA);
142          assertEquals(4, support.getPropertyChangeListeners().length);
143          support.removePropertyChangeListener(new PropertyChangeListenerProxy("a", addA));
144          assertEquals(3, support.getPropertyChangeListeners().length);
145          support.removePropertyChangeListener(
146                  "a", new PropertyChangeListenerProxy("b", addAProxiedB));
147          assertEquals(2, support.getPropertyChangeListeners().length);
148          support.removePropertyChangeListener(proxyAB);
149          assertEquals(1, support.getPropertyChangeListeners().length);
150  
151          support.removePropertyChangeListener(proxiedAAC);
152          assertEquals(1, support.getPropertyChangeListeners().length);
153          support.removePropertyChangeListener(new PropertyChangeListenerProxy("a", proxiedAAC));
154          assertEquals(0, support.getPropertyChangeListeners().length);
155      }
156  
testAddingOneListenerTwice()157      public void testAddingOneListenerTwice() {
158          Object bean = new Object();
159          PropertyChangeSupport support = new PropertyChangeSupport(bean);
160          EventLog log = new EventLog();
161          support.addPropertyChangeListener("a", log);
162          support.addPropertyChangeListener(log);
163          support.addPropertyChangeListener(log);
164          support.addPropertyChangeListener("a", log);
165  
166          PropertyChangeEvent eventA = new PropertyChangeEvent(bean, "a", false, true);
167          PropertyChangeEvent eventB = new PropertyChangeEvent(bean, "b", false, true);
168  
169          support.firePropertyChange(eventA);
170          support.firePropertyChange(eventB);
171  
172          assertEquals(Arrays.asList(eventA, eventA, eventA, eventA, eventB, eventB), log.log);
173      }
174  
testAddingAListenerActuallyAddsAProxy()175      public void testAddingAListenerActuallyAddsAProxy() {
176          Object bean = new Object();
177          PropertyChangeSupport support = new PropertyChangeSupport(bean);
178          PropertyChangeListener listener = new PropertyChangeListener() {
179              public void propertyChange(PropertyChangeEvent event) {}
180          };
181          support.addPropertyChangeListener("a", listener);
182  
183          PropertyChangeListenerProxy p1
184                  = (PropertyChangeListenerProxy) support.getPropertyChangeListeners()[0];
185          assertEquals(PropertyChangeListenerProxy.class, p1.getClass());
186          assertTrue(p1 != listener); // weird but consistent with the RI
187          assertEquals("a", p1.getPropertyName());
188          assertEquals(listener, p1.getListener());
189      }
190  
testAddingAProxy()191      public void testAddingAProxy() {
192          Object bean = new Object();
193          PropertyChangeSupport support = new PropertyChangeSupport(bean);
194          PropertyChangeListener listener = new PropertyChangeListener() {
195              public void propertyChange(PropertyChangeEvent event) {}
196          };
197          PropertyChangeListenerProxy proxy = new PropertyChangeListenerProxy("a", listener);
198          support.addPropertyChangeListener("b", proxy);
199  
200          // this proxy sets us up to receive 'b' events
201          PropertyChangeListenerProxy p1
202                  = (PropertyChangeListenerProxy) support.getPropertyChangeListeners()[0];
203          assertEquals(PropertyChangeListenerProxy.class, p1.getClass());
204          assertEquals("b", p1.getPropertyName());
205  
206          // there's no more proxy on 'a'.
207          assertEquals(listener, p1.getListener());
208      }
209  
testSerialize()210      public void testSerialize() {
211          String s = "aced0005737200206a6176612e6265616e732e50726f70657274794368616e67"
212                  + "65537570706f727458d5d264574860bb03000349002a70726f706572747943686"
213                  + "16e6765537570706f727453657269616c697a65644461746156657273696f6e4c"
214                  + "00086368696c6472656e7400154c6a6176612f7574696c2f486173687461626c6"
215                  + "53b4c0006736f757263657400124c6a6176612f6c616e672f4f626a6563743b78"
216                  + "7000000002737200136a6176612e7574696c2e486173687461626c6513bb0f252"
217                  + "14ae4b803000246000a6c6f6164466163746f724900097468726573686f6c6478"
218                  + "703f4000000000000877080000000b00000001740001617371007e00000000000"
219                  + "2707400046265616e7372003a6c6962636f72652e6a6176612e7574696c2e6265"
220                  + "616e732e50726f70657274794368616e6765537570706f7274546573742445766"
221                  + "56e744c6f67b92667637d0b6f450200024c00036c6f677400104c6a6176612f75"
222                  + "74696c2f4c6973743b4c00046e616d657400124c6a6176612f6c616e672f53747"
223                  + "2696e673b7870737200136a6176612e7574696c2e41727261794c6973747881d2"
224                  + "1d99c7619d03000149000473697a6578700000000077040000000a7874000b6c6"
225                  + "97374656e6572546f4171007e000c70787871007e00087371007e00097371007e"
226                  + "000d0000000077040000000a7874000d6c697374656e6572546f416c6c7078";
227  
228          Object bean = "bean";
229          PropertyChangeSupport support = new PropertyChangeSupport(bean);
230          EventLog listenerToAll = new EventLog();
231          listenerToAll.name = "listenerToAll";
232          EventLog listenerToA = new EventLog();
233          listenerToA.name = "listenerToA";
234          support.addPropertyChangeListener(listenerToAll);
235          support.addPropertyChangeListener("a", listenerToA);
236          support.addPropertyChangeListener("a", listenerToA);
237  
238          new SerializationTester<PropertyChangeSupport>(support, s) {
239              @Override protected boolean equals(PropertyChangeSupport a, PropertyChangeSupport b) {
240                  return describe(a.getPropertyChangeListeners())
241                          .equals(describe(b.getPropertyChangeListeners()));
242              }
243              @Override protected void verify(PropertyChangeSupport deserialized) {
244                  assertEquals("[a to listenerToA, a to listenerToA, listenerToAll]",
245                          describe(deserialized.getPropertyChangeListeners()));
246              }
247          }.test();
248      }
249  
testFireIndexedPropertyChange_intUpdate()250      public void testFireIndexedPropertyChange_intUpdate() {
251          Object bean = "bean";
252          PropertyChangeSupport support = new PropertyChangeSupport(bean);
253  
254          EventLog listenerToIntProperty = new EventLog();
255          support.addPropertyChangeListener("intProperty", listenerToIntProperty);
256  
257          support.fireIndexedPropertyChange("intProperty", 10, 1, 2);
258  
259          List<PropertyChangeEvent> events = listenerToIntProperty.log;
260          assertEquals(1, events.size());
261          assertEquals(1, events.get(0).getOldValue());
262          assertEquals(2, events.get(0).getNewValue());
263          assertEquals("intProperty", events.get(0).getPropertyName());
264          assertTrue(events.get(0) instanceof IndexedPropertyChangeEvent);
265          assertEquals(10, ((IndexedPropertyChangeEvent) events.get(0)).getIndex());
266      }
267  
testFireIndexedPropertyChange_intUpdate_noEventWhenOldIsEqualToNew()268      public void testFireIndexedPropertyChange_intUpdate_noEventWhenOldIsEqualToNew() {
269          Object bean = "bean";
270          PropertyChangeSupport support = new PropertyChangeSupport(bean);
271  
272          EventLog listenerToIntProperty = new EventLog();
273          support.addPropertyChangeListener("intProperty", listenerToIntProperty);
274  
275          support.fireIndexedPropertyChange("intProperty", 0, 1, 1);
276  
277          List<PropertyChangeEvent> events = listenerToIntProperty.log;
278          assertTrue(events.isEmpty());
279      }
280  
testFireIndexedPropertyChange_booleanUpdate()281      public void testFireIndexedPropertyChange_booleanUpdate() {
282          Object bean = "bean";
283          PropertyChangeSupport support = new PropertyChangeSupport(bean);
284  
285          EventLog listenerToBooleanProperty = new EventLog();
286          support.addPropertyChangeListener("booleanProperty", listenerToBooleanProperty);
287  
288          support.fireIndexedPropertyChange("booleanProperty", 11, true, false);
289  
290          List<PropertyChangeEvent> events = listenerToBooleanProperty.log;
291          assertEquals(1, events.size());
292          assertEquals(true, events.get(0).getOldValue());
293          assertEquals(false, events.get(0).getNewValue());
294          assertEquals("booleanProperty", events.get(0).getPropertyName());
295          assertTrue(events.get(0) instanceof IndexedPropertyChangeEvent);
296          assertEquals(11, ((IndexedPropertyChangeEvent) events.get(0)).getIndex());
297      }
298  
testFireIndexedPropertyChange_booleanUpdate_noEventWhenOldIsEqualToNew()299      public void testFireIndexedPropertyChange_booleanUpdate_noEventWhenOldIsEqualToNew() {
300          Object bean = "bean";
301          PropertyChangeSupport support = new PropertyChangeSupport(bean);
302  
303          EventLog listenerToBooleanProperty = new EventLog();
304          support.addPropertyChangeListener("booleanProperty", listenerToBooleanProperty);
305  
306          support.fireIndexedPropertyChange("booleanProperty", 0, true, true);
307  
308          List<PropertyChangeEvent> events = listenerToBooleanProperty.log;
309          assertTrue(events.isEmpty());
310      }
311  
describe(PropertyChangeListener[] listeners)312      private String describe(PropertyChangeListener[] listeners) {
313          List<String> result = new ArrayList<String>();
314          for (PropertyChangeListener listener : listeners) {
315              result.add(describe(listener));
316          }
317          Collections.sort(result);
318          return result.toString();
319      }
320  
describe(EventListener listener)321      private String describe(EventListener listener) {
322          if (listener instanceof PropertyChangeListenerProxy) {
323              PropertyChangeListenerProxy proxy = (PropertyChangeListenerProxy) listener;
324              return proxy.getPropertyName() + " to " + describe(proxy.getListener());
325          } else {
326              return listener.toString();
327          }
328      }
329  
330      static class EventLog implements PropertyChangeListener, Serializable {
331          String name = "EventLog";
332          List<PropertyChangeEvent> log = new ArrayList<PropertyChangeEvent>();
propertyChange(PropertyChangeEvent event)333          public void propertyChange(PropertyChangeEvent event) {
334              log.add(event);
335          }
toString()336          @Override public String toString() {
337              return name;
338          }
339      }
340  }
341