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.beanutils; 18 19 import java.lang.reflect.InvocationTargetException; 20 import java.util.ArrayList; 21 import java.util.HashMap; 22 import java.util.LinkedList; 23 import java.util.List; 24 import java.util.Map; 25 import java.util.TreeMap; 26 27 import junit.framework.Test; 28 import junit.framework.TestCase; 29 import junit.framework.TestSuite; 30 31 /** 32 * <p>Test Case for the <code>LazyDynaMap</code> implementation class.</p> 33 * 34 * @version $Id$ 35 */ 36 public class LazyDynaMapTestCase extends TestCase { 37 38 protected LazyDynaMap dynaMap = null; 39 protected String testProperty = "myProperty"; 40 protected String testPropertyA = "myProperty-A"; 41 protected String testPropertyB = "myProperty-B"; 42 protected String testString1 = "myStringValue-1"; 43 protected String testString2 = "myStringValue-2"; 44 protected Integer testInteger1 = new Integer(30); 45 protected Integer testInteger2 = new Integer(40); 46 protected String testKey = "myKey"; 47 48 // ---------------------------------------------------------- Constructors 49 50 /** 51 * Construct a new instance of this test case. 52 * 53 * @param name Name of the test case 54 */ LazyDynaMapTestCase(final String name)55 public LazyDynaMapTestCase(final String name) { 56 super(name); 57 } 58 59 // -------------------------------------------------- Overall Test Methods 60 61 /** 62 * Run thus Test 63 */ main(final String[] args)64 public static void main(final String[] args) { 65 junit.textui.TestRunner.run(suite()); 66 } 67 68 /** 69 * Return the tests included in this test suite. 70 */ suite()71 public static Test suite() { 72 return (new TestSuite(LazyDynaMapTestCase.class)); 73 } 74 75 /** 76 * Set up instance variables required by this test case. 77 */ 78 @Override setUp()79 public void setUp() throws Exception { 80 dynaMap = new LazyDynaMap(); 81 dynaMap.setReturnNull(true); 82 } 83 84 /** 85 * Tear down instance variables required by this test case. 86 */ 87 @Override tearDown()88 public void tearDown() { 89 dynaMap = null; 90 } 91 92 // ------------------------------------------------ Individual Test Methods 93 94 /** 95 * General Tests 96 */ testGeneral()97 public void testGeneral() { 98 // LazyDynaMap bean = new LazyDynaMap("TestBean"); 99 assertEquals("Check DynaClass name", "TestBean", new LazyDynaMap("TestBean").getName()); 100 101 } 102 103 /** 104 * Test Getting/Setting a Simple Property 105 */ testSimpleProperty()106 public void testSimpleProperty() { 107 108 // Check the property & value doesn't exist 109 assertNull("Check Property doesn't exist", dynaMap.getDynaProperty(testProperty)); 110 assertNull("Check Value is null", dynaMap.get(testProperty)); 111 112 // Set a new property - should add new property and set value 113 dynaMap.set(testProperty, testInteger1); 114 assertEquals("Check First Value is correct", testInteger1, dynaMap.get(testProperty)); 115 assertEquals("Check Property type is correct", Integer.class, dynaMap.getDynaProperty(testProperty).getType()); 116 117 // Set the property again - should set the new value 118 dynaMap.set(testProperty, testInteger2); 119 assertEquals("Check Second Value is correct", testInteger2, dynaMap.get(testProperty)); 120 121 // Set the property again - with a different type, should succeed 122 dynaMap.set(testProperty, testString1); 123 assertEquals("Check Third Value is correct", testString1, dynaMap.get(testProperty)); 124 125 } 126 127 /** 128 * Test Setting a Simple Property when MutableDynaClass is set to restricted 129 */ testSimplePropertyRestricted()130 public void testSimplePropertyRestricted() { 131 132 // Set the MutableDyanClass to 'restricted' (i.e. no new properties cab be added 133 dynaMap.setRestricted(true); 134 assertTrue("Check MutableDynaClass is restricted", dynaMap.isRestricted()); 135 136 // Check the property & value doesn't exist 137 assertNull("Check Property doesn't exist", dynaMap.getDynaProperty(testProperty)); 138 assertNull("Check Value is null", dynaMap.get(testProperty)); 139 140 // Set the property - should fail because property doesn't exist and MutableDynaClass is restricted 141 try { 142 dynaMap.set(testProperty, testString1); 143 fail("expected IllegalArgumentException trying to add new property to restricted DynaClass"); 144 } catch (final IllegalArgumentException expected) { 145 // expected result 146 } 147 148 } 149 150 /** 151 * Test Getting/Setting a 'Mapped' Property - default HashMap property 152 */ testMappedPropertyDefault()153 public void testMappedPropertyDefault() { 154 155 // Check the property & value doesn't exist 156 assertNull("Check Mapped Property doesn't exist", dynaMap.getDynaProperty(testProperty)); 157 assertNull("Check Map is null", dynaMap.get(testProperty)); 158 assertNull("Check Mapped Value is null", dynaMap.get(testProperty, testKey)); 159 160 // Set a new mapped property - should add new HashMap property and set the mapped value 161 dynaMap.set(testProperty, testKey, testInteger1); 162 assertEquals("Check Mapped Property exists", HashMap.class, dynaMap.get(testProperty).getClass()); 163 assertEquals("Check First Mapped Value is correct(a)", testInteger1, dynaMap.get(testProperty, testKey)); 164 assertEquals("Check First Mapped Value is correct(b)", testInteger1, ((HashMap<?, ?>)dynaMap.get(testProperty)).get(testKey)); 165 166 // Set the property again - should set the new value 167 dynaMap.set(testProperty, testKey, testInteger2); 168 assertEquals("Check Second Mapped Value is correct(a)", testInteger2, dynaMap.get(testProperty, testKey)); 169 assertEquals("Check Second Mapped Value is correct(b)", testInteger2, ((HashMap<?, ?>)dynaMap.get(testProperty)).get(testKey)); 170 } 171 172 /** 173 * Test Getting/Setting a 'Mapped' Property - use TreeMap property 174 */ testMappedPropertyTreeMap()175 public void testMappedPropertyTreeMap() { 176 177 // Check the property & value doesn't exist 178 assertNull("Check Mapped Property doesn't exist", dynaMap.getDynaProperty(testProperty)); 179 assertNull("Check Map is null", dynaMap.get(testProperty)); 180 181 // Add a 'TreeMap' property to the DynaClass 182 dynaMap.add(testProperty, TreeMap.class); 183 assertTrue("Check Property is mapped", dynaMap.getDynaProperty(testProperty).isMapped()); 184 assertEquals("Check Property is correct type", TreeMap.class, dynaMap.getDynaProperty(testProperty).getType()); 185 assertEquals("Check Mapped Property now exists", TreeMap.class, dynaMap.get(testProperty).getClass()); 186 187 // Set a new mapped property - should instatiate a new TreeMap property and set the mapped value 188 dynaMap.set(testProperty, testKey, testInteger1); 189 assertEquals("Check Mapped Property exists", TreeMap.class, dynaMap.get(testProperty).getClass()); 190 assertEquals("Check First Mapped Value is correct(a)", testInteger1, dynaMap.get(testProperty, testKey)); 191 assertEquals("Check First Mapped Value is correct(b)", testInteger1, ((TreeMap<?, ?>)dynaMap.get(testProperty)).get(testKey)); 192 193 // Set the property again - should set the new value 194 dynaMap.set(testProperty, testKey, testInteger2); 195 assertEquals("Check Second Mapped Value is correct(a)", testInteger2, dynaMap.get(testProperty, testKey)); 196 assertEquals("Check Second Mapped Value is correct(b)", testInteger2, ((TreeMap<?, ?>)dynaMap.get(testProperty)).get(testKey)); 197 } 198 199 /** 200 * Test Setting a 'Mapped' Property using PropertyUtils 201 */ testMappedPropertyUtils()202 public void testMappedPropertyUtils() { 203 204 dynaMap.setReturnNull(false); 205 206 // Check the property & value doesn't exist 207 assertFalse("Check Mapped Property doesn't exist", dynaMap.isDynaProperty(testProperty)); 208 assertNull("Check Map is null", dynaMap.get(testProperty)); 209 assertNull("Check Mapped Value is null", dynaMap.get(testProperty, testKey)); 210 211 // Set the mapped property using PropertyUtils 212 try { 213 PropertyUtils.setProperty(dynaMap, testProperty+"("+testKey+")", testString1); 214 } 215 catch (final NoSuchMethodException ex) { 216 fail("testIndexedPropertyUtils threw "+ex); 217 } 218 catch (final InvocationTargetException ex) { 219 fail("testIndexedPropertyUtils threw "+ex); 220 } 221 catch (final IllegalAccessException ex) { 222 fail("testIndexedPropertyUtils threw "+ex); 223 } 224 225 // Check property value correctly set 226 assertEquals("Check Mapped Bean Value is correct", testString1, dynaMap.get(testProperty, testKey)); 227 228 } 229 230 /** 231 * Test Setting a Mapped Property when MutableDynaClass is set to restricted 232 */ testMappedPropertyRestricted()233 public void testMappedPropertyRestricted() { 234 235 // Set the MutableDyanClass to 'restricted' (i.e. no new properties cab be added 236 dynaMap.setRestricted(true); 237 assertTrue("Check MutableDynaClass is restricted", dynaMap.isRestricted()); 238 239 // Check the property & value doesn't exist 240 assertNull("Check Property doesn't exist", dynaMap.getDynaProperty(testProperty)); 241 assertNull("Check Value is null", dynaMap.get(testProperty)); 242 243 // Set the property - should fail because property doesn't exist and MutableDynaClass is restricted 244 try { 245 dynaMap.set(testProperty, testKey, testInteger1); 246 fail("expected IllegalArgumentException trying to add new property to restricted MutableDynaClass"); 247 } catch (final IllegalArgumentException expected) { 248 // expected result 249 } 250 251 } 252 253 /** 254 * Test setting mapped property for type which is not Map 255 */ testMappedInvalidType()256 public void testMappedInvalidType() { 257 dynaMap.set(testProperty, new Integer(1)); 258 assertFalse("Check Property is not mapped", dynaMap.getDynaProperty(testProperty).isMapped()); 259 try { 260 dynaMap.set(testProperty, testKey, testInteger1); 261 fail("set(property, key, value) should have thrown IllegalArgumentException"); 262 } catch (final IllegalArgumentException expected) { 263 // expected result 264 } 265 } 266 267 /** 268 * Test Getting/Setting an 'Indexed' Property - default ArrayList property 269 */ testIndexedPropertyDefault()270 public void testIndexedPropertyDefault() { 271 272 int index = 3; 273 274 // Check the property & value doesn't exist 275 assertNull("Check Indexed Property doesn't exist", dynaMap.getDynaProperty(testProperty)); 276 assertNull("Check Indexed Property is null", dynaMap.get(testProperty)); 277 assertNull("Check Indexed value is null", dynaMap.get(testProperty, index)); 278 279 // Set the property, should create new ArrayList and set appropriate indexed value 280 dynaMap.set(testProperty, index, testInteger1); 281 assertNotNull("Check Indexed Property is not null", dynaMap.get(testProperty)); 282 assertEquals("Check Indexed Property is correct type", ArrayList.class, dynaMap.get(testProperty).getClass()); 283 assertEquals("Check First Indexed Value is correct", testInteger1, dynaMap.get(testProperty, index)); 284 assertEquals("Check First Array length is correct", new Integer(index+1), new Integer(((ArrayList<?>)dynaMap.get(testProperty)).size())); 285 286 // Set a second indexed value, should automatically grow the ArrayList and set appropriate indexed value 287 index = index + 2; 288 dynaMap.set(testProperty, index, testString1); 289 assertEquals("Check Second Indexed Value is correct", testString1, dynaMap.get(testProperty, index)); 290 assertEquals("Check Second Array length is correct", new Integer(index+1), new Integer(((ArrayList<?>)dynaMap.get(testProperty)).size())); 291 } 292 293 /** 294 * Test Getting/Setting a List 'Indexed' Property - use alternative List (LinkedList) 295 */ testIndexedLinkedList()296 public void testIndexedLinkedList() { 297 298 int index = 3; 299 300 // Check the property & value doesn't exist 301 assertNull("Check Indexed Property doesn't exist", dynaMap.getDynaProperty(testProperty)); 302 assertNull("Check Indexed Property is null", dynaMap.get(testProperty)); 303 304 // Add a 'LinkedList' property to the DynaClass - should instantiate a new LinkedList 305 dynaMap.add(testProperty, LinkedList.class); 306 assertTrue("Check Property is indexed", dynaMap.getDynaProperty(testProperty).isIndexed()); 307 assertEquals("Check Property is correct type", LinkedList.class, dynaMap.getDynaProperty(testProperty).getType()); 308 assertEquals("Check Indexed Property now exists", LinkedList.class, dynaMap.get(testProperty).getClass()); 309 310 // Set the Indexed property, should grow the list to the correct size 311 dynaMap.set(testProperty, index, testString1); 312 assertEquals("Check Property type is correct", LinkedList.class, dynaMap.get(testProperty).getClass()); 313 assertEquals("Check First Indexed Value is correct", testString1, dynaMap.get(testProperty, index)); 314 assertEquals("Check First Array length is correct", new Integer(index+1), new Integer(((LinkedList<?>)dynaMap.get(testProperty)).size())); 315 316 // Set a second indexed value, should automatically grow the LinkedList and set appropriate indexed value 317 index = index + 2; 318 dynaMap.set(testProperty, index, testInteger1); 319 assertEquals("Check Second Indexed Value is correct", testInteger1, dynaMap.get(testProperty, index)); 320 assertEquals("Check Second Array length is correct", new Integer(index+1), new Integer(((LinkedList<?>)dynaMap.get(testProperty)).size())); 321 } 322 323 /** 324 * Test Getting/Setting a primitive array 'Indexed' Property - use int[] 325 */ testIndexedPrimitiveArray()326 public void testIndexedPrimitiveArray() { 327 328 int index = 3; 329 final int[] primitiveArray = new int[0]; 330 331 // Check the property & value doesn't exist 332 assertNull("Check Indexed Property doesn't exist", dynaMap.getDynaProperty(testProperty)); 333 assertNull("Check Indexed Property is null", dynaMap.get(testProperty)); 334 335 // Add a DynaProperty of type int[] 336 dynaMap.add(testProperty, primitiveArray.getClass()); 337 assertEquals("Check Indexed Property exists", primitiveArray.getClass(), dynaMap.getDynaProperty(testProperty).getType()); 338 assertTrue("Check Indexed Property exists", dynaMap.get(testProperty).getClass().isInstance(primitiveArray)); 339 340 // Set an indexed value 341 dynaMap.set(testProperty, index, testInteger1); 342 assertNotNull("Check Indexed Property is not null", dynaMap.get(testProperty)); 343 assertEquals("Check Indexed Property is correct type", primitiveArray.getClass(), dynaMap.get(testProperty).getClass()); 344 assertEquals("Check First Indexed Value is correct(a)", testInteger1, dynaMap.get(testProperty, index)); 345 assertEquals("Check First Indexed Value is correct(b)", testInteger1, new Integer(((int[])dynaMap.get(testProperty))[index])); 346 assertEquals("Check Array length is correct", new Integer(index+1), new Integer(((int[])dynaMap.get(testProperty)).length)); 347 348 // Set a second indexed value, should automatically grow the int[] and set appropriate indexed value 349 index = index + 2; 350 dynaMap.set(testProperty, index, testInteger2); 351 assertEquals("Check Second Indexed Value is correct(a)", testInteger2, dynaMap.get(testProperty, index)); 352 assertEquals("Check Second Indexed Value is correct(b)", testInteger2, new Integer(((int[])dynaMap.get(testProperty))[index])); 353 assertEquals("Check Second Array length is correct", new Integer(index+1), new Integer(((int[])dynaMap.get(testProperty)).length)); 354 355 } 356 357 /** 358 * Test Getting/Setting an Object array 'Indexed' Property - use String[] 359 */ testIndexedObjectArray()360 public void testIndexedObjectArray() { 361 362 int index = 3; 363 final Object objectArray = new String[0]; 364 365 // Check the property & value doesn't exist 366 assertNull("Check Indexed Property doesn't exist", dynaMap.getDynaProperty(testProperty)); 367 assertNull("Check Indexed Property is null", dynaMap.get(testProperty)); 368 369 // Add a DynaProperty of type String[] 370 dynaMap.add(testProperty, objectArray.getClass()); 371 assertEquals("Check Indexed Property exists", objectArray.getClass(), dynaMap.getDynaProperty(testProperty).getType()); 372 assertTrue("Check Indexed Property exists", dynaMap.get(testProperty).getClass().isInstance(objectArray)); 373 374 // Set an indexed value 375 dynaMap.set(testProperty, index, testString1); 376 assertNotNull("Check Indexed Property is not null", dynaMap.get(testProperty)); 377 assertEquals("Check Indexed Property is correct type", objectArray.getClass(), dynaMap.get(testProperty).getClass()); 378 assertEquals("Check First Indexed Value is correct(a)", testString1, dynaMap.get(testProperty, index)); 379 assertEquals("Check First Indexed Value is correct(b)", testString1, ((String[])dynaMap.get(testProperty))[index]); 380 assertEquals("Check Array length is correct", new Integer(index+1), new Integer(((String[])dynaMap.get(testProperty)).length)); 381 382 // Set a second indexed value, should automatically grow the String[] and set appropriate indexed value 383 index = index + 2; 384 dynaMap.set(testProperty, index, testString2); 385 assertEquals("Check Second Indexed Value is correct(a)", testString2, dynaMap.get(testProperty, index)); 386 assertEquals("Check Second Indexed Value is correct(b)", testString2, ((String[])dynaMap.get(testProperty))[index]); 387 assertEquals("Check Second Array length is correct", new Integer(index+1), new Integer(((String[])dynaMap.get(testProperty)).length)); 388 } 389 390 /** 391 * Test Getting/Setting an DynaBean[] array 392 */ testIndexedDynaBeanArray()393 public void testIndexedDynaBeanArray() { 394 395 final int index = 3; 396 final Object objectArray = new LazyDynaBean[0]; 397 398 // Check the property & value doesn't exist 399 assertNull("Check Indexed Property doesn't exist", dynaMap.getDynaProperty(testProperty)); 400 assertNull("Check Indexed Property is null", dynaMap.get(testProperty)); 401 402 // Add a DynaProperty of type String[] 403 dynaMap.add(testProperty, objectArray.getClass()); 404 assertEquals("Check Indexed Property exists", objectArray.getClass(), dynaMap.getDynaProperty(testProperty).getType()); 405 assertEquals("Check Indexed Property is correct type", objectArray.getClass(), dynaMap.get(testProperty).getClass()); 406 407 // Retrieving from Array should initialize DynaBean 408 for (int i = index; i >= 0; i--) { 409 assertEquals("Check Array Components initialized", LazyDynaBean.class, dynaMap.get(testProperty, index).getClass()); 410 } 411 412 dynaMap.add(testPropertyB, objectArray.getClass()); 413 final LazyDynaBean newBean = new LazyDynaBean(); 414 newBean.set(testPropertyB, testString2); 415 dynaMap.set(testPropertyA, index, newBean); 416 assertEquals("Check Indexed Value is correct(a)", testString2, ((DynaBean)dynaMap.get(testPropertyA, index)).get(testPropertyB)); 417 418 } 419 420 /** 421 * Test Setting an 'Indexed' Property using PropertyUtils 422 */ testIndexedPropertyUtils()423 public void testIndexedPropertyUtils() { 424 425 final int index = 3; 426 dynaMap.setReturnNull(false); 427 428 // Check the property & value doesn't exist 429 assertFalse("Check Indexed Property doesn't exist", dynaMap.isDynaProperty(testProperty)); 430 assertNull("Check Indexed Property is null", dynaMap.get(testProperty)); 431 assertNull("Check Indexed value is null", dynaMap.get(testProperty, index)); 432 433 // Use PropertyUtils to set the indexed value 434 try { 435 PropertyUtils.setProperty(dynaMap, testProperty+"["+index+"]", testString1); 436 } 437 catch (final NoSuchMethodException ex) { 438 fail("testIndexedPropertyUtils threw "+ex); 439 } 440 catch (final InvocationTargetException ex) { 441 fail("testIndexedPropertyUtils threw "+ex); 442 } 443 catch (final IllegalAccessException ex) { 444 fail("testIndexedPropertyUtils threw "+ex); 445 } 446 447 // Check property value correctly set 448 assertEquals("Check Indexed Bean Value is correct", testString1, dynaMap.get(testProperty, index)); 449 450 } 451 452 /** 453 * Test Setting an Indexed Property when MutableDynaClass is set to restricted 454 */ testIndexedPropertyRestricted()455 public void testIndexedPropertyRestricted() { 456 457 final int index = 3; 458 459 // Set the MutableDyanClass to 'restricted' (i.e. no new properties cab be added 460 dynaMap.setRestricted(true); 461 assertTrue("Check MutableDynaClass is restricted", dynaMap.isRestricted()); 462 463 // Check the property & value doesn't exist 464 assertNull("Check Property doesn't exist", dynaMap.getDynaProperty(testProperty)); 465 assertNull("Check Value is null", dynaMap.get(testProperty)); 466 467 // Set the property - should fail because property doesn't exist and MutableDynaClass is restricted 468 try { 469 dynaMap.set(testProperty, index, testInteger1); 470 fail("expected IllegalArgumentException trying to add new property to restricted MutableDynaClass"); 471 } catch (final IllegalArgumentException expected) { 472 // expected result 473 } 474 475 } 476 477 /** 478 * Test setting indexed property for type which is not List or Array 479 */ testIndexedInvalidType()480 public void testIndexedInvalidType() { 481 final int index = 3; 482 dynaMap.set(testProperty, "Test String"); 483 assertFalse("Check Property is not indexed", dynaMap.getDynaProperty(testProperty).isIndexed()); 484 try { 485 dynaMap.set(testProperty, index, testString1); 486 fail("set(property, index, value) should have thrown IllegalArgumentException"); 487 } catch (final IllegalArgumentException expected) { 488 // expected result 489 } 490 } 491 492 /** 493 * Test creating using DynaClass.newInstance() 494 */ testNewInstance()495 public void testNewInstance() { 496 497 // Create LazyDynaMap using TreeMap 498 // containing some properties 499 final LazyDynaMap orig = new LazyDynaMap(new TreeMap<String, Object>()); 500 orig.set("indexProp", 0, "indexVal0"); 501 orig.set("indexProp", 1, "indexVal1"); 502 assertEquals("Index prop size", 2, ((List<?>)orig.get("indexProp")).size()); 503 504 final LazyDynaMap newOne = (LazyDynaMap)orig.newInstance(); 505 final Map<String, Object> newMap = newOne.getMap(); 506 assertEquals("Check Map type", TreeMap.class, newMap.getClass()); 507 508 final ArrayList<?> indexProp = (ArrayList<?>)newMap.get("indexProp"); 509 assertNotNull("Indexed Prop missing", indexProp); 510 assertEquals("Index prop size", 0, indexProp.size()); 511 } 512 513 }