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