1   /*
2    * Copyright 2002-2005 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5    * use this file except in compliance with the License. You may obtain a copy of
6    * 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, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations under
14   * the License.
15   */
16  package org.springframework.binding.value.support;
17  
18  import org.springframework.binding.support.TestPropertyChangeListener;
19  import org.springframework.binding.value.ValueModel;
20  import org.springframework.richclient.test.SpringRichTestCase;
21  
22  import java.beans.PropertyChangeListener;
23  import java.math.BigDecimal;
24  import java.math.BigInteger;
25  
26  /**
27   * Tests class {@link AbstractValueModel}.
28   *  
29   * @author Oliver Hutchison
30   */
31  public abstract class AbstractValueModelTests extends SpringRichTestCase {
32  
33      private TestAbstractValueModel vm;
34  
35      private TestPropertyChangeListener pcl;
36  
37      private class EqualsEverything {
38          public boolean equals(Object other) {
39              return true;
40          }
41      }
42  
43      public void doSetUp() {
44          vm = new TestAbstractValueModel();
45          pcl = new TestPropertyChangeListener(ValueModel.VALUE_PROPERTY);
46          vm.addValueChangeListener(pcl);
47      }
48  
49      public void testSetValueSilently() {
50          PropertyChangeListener pcl1 = new TestPropertyChangeListener(ValueModel.VALUE_PROPERTY);
51  
52          vm.setValueSilently("1", pcl1);
53          assertEquals("should have notified listener", 1, pcl.eventCount());
54          assertEquals("should have changed value", vm.value, "1");
55  
56          vm.setValueSilently("2", pcl);
57          assertEquals("should not have notified listener", 1, pcl.eventCount());
58          assertEquals("should have changed value", vm.value, "2");
59  
60          vm.setValue("3");
61          assertEquals("should have notified listener", 2, pcl.eventCount());
62          assertEquals("should have changed value", vm.value, "3");
63      }
64  
65      public void testFirePrimativeValueChange() {
66          vm.fireValueChange(true, false);
67          assertEquals(1, pcl.eventCount());
68          assertSame(Boolean.TRUE, pcl.lastEvent().getOldValue());
69          assertSame(Boolean.FALSE, pcl.lastEvent().getNewValue());
70  
71          vm.fireValueChange(1, 2);
72          assertEquals(2, pcl.eventCount());
73          assertEquals(new Integer(1), pcl.lastEvent().getOldValue());
74          assertEquals(new Integer(2), pcl.lastEvent().getNewValue());
75  
76          vm.fireValueChange(1l, 2l);
77          assertEquals(3, pcl.eventCount());
78          assertEquals(new Long(1), pcl.lastEvent().getOldValue());
79          assertEquals(new Long(2), pcl.lastEvent().getNewValue());
80  
81          vm.fireValueChange(1f, 2f);
82          assertEquals(4, pcl.eventCount());
83          assertEquals(new Double(1f), pcl.lastEvent().getOldValue());
84          assertEquals(new Double(2f), pcl.lastEvent().getNewValue());
85      }
86      
87      public void testFireValueChange() {
88          Object o1 = new Object();
89          Object o2 = new Object();
90          
91          vm.fireValueChange(o1, o2);
92          assertEquals(1, pcl.eventCount());
93          assertSame(o1, pcl.lastEvent().getOldValue());
94          assertSame(o2, pcl.lastEvent().getNewValue());
95  
96          vm.fireValueChange(o1, o1);
97          assertEquals(1, pcl.eventCount());
98  
99          vm.fireValueChange(o1, null);
100         assertEquals(2, pcl.eventCount());
101         assertEquals(o1, pcl.lastEvent().getOldValue());
102         assertEquals(null, pcl.lastEvent().getNewValue());
103         
104         vm.fireValueChange(null, o1);
105         assertEquals(3, pcl.eventCount());
106         assertEquals(null, pcl.lastEvent().getOldValue());
107         assertEquals(o1, pcl.lastEvent().getNewValue());
108         
109         vm.fireValueChange(null, null);
110         assertEquals(3, pcl.eventCount());
111         
112         vm.fireValueChange(new Integer(1), new Integer(1));
113         assertEquals(3, pcl.eventCount());
114 
115         vm.fireValueChangeWhenStillEqual();
116         assertEquals(4, pcl.eventCount());
117         assertEquals(vm.value, pcl.lastEvent().getOldValue());
118         assertEquals(vm.value, pcl.lastEvent().getNewValue());
119 
120         Object equalsEverything = new EqualsEverything();
121         vm.fireValueChange(o1, equalsEverything);
122         assertEquals(5, pcl.eventCount());
123         assertEquals(o1, pcl.lastEvent().getOldValue());
124         assertSame(equalsEverything, pcl.lastEvent().getNewValue());
125         
126         vm.fireValueChange(equalsEverything, o1);
127         assertEquals(6, pcl.eventCount());
128         assertSame(equalsEverything, pcl.lastEvent().getOldValue());
129         assertEquals(o1, pcl.lastEvent().getNewValue());
130     }
131 
132     public void testHasValueChangedChecksIdentityForUnsafeClasses() {
133         Object equalsEverything = new EqualsEverything();
134         Object o2 = new Object();
135 
136         assertTrue(vm.hasValueChanged(equalsEverything, o2));
137         assertTrue(vm.hasValueChanged(null, o2));
138         assertTrue(vm.hasValueChanged(null, equalsEverything));
139         assertTrue(vm.hasValueChanged(equalsEverything, null));
140 
141         assertTrue(!vm.hasValueChanged(equalsEverything, equalsEverything));
142         assertTrue(!vm.hasValueChanged(null, null));
143     }
144 
145     public void testHasValueChangedChecksEqualityForSafeClasses() {
146         vm.setValueChangeDetector( new DefaultValueChangeDetector() );
147 
148         testChecksEqualityForSafeClasses(new Boolean(true), new Boolean(false), new Boolean(true));        
149         testChecksEqualityForSafeClasses(new Byte((byte)1), new Byte((byte)2), new Byte((byte)1));
150         testChecksEqualityForSafeClasses(new Short((short)1), new Short((short)2), new Short((short)1));
151         testChecksEqualityForSafeClasses(new Integer(1), new Integer(2), new Integer(1));
152         testChecksEqualityForSafeClasses(new Long(1), new Long(2), new Long(1));
153         testChecksEqualityForSafeClasses(new Float(1), new Float(2), new Float(1));
154         testChecksEqualityForSafeClasses(new Double(1), new Double(2), new Double(1));
155         testChecksEqualityForSafeClasses(new BigInteger("1"), new BigInteger("2"), new BigInteger("1"));
156         testChecksEqualityForSafeClasses(new BigDecimal("1"), new BigDecimal("2"), new BigDecimal("1"));
157         testChecksEqualityForSafeClasses(new Character('a'), new Character('b'), new Character('a'));        
158         testChecksEqualityForSafeClasses("1", "2", new String("1"));
159     }
160 
161     private void testChecksEqualityForSafeClasses(Object o1, Object o2, Object o3) {        
162         Object other = new Object();
163         
164         assertNotSame(o1, o2);
165         assertNotSame(o1, o3);
166         assertEquals(o1, o3);
167         
168         assertTrue(vm.hasValueChanged(o1, o2));
169         assertTrue(vm.hasValueChanged(null, o2));
170         assertTrue(vm.hasValueChanged(o1, null));
171         assertTrue(vm.hasValueChanged(o1, other));
172         
173         assertTrue(vm.hasValueChanged(other, o1));
174         assertTrue(!vm.hasValueChanged(o1, o1));
175         assertTrue(!vm.hasValueChanged(o1, o3));
176         assertTrue(!vm.hasValueChanged(o3, o1));
177     }
178 
179     public class TestAbstractValueModel extends AbstractValueModel {
180 
181         public Object value;
182 
183         public Object getValue() {
184             return value;
185         }
186 
187         public void setValue(Object newValue) {
188             Object oldValue = value;
189             value = newValue;
190             fireValueChange(oldValue, newValue);
191         }
192     }
193 }