001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.beanutils;
018:
019: import java.util.Map;
020: import java.util.HashMap;
021: import java.util.TreeMap;
022: import java.util.List;
023: import java.util.ArrayList;
024: import java.util.LinkedList;
025: import java.lang.reflect.InvocationTargetException;
026: import junit.framework.TestCase;
027: import junit.framework.Test;
028: import junit.framework.TestSuite;
029:
030: /**
031: * <p>Test Case for the <code>LazyDynaMap</code> implementation class.</p>
032: *
033: * @author Niall Pemberton
034: */
035: public class LazyDynaMapTestCase extends TestCase {
036:
037: protected LazyDynaMap dynaMap = null;
038: protected String testProperty = "myProperty";
039: protected String testPropertyA = "myProperty-A";
040: protected String testPropertyB = "myProperty-B";
041: protected String testString1 = "myStringValue-1";
042: protected String testString2 = "myStringValue-2";
043: protected Integer testInteger1 = new Integer(30);
044: protected Integer testInteger2 = new Integer(40);
045: protected String testKey = "myKey";
046:
047: // ---------------------------------------------------------- Constructors
048:
049: /**
050: * Construct a new instance of this test case.
051: *
052: * @param name Name of the test case
053: */
054: public LazyDynaMapTestCase(String name) {
055: super (name);
056: }
057:
058: // -------------------------------------------------- Overall Test Methods
059:
060: /**
061: * Run thus Test
062: */
063: public static void main(String[] args) {
064: junit.textui.TestRunner.run(suite());
065: }
066:
067: /**
068: * Return the tests included in this test suite.
069: */
070: public static Test suite() {
071: return (new TestSuite(LazyDynaMapTestCase.class));
072: }
073:
074: /**
075: * Set up instance variables required by this test case.
076: */
077: public void setUp() throws Exception {
078: dynaMap = new LazyDynaMap();
079: dynaMap.setReturnNull(true);
080: }
081:
082: /**
083: * Tear down instance variables required by this test case.
084: */
085: public void tearDown() {
086: dynaMap = null;
087: }
088:
089: // ------------------------------------------------ Individual Test Methods
090:
091: /**
092: * General Tests
093: */
094: public void testGeneral() {
095: // LazyDynaMap bean = new LazyDynaMap("TestBean");
096: assertEquals("Check DynaClass name", "TestBean",
097: new LazyDynaMap("TestBean").getName());
098:
099: }
100:
101: /**
102: * Test Getting/Setting a Simple Property
103: */
104: public void testSimpleProperty() {
105:
106: // Check the property & value doesn't exist
107: assertNull("Check Property doesn't exist", dynaMap
108: .getDynaProperty(testProperty));
109: assertNull("Check Value is null", dynaMap.get(testProperty));
110:
111: // Set a new property - should add new property and set value
112: dynaMap.set(testProperty, testInteger1);
113: assertEquals("Check First Value is correct", testInteger1,
114: dynaMap.get(testProperty));
115: assertEquals("Check Property type is correct", Integer.class,
116: dynaMap.getDynaProperty(testProperty).getType());
117:
118: // Set the property again - should set the new value
119: dynaMap.set(testProperty, testInteger2);
120: assertEquals("Check Second Value is correct", testInteger2,
121: dynaMap.get(testProperty));
122:
123: // Set the property again - with a different type, should succeed
124: dynaMap.set(testProperty, testString1);
125: assertEquals("Check Third Value is correct", testString1,
126: dynaMap.get(testProperty));
127:
128: }
129:
130: /**
131: * Test Setting a Simple Property when MutableDynaClass is set to restricted
132: */
133: public void testSimplePropertyRestricted() {
134:
135: // Set the MutableDyanClass to 'restricted' (i.e. no new properties cab be added
136: dynaMap.setRestricted(true);
137: assertTrue("Check MutableDynaClass is restricted", dynaMap
138: .isRestricted());
139:
140: // Check the property & value doesn't exist
141: assertNull("Check Property doesn't exist", dynaMap
142: .getDynaProperty(testProperty));
143: assertNull("Check Value is null", dynaMap.get(testProperty));
144:
145: // Set the property - should fail because property doesn't exist and MutableDynaClass is restricted
146: try {
147: dynaMap.set(testProperty, testString1);
148: fail("expected IllegalArgumentException trying to add new property to restricted DynaClass");
149: } catch (IllegalArgumentException expected) {
150: // expected result
151: }
152:
153: }
154:
155: /**
156: * Test Getting/Setting a 'Mapped' Property - default HashMap property
157: */
158: public void testMappedPropertyDefault() {
159:
160: // Check the property & value doesn't exist
161: assertNull("Check Mapped Property doesn't exist", dynaMap
162: .getDynaProperty(testProperty));
163: assertNull("Check Map is null", dynaMap.get(testProperty));
164: assertNull("Check Mapped Value is null", dynaMap.get(
165: testProperty, testKey));
166:
167: // Set a new mapped property - should add new HashMap property and set the mapped value
168: dynaMap.set(testProperty, testKey, testInteger1);
169: assertEquals("Check Mapped Property exists", HashMap.class,
170: dynaMap.get(testProperty).getClass());
171: assertEquals("Check First Mapped Value is correct(a)",
172: testInteger1, dynaMap.get(testProperty, testKey));
173: assertEquals("Check First Mapped Value is correct(b)",
174: testInteger1, ((HashMap) dynaMap.get(testProperty))
175: .get(testKey));
176:
177: // Set the property again - should set the new value
178: dynaMap.set(testProperty, testKey, testInteger2);
179: assertEquals("Check Second Mapped Value is correct(a)",
180: testInteger2, dynaMap.get(testProperty, testKey));
181: assertEquals("Check Second Mapped Value is correct(b)",
182: testInteger2, ((HashMap) dynaMap.get(testProperty))
183: .get(testKey));
184: }
185:
186: /**
187: * Test Getting/Setting a 'Mapped' Property - use TreeMap property
188: */
189: public void testMappedPropertyTreeMap() {
190:
191: // Check the property & value doesn't exist
192: assertNull("Check Mapped Property doesn't exist", dynaMap
193: .getDynaProperty(testProperty));
194: assertNull("Check Map is null", dynaMap.get(testProperty));
195:
196: // Add a 'TreeMap' property to the DynaClass
197: dynaMap.add(testProperty, TreeMap.class);
198: assertTrue("Check Property is mapped", dynaMap.getDynaProperty(
199: testProperty).isMapped());
200: assertEquals("Check Property is correct type", TreeMap.class,
201: dynaMap.getDynaProperty(testProperty).getType());
202: assertEquals("Check Mapped Property now exists", TreeMap.class,
203: dynaMap.get(testProperty).getClass());
204:
205: // Set a new mapped property - should instatiate a new TreeMap property and set the mapped value
206: dynaMap.set(testProperty, testKey, testInteger1);
207: assertEquals("Check Mapped Property exists", TreeMap.class,
208: dynaMap.get(testProperty).getClass());
209: assertEquals("Check First Mapped Value is correct(a)",
210: testInteger1, dynaMap.get(testProperty, testKey));
211: assertEquals("Check First Mapped Value is correct(b)",
212: testInteger1, ((TreeMap) dynaMap.get(testProperty))
213: .get(testKey));
214:
215: // Set the property again - should set the new value
216: dynaMap.set(testProperty, testKey, testInteger2);
217: assertEquals("Check Second Mapped Value is correct(a)",
218: testInteger2, dynaMap.get(testProperty, testKey));
219: assertEquals("Check Second Mapped Value is correct(b)",
220: testInteger2, ((TreeMap) dynaMap.get(testProperty))
221: .get(testKey));
222: }
223:
224: /**
225: * Test Setting a 'Mapped' Property using PropertyUtils
226: */
227: public void testMappedPropertyUtils() {
228:
229: dynaMap.setReturnNull(false);
230:
231: // Check the property & value doesn't exist
232: assertFalse("Check Mapped Property doesn't exist", dynaMap
233: .isDynaProperty(testProperty));
234: assertNull("Check Map is null", dynaMap.get(testProperty));
235: assertNull("Check Mapped Value is null", dynaMap.get(
236: testProperty, testKey));
237:
238: // Set the mapped property using PropertyUtils
239: try {
240: PropertyUtils.setProperty(dynaMap, testProperty + "("
241: + testKey + ")", testString1);
242: } catch (NoSuchMethodException ex) {
243: fail("testIndexedPropertyUtils threw " + ex);
244: } catch (InvocationTargetException ex) {
245: fail("testIndexedPropertyUtils threw " + ex);
246: } catch (IllegalAccessException ex) {
247: fail("testIndexedPropertyUtils threw " + ex);
248: }
249:
250: // Check property value correctly set
251: assertEquals("Check Mapped Bean Value is correct", testString1,
252: dynaMap.get(testProperty, testKey));
253:
254: }
255:
256: /**
257: * Test Setting a Mapped Property when MutableDynaClass is set to restricted
258: */
259: public void testMappedPropertyRestricted() {
260:
261: // Set the MutableDyanClass to 'restricted' (i.e. no new properties cab be added
262: dynaMap.setRestricted(true);
263: assertTrue("Check MutableDynaClass is restricted", dynaMap
264: .isRestricted());
265:
266: // Check the property & value doesn't exist
267: assertNull("Check Property doesn't exist", dynaMap
268: .getDynaProperty(testProperty));
269: assertNull("Check Value is null", dynaMap.get(testProperty));
270:
271: // Set the property - should fail because property doesn't exist and MutableDynaClass is restricted
272: try {
273: dynaMap.set(testProperty, testKey, testInteger1);
274: fail("expected IllegalArgumentException trying to add new property to restricted MutableDynaClass");
275: } catch (IllegalArgumentException expected) {
276: // expected result
277: }
278:
279: }
280:
281: /**
282: * Test setting mapped property for type which is not Map
283: */
284: public void testMappedInvalidType() {
285: dynaMap.set(testProperty, new Integer(1));
286: assertFalse("Check Property is not mapped", dynaMap
287: .getDynaProperty(testProperty).isMapped());
288: try {
289: dynaMap.set(testProperty, testKey, testInteger1);
290: fail("set(property, key, value) should have thrown IllegalArgumentException");
291: } catch (IllegalArgumentException expected) {
292: // expected result
293: }
294: }
295:
296: /**
297: * Test Getting/Setting an 'Indexed' Property - default ArrayList property
298: */
299: public void testIndexedPropertyDefault() {
300:
301: int index = 3;
302:
303: // Check the property & value doesn't exist
304: assertNull("Check Indexed Property doesn't exist", dynaMap
305: .getDynaProperty(testProperty));
306: assertNull("Check Indexed Property is null", dynaMap
307: .get(testProperty));
308: assertNull("Check Indexed value is null", dynaMap.get(
309: testProperty, index));
310:
311: // Set the property, should create new ArrayList and set appropriate indexed value
312: dynaMap.set(testProperty, index, testInteger1);
313: assertNotNull("Check Indexed Property is not null", dynaMap
314: .get(testProperty));
315: assertEquals("Check Indexed Property is correct type",
316: ArrayList.class, dynaMap.get(testProperty).getClass());
317: assertEquals("Check First Indexed Value is correct",
318: testInteger1, dynaMap.get(testProperty, index));
319: assertEquals("Check First Array length is correct",
320: new Integer(index + 1), new Integer(
321: ((ArrayList) dynaMap.get(testProperty)).size()));
322:
323: // Set a second indexed value, should automatically grow the ArrayList and set appropriate indexed value
324: index = index + 2;
325: dynaMap.set(testProperty, index, testString1);
326: assertEquals("Check Second Indexed Value is correct",
327: testString1, dynaMap.get(testProperty, index));
328: assertEquals("Check Second Array length is correct",
329: new Integer(index + 1), new Integer(
330: ((ArrayList) dynaMap.get(testProperty)).size()));
331: }
332:
333: /**
334: * Test Getting/Setting a List 'Indexed' Property - use alternative List (LinkedList)
335: */
336: public void testIndexedLinkedList() {
337:
338: int index = 3;
339:
340: // Check the property & value doesn't exist
341: assertNull("Check Indexed Property doesn't exist", dynaMap
342: .getDynaProperty(testProperty));
343: assertNull("Check Indexed Property is null", dynaMap
344: .get(testProperty));
345:
346: // Add a 'LinkedList' property to the DynaClass - should instantiate a new LinkedList
347: dynaMap.add(testProperty, LinkedList.class);
348: assertTrue("Check Property is indexed", dynaMap
349: .getDynaProperty(testProperty).isIndexed());
350: assertEquals("Check Property is correct type",
351: LinkedList.class, dynaMap.getDynaProperty(testProperty)
352: .getType());
353: assertEquals("Check Indexed Property now exists",
354: LinkedList.class, dynaMap.get(testProperty).getClass());
355:
356: // Set the Indexed property, should grow the list to the correct size
357: dynaMap.set(testProperty, index, testString1);
358: assertEquals("Check Property type is correct",
359: LinkedList.class, dynaMap.get(testProperty).getClass());
360: assertEquals("Check First Indexed Value is correct",
361: testString1, dynaMap.get(testProperty, index));
362: assertEquals("Check First Array length is correct",
363: new Integer(index + 1),
364: new Integer(((LinkedList) dynaMap.get(testProperty))
365: .size()));
366:
367: // Set a second indexed value, should automatically grow the LinkedList and set appropriate indexed value
368: index = index + 2;
369: dynaMap.set(testProperty, index, testInteger1);
370: assertEquals("Check Second Indexed Value is correct",
371: testInteger1, dynaMap.get(testProperty, index));
372: assertEquals("Check Second Array length is correct",
373: new Integer(index + 1),
374: new Integer(((LinkedList) dynaMap.get(testProperty))
375: .size()));
376: }
377:
378: /**
379: * Test Getting/Setting a primitive array 'Indexed' Property - use int[]
380: */
381: public void testIndexedPrimitiveArray() {
382:
383: int index = 3;
384: int[] primitiveArray = new int[0];
385:
386: // Check the property & value doesn't exist
387: assertNull("Check Indexed Property doesn't exist", dynaMap
388: .getDynaProperty(testProperty));
389: assertNull("Check Indexed Property is null", dynaMap
390: .get(testProperty));
391:
392: // Add a DynaProperty of type int[]
393: dynaMap.add(testProperty, primitiveArray.getClass());
394: assertEquals("Check Indexed Property exists", primitiveArray
395: .getClass(), dynaMap.getDynaProperty(testProperty)
396: .getType());
397: assertTrue("Check Indexed Property exists", dynaMap.get(
398: testProperty).getClass().isInstance(primitiveArray));
399:
400: // Set an indexed value
401: dynaMap.set(testProperty, index, testInteger1);
402: assertNotNull("Check Indexed Property is not null", dynaMap
403: .get(testProperty));
404: assertEquals("Check Indexed Property is correct type",
405: primitiveArray.getClass(), dynaMap.get(testProperty)
406: .getClass());
407: assertEquals("Check First Indexed Value is correct(a)",
408: testInteger1, dynaMap.get(testProperty, index));
409: assertEquals("Check First Indexed Value is correct(b)",
410: testInteger1, new Integer(((int[]) dynaMap
411: .get(testProperty))[index]));
412: assertEquals("Check Array length is correct", new Integer(
413: index + 1), new Integer(((int[]) dynaMap
414: .get(testProperty)).length));
415:
416: // Set a second indexed value, should automatically grow the int[] and set appropriate indexed value
417: index = index + 2;
418: dynaMap.set(testProperty, index, testInteger2);
419: assertEquals("Check Second Indexed Value is correct(a)",
420: testInteger2, dynaMap.get(testProperty, index));
421: assertEquals("Check Second Indexed Value is correct(b)",
422: testInteger2, new Integer(((int[]) dynaMap
423: .get(testProperty))[index]));
424: assertEquals("Check Second Array length is correct",
425: new Integer(index + 1), new Integer(((int[]) dynaMap
426: .get(testProperty)).length));
427:
428: }
429:
430: /**
431: * Test Getting/Setting an Object array 'Indexed' Property - use String[]
432: */
433: public void testIndexedObjectArray() {
434:
435: int index = 3;
436: Object objectArray = new String[0];
437:
438: // Check the property & value doesn't exist
439: assertNull("Check Indexed Property doesn't exist", dynaMap
440: .getDynaProperty(testProperty));
441: assertNull("Check Indexed Property is null", dynaMap
442: .get(testProperty));
443:
444: // Add a DynaProperty of type String[]
445: dynaMap.add(testProperty, objectArray.getClass());
446: assertEquals("Check Indexed Property exists", objectArray
447: .getClass(), dynaMap.getDynaProperty(testProperty)
448: .getType());
449: assertTrue("Check Indexed Property exists", dynaMap.get(
450: testProperty).getClass().isInstance(objectArray));
451:
452: // Set an indexed value
453: dynaMap.set(testProperty, index, testString1);
454: assertNotNull("Check Indexed Property is not null", dynaMap
455: .get(testProperty));
456: assertEquals("Check Indexed Property is correct type",
457: objectArray.getClass(), dynaMap.get(testProperty)
458: .getClass());
459: assertEquals("Check First Indexed Value is correct(a)",
460: testString1, dynaMap.get(testProperty, index));
461: assertEquals("Check First Indexed Value is correct(b)",
462: testString1,
463: ((String[]) dynaMap.get(testProperty))[index]);
464: assertEquals("Check Array length is correct", new Integer(
465: index + 1), new Integer(((String[]) dynaMap
466: .get(testProperty)).length));
467:
468: // Set a second indexed value, should automatically grow the String[] and set appropriate indexed value
469: index = index + 2;
470: dynaMap.set(testProperty, index, testString2);
471: assertEquals("Check Second Indexed Value is correct(a)",
472: testString2, dynaMap.get(testProperty, index));
473: assertEquals("Check Second Indexed Value is correct(b)",
474: testString2,
475: ((String[]) dynaMap.get(testProperty))[index]);
476: assertEquals("Check Second Array length is correct",
477: new Integer(index + 1), new Integer(((String[]) dynaMap
478: .get(testProperty)).length));
479: }
480:
481: /**
482: * Test Getting/Setting an DynaBean[] array
483: */
484: public void testIndexedDynaBeanArray() {
485:
486: int index = 3;
487: Object objectArray = new LazyDynaBean[0];
488:
489: // Check the property & value doesn't exist
490: assertNull("Check Indexed Property doesn't exist", dynaMap
491: .getDynaProperty(testProperty));
492: assertNull("Check Indexed Property is null", dynaMap
493: .get(testProperty));
494:
495: // Add a DynaProperty of type String[]
496: dynaMap.add(testProperty, objectArray.getClass());
497: assertEquals("Check Indexed Property exists", objectArray
498: .getClass(), dynaMap.getDynaProperty(testProperty)
499: .getType());
500: assertEquals("Check Indexed Property is correct type",
501: objectArray.getClass(), dynaMap.get(testProperty)
502: .getClass());
503:
504: // Retrieving from Array should initialize DynaBean
505: for (int i = index; i >= 0; i--) {
506: assertEquals("Check Array Components initialized",
507: LazyDynaBean.class, dynaMap
508: .get(testProperty, index).getClass());
509: }
510:
511: dynaMap.add(testPropertyB, objectArray.getClass());
512: LazyDynaBean newBean = new LazyDynaBean();
513: newBean.set(testPropertyB, testString2);
514: dynaMap.set(testPropertyA, index, newBean);
515: assertEquals("Check Indexed Value is correct(a)", testString2,
516: ((DynaBean) dynaMap.get(testPropertyA, index))
517: .get(testPropertyB));
518:
519: }
520:
521: /**
522: * Test Setting an 'Indexed' Property using PropertyUtils
523: */
524: public void testIndexedPropertyUtils() {
525:
526: int index = 3;
527: dynaMap.setReturnNull(false);
528:
529: // Check the property & value doesn't exist
530: assertFalse("Check Indexed Property doesn't exist", dynaMap
531: .isDynaProperty(testProperty));
532: assertNull("Check Indexed Property is null", dynaMap
533: .get(testProperty));
534: assertNull("Check Indexed value is null", dynaMap.get(
535: testProperty, index));
536:
537: // Use PropertyUtils to set the indexed value
538: try {
539: PropertyUtils.setProperty(dynaMap, testProperty + "["
540: + index + "]", testString1);
541: } catch (NoSuchMethodException ex) {
542: fail("testIndexedPropertyUtils threw " + ex);
543: } catch (InvocationTargetException ex) {
544: fail("testIndexedPropertyUtils threw " + ex);
545: } catch (IllegalAccessException ex) {
546: fail("testIndexedPropertyUtils threw " + ex);
547: }
548:
549: // Check property value correctly set
550: assertEquals("Check Indexed Bean Value is correct",
551: testString1, dynaMap.get(testProperty, index));
552:
553: }
554:
555: /**
556: * Test Setting an Indexed Property when MutableDynaClass is set to restricted
557: */
558: public void testIndexedPropertyRestricted() {
559:
560: int index = 3;
561:
562: // Set the MutableDyanClass to 'restricted' (i.e. no new properties cab be added
563: dynaMap.setRestricted(true);
564: assertTrue("Check MutableDynaClass is restricted", dynaMap
565: .isRestricted());
566:
567: // Check the property & value doesn't exist
568: assertNull("Check Property doesn't exist", dynaMap
569: .getDynaProperty(testProperty));
570: assertNull("Check Value is null", dynaMap.get(testProperty));
571:
572: // Set the property - should fail because property doesn't exist and MutableDynaClass is restricted
573: try {
574: dynaMap.set(testProperty, index, testInteger1);
575: fail("expected IllegalArgumentException trying to add new property to restricted MutableDynaClass");
576: } catch (IllegalArgumentException expected) {
577: // expected result
578: }
579:
580: }
581:
582: /**
583: * Test setting indexed property for type which is not List or Array
584: */
585: public void testIndexedInvalidType() {
586: int index = 3;
587: dynaMap.set(testProperty, "Test String");
588: assertFalse("Check Property is not indexed", dynaMap
589: .getDynaProperty(testProperty).isIndexed());
590: try {
591: dynaMap.set(testProperty, index, testString1);
592: fail("set(property, index, value) should have thrown IllegalArgumentException");
593: } catch (IllegalArgumentException expected) {
594: // expected result
595: }
596: }
597:
598: /**
599: * Test creating using DynaClass.newInstance()
600: */
601: public void testNewInstance() {
602:
603: // Create LazyDynaMap using TreeMap
604: // containing some properties
605: LazyDynaMap orig = new LazyDynaMap(new TreeMap());
606: orig.set("indexProp", 0, "indexVal0");
607: orig.set("indexProp", 1, "indexVal1");
608: assertEquals("Index prop size", 2, ((List) orig
609: .get("indexProp")).size());
610:
611: LazyDynaMap newOne = (LazyDynaMap) orig.newInstance();
612: Map newMap = newOne.getMap();
613: assertEquals("Check Map type", TreeMap.class, newMap.getClass());
614:
615: ArrayList indexProp = (ArrayList) newMap.get("indexProp");
616: assertNotNull("Indexed Prop missing", indexProp);
617: assertEquals("Index prop size", 0, indexProp.size());
618: }
619:
620: }
|