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