1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.configuration.beanutils;
19
20 import java.util.ArrayList;
21 import java.util.List;
22
23 import junit.framework.AssertionFailedError;
24 import junit.framework.TestCase;
25 import junitx.framework.ObjectAssert;
26 import org.apache.commons.beanutils.DynaProperty;
27 import org.apache.commons.configuration.BaseConfiguration;
28 import org.apache.commons.configuration.Configuration;
29
30 /***
31 * <p>Test Case for the <code>ConfigurationDynaBean</code> implementation class.
32 * These tests were based on the ones in <code>BasicDynaBeanTestCase</code>
33 * because the two classes provide similar levels of functionality.</p>
34 *
35 * @author <a href="mailto:ricardo.gladwell@btinternet.com">Ricardo Gladwell</a>
36 * @version $Revision: 447537 $
37 */
38 public class TestConfigurationDynaBean extends TestCase
39 {
40 /***
41 * The basic test bean for each test.
42 */
43 private ConfigurationDynaBean bean;
44
45 /***
46 * The set of property names we expect to have returned when calling
47 * <code>getDynaProperties()</code>. You should update this list
48 * when new properties are added to TestBean.
49 */
50 String[] properties = {
51 "booleanProperty",
52 "booleanSecond",
53 "doubleProperty",
54 "floatProperty",
55 "intProperty",
56 "longProperty",
57 "mappedProperty.key1",
58 "mappedProperty.key2",
59 "mappedProperty.key3",
60 "mappedIntProperty.key1",
61 "shortProperty",
62 "stringProperty",
63 "byteProperty",
64 "charProperty"
65 };
66
67 Object[] values = {
68 Boolean.TRUE,
69 Boolean.TRUE,
70 new Double(Double.MAX_VALUE),
71 new Float(Float.MAX_VALUE),
72 new Integer(Integer.MAX_VALUE),
73 new Long(Long.MAX_VALUE),
74 "First Value",
75 "Second Value",
76 "Third Value",
77 new Integer(Integer.MAX_VALUE),
78 new Short(Short.MAX_VALUE),
79 "This is a string",
80 new Byte(Byte.MAX_VALUE),
81 new Character(Character.MAX_VALUE)
82 };
83
84 int[] intArray = {0, 10, 20, 30, 40};
85 boolean[] booleanArray = {true, false, true, false, true};
86 char[] charArray = {'a', 'b', 'c', 'd', 'e'};
87 byte[] byteArray = {0, 10, 20, 30, 40};
88 long[] longArray = {0, 10, 20, 30, 40};
89 short[] shortArray = {0, 10, 20, 30, 40};
90 float[] floatArray = {0, 10, 20, 30, 40};
91 double[] doubleArray = {0.0, 10.0, 20.0, 30.0, 40.0};
92 String[] stringArray = {"String 0", "String 1", "String 2", "String 3", "String 4"};
93
94
95 /***
96 * Set up instance variables required by this test case.
97 */
98 public void setUp() throws Exception
99 {
100 Configuration configuration = createConfiguration();
101
102 for (int i = 0; i < properties.length; i++)
103 {
104 configuration.setProperty(properties[i], values[i]);
105 }
106
107 for (int a = 0; a < intArray.length; a++)
108 {
109 configuration.addProperty("intIndexed", new Integer(intArray[a]));
110 }
111
112 for (int a = 0; a < stringArray.length; a++)
113 {
114 configuration.addProperty("stringIndexed", stringArray[a]);
115 }
116
117 List list = new ArrayList();
118 for (int i = 0; i < stringArray.length; i++)
119 {
120 list.add(stringArray[i]);
121 }
122 configuration.addProperty("listIndexed", list);
123
124 bean = new ConfigurationDynaBean(configuration);
125
126 bean.set("listIndexed", list);
127 bean.set("intArray", intArray);
128 bean.set("booleanArray", booleanArray);
129 bean.set("charArray", charArray);
130 bean.set("longArray", longArray);
131 bean.set("shortArray", shortArray);
132 bean.set("floatArray", floatArray);
133 bean.set("doubleArray", doubleArray);
134 bean.set("byteArray", byteArray);
135 bean.set("stringArray", stringArray);
136 }
137
138 /***
139 * Creates the underlying configuration object for the dyna bean.
140 * @return the underlying configuration object
141 */
142 protected Configuration createConfiguration()
143 {
144 return new BaseConfiguration();
145 }
146
147 /***
148 * Corner cases on getDynaProperty invalid arguments.
149 */
150 public void testGetDescriptorArguments()
151 {
152 DynaProperty descriptor = bean.getDynaClass().getDynaProperty("unknown");
153 assertNull("Unknown property descriptor should be null", descriptor);
154
155 try
156 {
157 bean.getDynaClass().getDynaProperty(null);
158 fail("Should throw IllegalArgumentException");
159 }
160 catch (java.lang.IllegalArgumentException e)
161 {
162
163 }
164 catch (AssertionFailedError e)
165 {
166
167 }
168 catch (Throwable t)
169 {
170 fail("Threw '" + t + "' instead of 'IllegalArgumentException'");
171 }
172 }
173
174 /***
175 * Positive getDynaProperty on property <code>booleanProperty</code>.
176 */
177 public void testGetDescriptorBoolean()
178 {
179 testGetDescriptorBase("booleanProperty", Boolean.TYPE);
180 }
181
182 /***
183 * Positive getDynaProperty on property <code>doubleProperty</code>.
184 */
185 public void testGetDescriptorDouble()
186 {
187 testGetDescriptorBase("doubleProperty", Double.TYPE);
188 }
189
190 /***
191 * Positive getDynaProperty on property <code>floatProperty</code>.
192 */
193 public void testGetDescriptorFloat()
194 {
195 testGetDescriptorBase("floatProperty", Float.TYPE);
196 }
197
198 /***
199 * Positive getDynaProperty on property <code>intProperty</code>.
200 */
201 public void testGetDescriptorInt()
202 {
203 testGetDescriptorBase("intProperty", Integer.TYPE);
204 }
205
206 /***
207 * Positive getDynaProperty on property <code>longProperty</code>.
208 */
209 public void testGetDescriptorLong()
210 {
211 testGetDescriptorBase("longProperty", Long.TYPE);
212 }
213
214 /***
215 * Positive getDynaProperty on property <code>booleanSecond</code>
216 * that uses an "is" method as the getter.
217 */
218 public void testGetDescriptorSecond()
219 {
220 testGetDescriptorBase("booleanSecond", Boolean.TYPE);
221 }
222
223 /***
224 * Positive getDynaProperty on property <code>shortProperty</code>.
225 */
226 public void testGetDescriptorShort()
227 {
228 testGetDescriptorBase("shortProperty", Short.TYPE);
229 }
230
231 /***
232 * Positive getDynaProperty on property <code>stringProperty</code>.
233 */
234 public void testGetDescriptorString()
235 {
236 testGetDescriptorBase("stringProperty", String.class);
237 }
238
239 /***
240 * Positive test for getDynaPropertys(). Each property name
241 * listed in <code>properties</code> should be returned exactly once.
242 */
243 public void testGetDescriptors()
244 {
245 DynaProperty pd[] = bean.getDynaClass().getDynaProperties();
246 assertNotNull("Got descriptors", pd);
247 int count[] = new int[properties.length];
248 for (int i = 0; i < pd.length; i++)
249 {
250 String name = pd[i].getName();
251 for (int j = 0; j < properties.length; j++)
252 {
253 if (name.equals(properties[j]))
254 {
255 count[j]++;
256 }
257 }
258 }
259
260 for (int j = 0; j < properties.length; j++)
261 {
262 if (count[j] < 0)
263 {
264 fail("Missing property " + properties[j]);
265 }
266 else if (count[j] > 1)
267 {
268 fail("Duplicate property " + properties[j]);
269 }
270 }
271 }
272
273 /***
274 * Corner cases on getIndexedProperty invalid arguments.
275 */
276 public void testGetIndexedArguments()
277 {
278 try
279 {
280 bean.get("intArray", -1);
281 }
282 catch (IndexOutOfBoundsException e)
283 {
284 return;
285 }
286 catch (Throwable t)
287 {
288 fail("Threw '" + t + "' instead of 'IndexOutOfBoundsException'");
289 return;
290 }
291
292 fail("Should throw IndexOutOfBoundsException");
293 }
294
295 /***
296 * Positive and negative tests on getIndexedProperty valid arguments.
297 */
298 public void testGetIndexedValues()
299 {
300 for (int i = 0; i < 5; i++)
301 {
302 Object value = bean.get("intArray", i);
303
304 assertNotNull("intArray index " + i + " did not return value.", value);
305 ObjectAssert.assertInstanceOf("intArray index " + i, Integer.class, value);
306 assertEquals("intArray " + i + " returned incorrect value.", i * 10, ((Integer) value).intValue());
307
308 value = bean.get("intIndexed", i);
309
310 assertNotNull("intIndexed index " + i + "returned value " + i, value);
311 ObjectAssert.assertInstanceOf("intIndexed index " + i, Integer.class, value);
312 assertEquals("intIndexed index " + i + "returned correct " + i, i * 10, ((Integer) value).intValue());
313
314 value = bean.get("listIndexed", i);
315
316 assertNotNull("listIndexed index " + i + "returned value " + i, value);
317 ObjectAssert.assertInstanceOf("list index " + i, String.class, value);
318 assertEquals("listIndexed index " + i + "returned correct " + i, "String " + i, (String) value);
319
320 value = bean.get("stringArray", i);
321
322 assertNotNull("stringArray index " + i + " returnde null.", value);
323 assertFalse("stringArray index " + i + " returned array instead of String.", value.getClass().isArray());
324 ObjectAssert.assertInstanceOf("stringArray index " + i, String.class, value);
325 assertEquals("stringArray returned correct " + i, "String " + i, (String) value);
326
327 value = bean.get("stringIndexed", i);
328
329 assertNotNull("stringIndexed returned value " + i, value);
330 ObjectAssert.assertInstanceOf("stringIndexed", String.class, value);
331 assertEquals("stringIndexed returned correct " + i, "String " + i, (String) value);
332 }
333 }
334
335 /***
336 * Corner cases on getMappedProperty invalid arguments.
337 */
338 public void testGetMappedArguments()
339 {
340 try
341 {
342 Object value = bean.get("mappedProperty", "unknown");
343 assertNull("Should not return a value", value);
344 }
345 catch (Throwable t)
346 {
347 fail("Threw " + t + " instead of returning null");
348 }
349 }
350
351 /***
352 * Positive and negative tests on getMappedProperty valid arguments.
353 */
354 public void testGetMappedValues()
355 {
356 Object value = bean.get("mappedProperty", "key1");
357 assertEquals("Can find first value", "First Value", value);
358
359 value = bean.get("mappedProperty", "key2");
360 assertEquals("Can find second value", "Second Value", value);
361
362 value = bean.get("mappedProperty", "key3");
363 assertNotNull("Cannot find third value", value);
364 }
365
366 /***
367 * Corner cases on getSimpleProperty invalid arguments.
368 */
369 public void testGetSimpleArguments()
370 {
371 try
372 {
373 bean.get("a non existing property");
374 }
375 catch (IllegalArgumentException e)
376 {
377 return;
378 }
379 catch (Throwable t)
380 {
381 fail("Threw " + t + " instead of IllegalArgumentException");
382 }
383 fail("Should throw IllegalArgumentException");
384 }
385
386 /***
387 * Test getSimpleProperty on a boolean property.
388 */
389 public void testGetSimpleBoolean()
390 {
391 Object value = bean.get("booleanProperty");
392 assertNotNull("Got a value", value);
393 ObjectAssert.assertInstanceOf("Got correct type", Boolean.class, value);
394 assertTrue("Got correct value", ((Boolean) value).booleanValue());
395 }
396
397 /***
398 * Test getSimpleProperty on a double property.
399 */
400 public void testGetSimpleDouble()
401 {
402 Object value = bean.get("doubleProperty");
403 assertNotNull("Got a value", value);
404 ObjectAssert.assertInstanceOf("Got correct type", Double.class, value);
405 assertEquals("Got correct value", ((Double) value).doubleValue(), Double.MAX_VALUE, 0.005);
406 }
407
408 /***
409 * Test getSimpleProperty on a float property.
410 */
411 public void testGetSimpleFloat()
412 {
413 Object value = bean.get("floatProperty");
414 assertNotNull("Got a value", value);
415 ObjectAssert.assertInstanceOf("Got correct type", Float.class, value);
416 assertEquals("Got correct value", ((Float) value).floatValue(), Float.MAX_VALUE, 0.005f);
417 }
418
419 /***
420 * Test getSimpleProperty on a int property.
421 */
422 public void testGetSimpleInt()
423 {
424 Object value = bean.get("intProperty");
425 assertNotNull("Failed to get value", value);
426 ObjectAssert.assertInstanceOf("Incorrect type", Integer.class, value);
427 assertEquals("Incorrect value", ((Integer) value).intValue(), Integer.MAX_VALUE);
428 }
429
430 /***
431 * Test getSimpleProperty on a long property.
432 */
433 public void testGetSimpleLong()
434 {
435 Object value = bean.get("longProperty");
436 assertNotNull("Got a value", value);
437 ObjectAssert.assertInstanceOf("Returned incorrect type", Long.class, value);
438 assertEquals("Returned value of Incorrect value", ((Long) value).longValue(), Long.MAX_VALUE);
439 }
440
441 /***
442 * Test getSimpleProperty on a short property.
443 */
444 public void testGetSimpleShort()
445 {
446 Object value = bean.get("shortProperty");
447 assertNotNull("Got a value", value);
448 ObjectAssert.assertInstanceOf("Got correct type", Short.class, value);
449 assertEquals("Got correct value", ((Short) value).shortValue(), Short.MAX_VALUE);
450 }
451
452 /***
453 * Test getSimpleProperty on a String property.
454 */
455 public void testGetSimpleString()
456 {
457 Object value = bean.get("stringProperty");
458 assertNotNull("Got a value", value);
459 ObjectAssert.assertInstanceOf("Got correct type", String.class, value);
460 assertEquals("Got correct value", (String) value, "This is a string");
461 }
462
463 /***
464 * Test <code>contains()</code> method for mapped properties.
465 */
466 public void testMappedContains()
467 {
468 assertTrue("Can't see first key", bean.contains("mappedProperty", "key1"));
469 assertTrue("Can see unknown key", !bean.contains("mappedProperty", "Unknown Key"));
470 }
471
472 /***
473 * Test <code>remove()</code> method for mapped properties.
474 */
475 public void testMappedRemove()
476 {
477 assertTrue("Can see first key", bean.contains("mappedProperty", "key1"));
478 bean.remove("mappedProperty", "key1");
479 assertTrue("Can not see first key", !bean.contains("mappedProperty", "key1"));
480
481 assertTrue("Can not see unknown key", !bean.contains("mappedProperty", "key4"));
482 bean.remove("mappedProperty", "key4");
483 assertTrue("Can not see unknown key", !bean.contains("mappedProperty", "key4"));
484 }
485
486 /***
487 * Corner cases on setIndexedProperty invalid arguments.
488 */
489 public void testSetIndexedArguments()
490 {
491 try
492 {
493 bean.set("intArray", -1, new Integer(0));
494 }
495 catch (IndexOutOfBoundsException e)
496 {
497 return;
498 }
499 catch (Throwable t)
500 {
501 fail("Threw " + t + " instead of IndexOutOfBoundsException");
502 }
503
504 fail("Should throw IndexOutOfBoundsException");
505 }
506
507 /***
508 * Positive and negative tests on setIndexedProperty valid arguments.
509 */
510 public void testSetIndexedValues()
511 {
512 bean.set("intArray", 0, new Integer(1));
513 Object value = bean.get("intArray", 0);
514
515 assertNotNull("Returned new value 0", value);
516 ObjectAssert.assertInstanceOf("Returned Integer new value 0", Integer.class, value);
517 assertEquals("Returned correct new value 0", 1, ((Integer) value).intValue());
518
519
520 bean.set("intIndexed", 1, new Integer(11));
521 value = bean.get("intIndexed", 1);
522
523 assertNotNull("Returned new value 1", value);
524 ObjectAssert.assertInstanceOf("Returned Integer new value 1", Integer.class, value);
525 assertEquals("Returned correct new value 1", 11, ((Integer) value).intValue());
526
527
528 bean.set("listIndexed", 2, "New Value 2");
529 value = bean.get("listIndexed", 2);
530
531 assertNotNull("Returned new value 2", value);
532 ObjectAssert.assertInstanceOf("Returned String new value 2", String.class, value);
533 assertEquals("Returned correct new value 2", "New Value 2", (String) value);
534
535
536 bean.set("stringArray", 3, "New Value 3");
537 value = bean.get("stringArray", 3);
538
539 assertNotNull("Returned new value 3", value);
540 ObjectAssert.assertInstanceOf("Returned String new value 3", String.class, value);
541 assertEquals("Returned correct new value 3", "New Value 3", (String) value);
542
543
544 bean.set("stringIndexed", 4, "New Value 4");
545 value = bean.get("stringIndexed", 4);
546
547 assertNotNull("Returned new value 4", value);
548 ObjectAssert.assertInstanceOf("Returned String new value 4", String.class, value);
549 assertEquals("Returned correct new value 4", "New Value 4", (String) value);
550 }
551
552 /***
553 * Positive and negative tests on setMappedProperty valid arguments.
554 */
555 public void testSetMappedValues()
556 {
557 bean.set("mappedProperty", "First Key", "New First Value");
558 assertEquals("Can replace old value", "New First Value", (String) bean.get("mappedProperty", "First Key"));
559
560 bean.set("mappedProperty", "Fourth Key", "Fourth Value");
561 assertEquals("Can set new value", "Fourth Value", (String) bean.get("mappedProperty", "Fourth Key"));
562 }
563
564 /***
565 * Test setSimpleProperty on a boolean property.
566 */
567 public void testSetSimpleBoolean()
568 {
569 boolean oldValue = ((Boolean) bean.get("booleanProperty")).booleanValue();
570 boolean newValue = !oldValue;
571 bean.set("booleanProperty", new Boolean(newValue));
572 assertTrue("Matched new value", newValue == ((Boolean) bean.get("booleanProperty")).booleanValue());
573 }
574
575 /***
576 * Test setSimpleProperty on a double property.
577 */
578 public void testSetSimpleDouble()
579 {
580 double oldValue = ((Double) bean.get("doubleProperty")).doubleValue();
581 double newValue = oldValue + 1.0;
582 bean.set("doubleProperty", new Double(newValue));
583 assertEquals("Matched new value", newValue, ((Double) bean.get("doubleProperty")).doubleValue(), 0.005);
584 }
585
586 /***
587 * Test setSimpleProperty on a float property.
588 */
589 public void testSetSimpleFloat()
590 {
591 float oldValue = ((Float) bean.get("floatProperty")).floatValue();
592 float newValue = oldValue + (float) 1.0;
593 bean.set("floatProperty", new Float(newValue));
594 assertEquals("Matched new value", newValue, ((Float) bean.get("floatProperty")).floatValue(), 0.005f);
595 }
596
597 /***
598 * Test setSimpleProperty on a int property.
599 */
600 public void testSetSimpleInt()
601 {
602 int oldValue = ((Integer) bean.get("intProperty")).intValue();
603 int newValue = oldValue + 1;
604 bean.set("intProperty", new Integer(newValue));
605 assertEquals("Matched new value", newValue, ((Integer) bean.get("intProperty")).intValue());
606 }
607
608 /***
609 * Test setSimpleProperty on a long property.
610 */
611 public void testSetSimpleLong()
612 {
613 long oldValue = ((Long) bean.get("longProperty")).longValue();
614 long newValue = oldValue + 1;
615 bean.set("longProperty", new Long(newValue));
616 assertEquals("Matched new value", newValue, ((Long) bean.get("longProperty")).longValue());
617 }
618
619 /***
620 * Test setSimpleProperty on a short property.
621 */
622 public void testSetSimpleShort()
623 {
624 short oldValue = ((Short) bean.get("shortProperty")).shortValue();
625 short newValue = (short) (oldValue + 1);
626 bean.set("shortProperty", new Short(newValue));
627 assertEquals("Matched new value", newValue, ((Short) bean.get("shortProperty")).shortValue());
628 }
629
630 /***
631 * Test setSimpleProperty on a String property.
632 */
633 public void testSetSimpleString()
634 {
635 String oldValue = (String) bean.get("stringProperty");
636 String newValue = oldValue + " Extra Value";
637 bean.set("stringProperty", newValue);
638 assertEquals("Matched new value", newValue, (String) bean.get("stringProperty"));
639 }
640
641 /***
642 * Tests set on a null value: should throw NPE.
643 */
644 public void testAddNullPropertyValue()
645 {
646 try
647 {
648 bean.set("nullProperty", null);
649 }
650 catch (NullPointerException e)
651 {
652 return;
653 }
654 catch (Throwable t)
655 {
656 fail("Threw " + t + " instead of NullPointerException");
657 return;
658 }
659 fail("Should have thrown NullPointerException");
660 }
661
662 /***
663 * Test the retrieval of a non-existent property.
664 */
665 public void testGetNonExistentProperty()
666 {
667 try
668 {
669 bean.get("nonexistProperty");
670 }
671 catch (IllegalArgumentException e)
672 {
673 return;
674 }
675 catch (Exception e)
676 {
677 fail("Threw '" + e + "' instead of java.lang.IllegalArgumentException");
678 }
679
680 fail("Get non-existent property failed to throw java.lang.IllegalArgumentException");
681 }
682
683 /***
684 * Base for testGetDescriptorXxxxx() series of tests.
685 *
686 * @param name Name of the property to be retrieved
687 * @param type Expected class type of this property
688 */
689 protected void testGetDescriptorBase(String name, Class type)
690 {
691 DynaProperty descriptor = bean.getDynaClass().getDynaProperty(name);
692
693 assertNotNull("Failed to get descriptor", descriptor);
694 assertEquals("Got incorrect type", type, descriptor.getType());
695 }
696
697 /***
698 * Tests if accessing a non-indexed property using the index
699 * get method throws an IllegalArgumentException as it
700 * should.
701 */
702 public void testNonIndexedPropeties()
703 {
704 ConfigurationDynaBean nested = (ConfigurationDynaBean) bean.get("mappedProperty");
705
706 String value = (String) nested.get("key1");
707 assertEquals("Can find first value", "First Value", value);
708
709 nested.set("key1", "undefined");
710 assertEquals("Incorrect value returned", "undefined", bean.get("mappedProperty.key1"));
711 }
712
713 /***
714 * Tests if accessing a non-indexed property using the index
715 * get method throws an IllegalArgumentException as it
716 * should.
717 */
718 public void testNestedPropeties()
719 {
720 try
721 {
722 bean.get("booleanProperty", 0);
723 }
724 catch (IllegalArgumentException e)
725 {
726 return;
727 }
728 catch (Throwable t)
729 {
730 fail("Threw " + t + " instead of IllegalArgumentException");
731 return;
732 }
733
734 fail("Should have thrown IllegalArgumentException");
735
736 try
737 {
738 bean.set("booleanProperty", 0, Boolean.TRUE);
739 }
740 catch (IllegalArgumentException e)
741 {
742 return;
743 }
744 catch (Throwable t)
745 {
746 fail("Threw " + t + " instead of IllegalArgumentException");
747 return;
748 }
749
750 fail("Should have thrown IllegalArgumentException");
751 }
752
753
754 }