001    /*
002     * Copyright 2002-2005 the original author or authors.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     * 
008     * http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.binding.value.support;
017    
018    import org.springframework.binding.support.TestPropertyChangeListener;
019    import org.springframework.binding.value.ValueModel;
020    import org.springframework.richclient.test.SpringRichTestCase;
021    
022    import java.beans.PropertyChangeListener;
023    import java.math.BigDecimal;
024    import java.math.BigInteger;
025    
026    /**
027     * Tests class {@link AbstractValueModel}.
028     *  
029     * @author Oliver Hutchison
030     */
031    public abstract class AbstractValueModelTests extends SpringRichTestCase {
032    
033        private TestAbstractValueModel vm;
034    
035        private TestPropertyChangeListener pcl;
036    
037        private class EqualsEverything {
038            public boolean equals(Object other) {
039                return true;
040            }
041        }
042    
043        public void doSetUp() {
044            vm = new TestAbstractValueModel();
045            pcl = new TestPropertyChangeListener(ValueModel.VALUE_PROPERTY);
046            vm.addValueChangeListener(pcl);
047        }
048    
049        public void testSetValueSilently() {
050            PropertyChangeListener pcl1 = new TestPropertyChangeListener(ValueModel.VALUE_PROPERTY);
051    
052            vm.setValueSilently("1", pcl1);
053            assertEquals("should have notified listener", 1, pcl.eventCount());
054            assertEquals("should have changed value", vm.value, "1");
055    
056            vm.setValueSilently("2", pcl);
057            assertEquals("should not have notified listener", 1, pcl.eventCount());
058            assertEquals("should have changed value", vm.value, "2");
059    
060            vm.setValue("3");
061            assertEquals("should have notified listener", 2, pcl.eventCount());
062            assertEquals("should have changed value", vm.value, "3");
063        }
064    
065        public void testFirePrimativeValueChange() {
066            vm.fireValueChange(true, false);
067            assertEquals(1, pcl.eventCount());
068            assertSame(Boolean.TRUE, pcl.lastEvent().getOldValue());
069            assertSame(Boolean.FALSE, pcl.lastEvent().getNewValue());
070    
071            vm.fireValueChange(1, 2);
072            assertEquals(2, pcl.eventCount());
073            assertEquals(new Integer(1), pcl.lastEvent().getOldValue());
074            assertEquals(new Integer(2), pcl.lastEvent().getNewValue());
075    
076            vm.fireValueChange(1l, 2l);
077            assertEquals(3, pcl.eventCount());
078            assertEquals(new Long(1), pcl.lastEvent().getOldValue());
079            assertEquals(new Long(2), pcl.lastEvent().getNewValue());
080    
081            vm.fireValueChange(1f, 2f);
082            assertEquals(4, pcl.eventCount());
083            assertEquals(new Double(1f), pcl.lastEvent().getOldValue());
084            assertEquals(new Double(2f), pcl.lastEvent().getNewValue());
085        }
086        
087        public void testFireValueChange() {
088            Object o1 = new Object();
089            Object o2 = new Object();
090            
091            vm.fireValueChange(o1, o2);
092            assertEquals(1, pcl.eventCount());
093            assertSame(o1, pcl.lastEvent().getOldValue());
094            assertSame(o2, pcl.lastEvent().getNewValue());
095    
096            vm.fireValueChange(o1, o1);
097            assertEquals(1, pcl.eventCount());
098    
099            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    }