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