1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.collections; 18 19 import java.io.Serializable; 20 import java.lang.reflect.Method; 21 import java.util.Map; 22 23 import junit.framework.Test; 24 import junit.textui.TestRunner; 25 26 import org.apache.commons.collections.map.AbstractTestMap; 27 28 /** 29 * Test cases for BeanMap 30 * 31 * @version $Revision: 646780 $ $Date: 2008-04-10 14:48:07 +0200 (Thu, 10 Apr 2008) $ 32 * 33 * @author Morgan Delagrange 34 * @author Stephen Colebourne 35 */ 36 public class TestBeanMap extends AbstractTestMap { 37 TestBeanMap(String testName)38 public TestBeanMap(String testName) { 39 super(testName); 40 } 41 main(String[] args)42 public static void main(String[] args) { 43 TestRunner.run(suite()); 44 } 45 suite()46 public static Test suite() { 47 return BulkTest.makeSuite(TestBeanMap.class); 48 } 49 50 /* 51 note to self. The getter and setter methods were generated by copying the 52 field declarations and using the following regular expression search and 53 replace: 54 55 From: 56 private \(.*\) some\(.*\); 57 To: 58 public \1 getSome\2Value() { 59 return some\2; 60 } 61 public void setSome\2Value(\1 value) { 62 some\2 = value; 63 } 64 65 Also note: The sample keys and mappings were generated manually. 66 */ 67 68 69 public static class BeanWithProperties implements Serializable { 70 private int someInt; 71 private long someLong; 72 private double someDouble; 73 private float someFloat; 74 private short someShort; 75 private byte someByte; 76 private char someChar; 77 private Integer someInteger; 78 private String someString; 79 private Object someObject; 80 getSomeIntValue()81 public int getSomeIntValue() { 82 return someInt; 83 } setSomeIntValue(int value)84 public void setSomeIntValue(int value) { 85 someInt = value; 86 } 87 getSomeLongValue()88 public long getSomeLongValue() { 89 return someLong; 90 } setSomeLongValue(long value)91 public void setSomeLongValue(long value) { 92 someLong = value; 93 } 94 getSomeDoubleValue()95 public double getSomeDoubleValue() { 96 return someDouble; 97 } setSomeDoubleValue(double value)98 public void setSomeDoubleValue(double value) { 99 someDouble = value; 100 } 101 getSomeFloatValue()102 public float getSomeFloatValue() { 103 return someFloat; 104 } setSomeFloatValue(float value)105 public void setSomeFloatValue(float value) { 106 someFloat = value; 107 } 108 getSomeShortValue()109 public short getSomeShortValue() { 110 return someShort; 111 } setSomeShortValue(short value)112 public void setSomeShortValue(short value) { 113 someShort = value; 114 } 115 getSomeByteValue()116 public byte getSomeByteValue() { 117 return someByte; 118 } setSomeByteValue(byte value)119 public void setSomeByteValue(byte value) { 120 someByte = value; 121 } 122 getSomeCharValue()123 public char getSomeCharValue() { 124 return someChar; 125 } setSomeCharValue(char value)126 public void setSomeCharValue(char value) { 127 someChar = value; 128 } 129 getSomeStringValue()130 public String getSomeStringValue() { 131 return someString; 132 } setSomeStringValue(String value)133 public void setSomeStringValue(String value) { 134 someString = value; 135 } 136 getSomeIntegerValue()137 public Integer getSomeIntegerValue() { 138 return someInteger; 139 } setSomeIntegerValue(Integer value)140 public void setSomeIntegerValue(Integer value) { 141 someInteger = value; 142 } 143 getSomeObjectValue()144 public Object getSomeObjectValue() { 145 return someObject; 146 } setSomeObjectValue(Object value)147 public void setSomeObjectValue(Object value) { 148 someObject = value; 149 } 150 } 151 152 // note to self. The Sample keys were generated by copying the field 153 // declarations and using the following regular expression search and replace: 154 // 155 // From: 156 // private \(.*\) some\(.*\); 157 // To: 158 // "some\2Value", 159 // 160 // Then, I manually added the "class" key, which is a property that exists for 161 // all beans (and all objects for that matter. getSampleKeys()162 public Object[] getSampleKeys() { 163 Object[] keys = new Object[] { 164 "someIntValue", 165 "someLongValue", 166 "someDoubleValue", 167 "someFloatValue", 168 "someShortValue", 169 "someByteValue", 170 "someCharValue", 171 "someIntegerValue", 172 "someStringValue", 173 "someObjectValue", 174 "class", 175 }; 176 return keys; 177 } 178 179 /** 180 * An object value that will be stored in the bean map as a value. Need 181 * to save this externally so that we can make sure the object instances 182 * are equivalent since getSampleValues() would otherwise construct a new 183 * and different Object each time. 184 **/ 185 private Object objectInFullMap = new Object(); 186 187 // note to self: the sample values were created manually getSampleValues()188 public Object[] getSampleValues() { 189 Object[] values = new Object[] { 190 new Integer(1234), 191 new Long(1298341928234L), 192 new Double(123423.34), 193 new Float(1213332.12f), 194 new Short((short)134), 195 new Byte((byte)10), 196 new Character('a'), 197 new Integer(1432), 198 "SomeStringValue", 199 objectInFullMap, 200 BeanWithProperties.class, 201 }; 202 return values; 203 } 204 getNewSampleValues()205 public Object[] getNewSampleValues() { 206 Object[] values = new Object[] { 207 new Integer(223), 208 new Long(23341928234L), 209 new Double(23423.34), 210 new Float(213332.12f), 211 new Short((short)234), 212 new Byte((byte)20), 213 new Character('b'), 214 new Integer(232), 215 "SomeNewStringValue", 216 new Object(), 217 null, 218 }; 219 return values; 220 } 221 222 /** 223 * Values is a dead copy in BeanMap, so refresh each time. 224 */ verifyValues()225 public void verifyValues() { 226 values = map.values(); 227 super.verifyValues(); 228 } 229 230 /** 231 * The mappings in a BeanMap are fixed on the properties the underlying 232 * bean has. Adding and removing mappings is not possible, thus this 233 * method is overridden to return false. 234 */ isPutAddSupported()235 public boolean isPutAddSupported() { 236 return false; 237 } 238 239 /** 240 * The mappings in a BeanMap are fixed on the properties the underlying 241 * bean has. Adding and removing mappings is not possible, thus this 242 * method is overridden to return false. 243 */ isRemoveSupported()244 public boolean isRemoveSupported() { 245 return false; 246 } 247 makeFullMap()248 public Map makeFullMap() { 249 // note: These values must match (i.e. .equals() must return true) 250 // those returned from getSampleValues(). 251 BeanWithProperties bean = new BeanWithProperties(); 252 bean.setSomeIntValue(1234); 253 bean.setSomeLongValue(1298341928234L); 254 bean.setSomeDoubleValue(123423.34); 255 bean.setSomeFloatValue(1213332.12f); 256 bean.setSomeShortValue((short)134); 257 bean.setSomeByteValue((byte)10); 258 bean.setSomeCharValue('a'); 259 bean.setSomeIntegerValue(new Integer(1432)); 260 bean.setSomeStringValue("SomeStringValue"); 261 bean.setSomeObjectValue(objectInFullMap); 262 return new BeanMap(bean); 263 } 264 makeEmptyMap()265 public Map makeEmptyMap() { 266 return new BeanMap(); 267 } 268 ignoredTests()269 public String[] ignoredTests() { 270 // Ignore the serialization tests on collection views. 271 return new String[] { 272 "TestBeanMap.bulkTestMapEntrySet.testCanonicalEmptyCollectionExists", 273 "TestBeanMap.bulkTestMapEntrySet.testCanonicalFullCollectionExists", 274 "TestBeanMap.bulkTestMapKeySet.testCanonicalEmptyCollectionExists", 275 "TestBeanMap.bulkTestMapKeySet.testCanonicalFullCollectionExists", 276 "TestBeanMap.bulkTestMapValues.testCanonicalEmptyCollectionExists", 277 "TestBeanMap.bulkTestMapValues.testCanonicalFullCollectionExists", 278 "TestBeanMap.bulkTestMapEntrySet.testSimpleSerialization", 279 "TestBeanMap.bulkTestMapKeySet.testSimpleSerialization", 280 "TestBeanMap.bulkTestMapEntrySet.testSerializeDeserializeThenCompare", 281 "TestBeanMap.bulkTestMapKeySet.testSerializeDeserializeThenCompare" 282 }; 283 } 284 285 /** 286 * Need to override this method because the "clear()" method on the bean 287 * map just returns the bean properties to their default states. It does 288 * not actually remove the mappings as per the map contract. The default 289 * testClear() methods checks that the clear method throws an 290 * UnsupportedOperationException since this class is not add/remove 291 * modifiable. In our case though, we do not always throw that exception. 292 */ testMapClear()293 public void testMapClear() { 294 //TODO: make sure a call to BeanMap.clear returns the bean to its 295 //default initialization values. 296 } 297 298 /** 299 * Need to override this method because the "put()" method on the bean 300 * doesn't work for this type of Map. 301 */ testMapPut()302 public void testMapPut() { 303 // see testBeanMapPutAllWriteable 304 } 305 testBeanMapClone()306 public void testBeanMapClone() { 307 BeanMap map = (BeanMap)makeFullMap(); 308 try { 309 BeanMap map2 = (BeanMap)((BeanMap)map).clone(); 310 311 // make sure containsKey is working to verify the bean was cloned 312 // ok, and the read methods were properly initialized 313 Object[] keys = getSampleKeys(); 314 for(int i = 0; i < keys.length; i++) { 315 assertTrue("Cloned BeanMap should contain the same keys", 316 map2.containsKey(keys[i])); 317 } 318 } catch (CloneNotSupportedException exception) { 319 fail("BeanMap.clone() should not throw a " + 320 "CloneNotSupportedException when clone should succeed."); 321 } 322 } 323 testBeanMapPutAllWriteable()324 public void testBeanMapPutAllWriteable() { 325 BeanMap map1 = (BeanMap)makeFullMap(); 326 BeanMap map2 = (BeanMap)makeFullMap(); 327 map2.put("someIntValue", new Integer(0)); 328 map1.putAllWriteable(map2); 329 assertEquals(map1.get("someIntValue"), new Integer(0)); 330 } 331 testMethodAccessor()332 public void testMethodAccessor() throws Exception { 333 BeanMap map = (BeanMap) makeFullMap(); 334 Method method = BeanWithProperties.class.getDeclaredMethod("getSomeIntegerValue", (Class[]) null); 335 assertEquals(method, map.getReadMethod("someIntegerValue")); 336 } 337 testMethodMutator()338 public void testMethodMutator() throws Exception { 339 BeanMap map = (BeanMap) makeFullMap(); 340 Method method = BeanWithProperties.class.getDeclaredMethod("setSomeIntegerValue", new Class[] {Integer.class}); 341 assertEquals(method, map.getWriteMethod("someIntegerValue")); 342 } 343 344 } 345