1   /*
2    * $Id: IndexedPropertyTestCase.java 546480 2007-06-12 13:35:32Z niallp $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one or more
5    * contributor license agreements.  See the NOTICE file distributed with
6    * this work for additional information regarding copyright ownership.
7    * The ASF licenses this file to You under the Apache License, Version 2.0
8    * (the "License"); you may not use this file except in compliance with
9    * the License.  You may obtain a copy of the License at
10   * 
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */ 
19  
20  package org.apache.commons.beanutils;
21  
22  import java.util.List;
23  import java.util.ArrayList;
24  import java.beans.IndexedPropertyDescriptor;
25  import java.beans.PropertyDescriptor;
26  
27  import junit.framework.Test;
28  import junit.framework.TestCase;
29  import junit.framework.TestSuite;
30  
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  
34  
35  
36  
37  /***
38   * <p>Test Case for the Indexed Properties.</p>
39   *
40   * @author Niall Pemberton
41   * @version $Revision: 546480 $ $Date: 2007-06-12 14:35:32 +0100 (Tue, 12 Jun 2007) $
42   */
43  
44  public class IndexedPropertyTestCase extends TestCase {
45  
46      private static final Log log = LogFactory.getLog(IndexedPropertyTestCase.class);
47  
48      // ---------------------------------------------------- Instance Variables
49  
50      /***
51       * The test bean for each test.
52       */
53      private IndexedTestBean bean = null;
54      private BeanUtilsBean beanUtilsBean; 
55      private PropertyUtilsBean propertyUtilsBean;
56      private String[] testArray;
57      private String[] newArray;
58      private List testList;
59      private List newList;
60      private ArrayList arrayList;
61  
62      // ---------------------------------------------------------- Constructors
63  
64      /***
65       * Construct a new instance of this test case.
66       *
67       * @param name Name of the test case
68       */
69      public IndexedPropertyTestCase(String name) {
70          super(name);
71      }
72  
73  
74      // -------------------------------------------------- Overall Test Methods
75  
76  
77      /***
78       * Set up instance variables required by this test case.
79       */
80      public void setUp() {
81  
82          // BeanUtils
83          beanUtilsBean = new BeanUtilsBean();
84          propertyUtilsBean = beanUtilsBean.getPropertyUtils();
85  
86          // initialize Arrays and Lists
87          testArray= new String[] {"array-0", "array-1", "array-2"};
88          newArray = new String[]  {"newArray-0", "newArray-1", "newArray-2"};
89  
90          testList = new ArrayList();
91          testList.add("list-0");
92          testList.add("list-1");
93          testList.add("list-2");
94  
95          newList = new ArrayList();
96          newList.add("newList-0");
97          newList.add("newList-1");
98          newList.add("newList-2");
99  
100         arrayList = new ArrayList();
101         arrayList.add("arrayList-0");
102         arrayList.add("arrayList-1");
103         arrayList.add("arrayList-2");
104 
105         // initialize Test Bean  properties
106         bean = new IndexedTestBean();
107         bean.setStringArray(testArray);
108         bean.setStringList(testList);
109         bean.setArrayList(arrayList);
110     }
111 
112 
113     /***
114      * Return the tests included in this test suite.
115      */
116     public static Test suite() {
117         return (new TestSuite(IndexedPropertyTestCase.class));
118     }
119 
120     /***
121      * Tear down instance variables required by this test case.
122      */
123     public void tearDown() {
124         bean = null;
125     }
126 
127 
128     // ------------------------------------------------ Individual Test Methods
129 
130     /***
131      * Test IndexedPropertyDescriptor for an Array
132      */
133     public void testArrayIndexedPropertyDescriptor() {
134 
135         try {
136             PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "stringArray");
137             assertNotNull("No Array Descriptor", descriptor);
138             assertEquals("Not IndexedPropertyDescriptor", 
139                          IndexedPropertyDescriptor.class,
140                          descriptor.getClass());
141             assertEquals("PropertDescriptor Type invalid", 
142                          testArray.getClass(),
143                          descriptor.getPropertyType());
144         } catch(Exception e) {
145             fail("Threw exception " + e);
146         }
147     }
148 
149     /***
150      * Test IndexedPropertyDescriptor for a List
151      */
152     public void testListIndexedPropertyDescriptor() {
153 
154         try {
155             PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "stringList");
156             assertNotNull("No List Descriptor", descriptor);
157             assertEquals("Not IndexedPropertyDescriptor", 
158                          IndexedPropertyDescriptor.class,
159                          descriptor.getClass());
160             assertEquals("PropertDescriptor Type invalid", 
161                          List.class,
162                          descriptor.getPropertyType());
163         } catch(Exception e) {
164             fail("Threw exception " + e);
165         }
166     }
167 
168     /***
169      * Test IndexedPropertyDescriptor for an ArrayList
170      */
171     public void testArrayListIndexedPropertyDescriptor() {
172 
173         try {
174             PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "arrayList");
175             assertNotNull("No ArrayList Descriptor", descriptor);
176             assertEquals("Not IndexedPropertyDescriptor", 
177                          IndexedPropertyDescriptor.class,
178                          descriptor.getClass());
179             assertEquals("PropertDescriptor Type invalid", 
180                          ArrayList.class,
181                          descriptor.getPropertyType());
182         } catch(Exception e) {
183             fail("Threw exception " + e);
184         }
185     }
186 
187     /***
188      * Test Read Method for an Array
189      */
190     public void testArrayReadMethod() {
191 
192         try {
193             IndexedPropertyDescriptor descriptor = 
194                  (IndexedPropertyDescriptor)propertyUtilsBean.getPropertyDescriptor(bean, "stringArray");
195             assertNotNull("No Array Read Method", descriptor.getReadMethod());
196         } catch(Exception e) {
197             fail("Threw exception " + e);
198         }
199     }
200 
201     /***
202      * Test Write Method for an Array
203      */
204     public void testArrayWriteMethod() {
205 
206         try {
207             IndexedPropertyDescriptor descriptor = 
208                  (IndexedPropertyDescriptor)propertyUtilsBean.getPropertyDescriptor(bean, "stringArray");
209             assertNotNull("No Array Write Method", descriptor.getWriteMethod());
210         } catch(Exception e) {
211             fail("Threw exception " + e);
212         }
213     }
214 
215     /***
216      * Test Indexed Read Method for an Array
217      */
218     public void testArrayIndexedReadMethod() {
219 
220         try {
221             IndexedPropertyDescriptor descriptor = 
222                  (IndexedPropertyDescriptor)propertyUtilsBean.getPropertyDescriptor(bean, "stringArray");
223             assertNotNull("No Array Indexed Read Method", descriptor.getIndexedReadMethod());
224         } catch(Exception e) {
225             fail("Threw exception " + e);
226         }
227     }
228 
229     /***
230      * Test Indexed Write Method for an Array
231      */
232     public void testArrayIndexedWriteMethod() {
233 
234         try {
235             IndexedPropertyDescriptor descriptor = 
236                  (IndexedPropertyDescriptor)propertyUtilsBean.getPropertyDescriptor(bean, "stringArray");
237             assertNotNull("No Array Indexed Write Method", descriptor.getIndexedWriteMethod());
238         } catch(Exception e) {
239             fail("Threw exception " + e);
240         }
241     }
242 
243     /***
244      * Test Read Method for a List
245      *
246      * JDK 1.3.1_04: Test Passes
247      * JDK 1.4.2_05: Test Fails - getter which returns java.util.List not returned
248      *                            by IndexedPropertyDescriptor.getReadMethod();
249      */
250     public void testListReadMethod() {
251 
252         try {
253             IndexedPropertyDescriptor descriptor = 
254                  (IndexedPropertyDescriptor)propertyUtilsBean.getPropertyDescriptor(bean, "stringList");
255             assertNotNull("No List Read Method", descriptor.getReadMethod());
256         } catch(Exception e) {
257             fail("Threw exception " + e);
258         }
259     }
260 
261     /***
262      * Test Write Method for a List
263      *
264      * JDK 1.3.1_04: Test Passes
265      * JDK 1.4.2_05: Test Fails - setter whith java.util.List argument not returned
266      *                            by IndexedPropertyDescriptor.getWriteMethod();
267      */
268     public void testListWriteMethod() {
269 
270         try {
271             IndexedPropertyDescriptor descriptor = 
272                  (IndexedPropertyDescriptor)propertyUtilsBean.getPropertyDescriptor(bean, "stringList");
273             assertNotNull("No List Write Method", descriptor.getWriteMethod());
274         } catch(Exception e) {
275             fail("Threw exception " + e);
276         }
277     }
278 
279     /***
280      * Test Indexed Read Method for a List
281      */
282     public void testListIndexedReadMethod() {
283 
284         try {
285             IndexedPropertyDescriptor descriptor = 
286                  (IndexedPropertyDescriptor)propertyUtilsBean.getPropertyDescriptor(bean, "stringList");
287             assertNotNull("No List Indexed Read Method", descriptor.getIndexedReadMethod());
288         } catch(Exception e) {
289             fail("Threw exception " + e);
290         }
291     }
292 
293     /***
294      * Test Indexed Write Method for a List
295      */
296     public void testListIndexedWriteMethod() {
297 
298         try {
299             IndexedPropertyDescriptor descriptor = 
300                  (IndexedPropertyDescriptor)propertyUtilsBean.getPropertyDescriptor(bean, "stringList");
301             assertNotNull("No List Indexed Write Method", descriptor.getIndexedWriteMethod());
302         } catch(Exception e) {
303             fail("Threw exception " + e);
304         }
305     }
306 
307     /***
308      * Test Read Method for an ArrayList
309      */
310     public void testArrayListReadMethod() {
311 
312         try {
313             IndexedPropertyDescriptor descriptor = 
314                  (IndexedPropertyDescriptor)propertyUtilsBean.getPropertyDescriptor(bean, "arrayList");
315             assertNotNull("No ArrayList Read Method", descriptor.getReadMethod());
316         } catch(Exception e) {
317             fail("Threw exception " + e);
318         }
319     }
320 
321     /***
322      * Test Write Method for an ArrayList
323      */
324     public void testArrayListWriteMethod() {
325 
326         try {
327             IndexedPropertyDescriptor descriptor = 
328                  (IndexedPropertyDescriptor)propertyUtilsBean.getPropertyDescriptor(bean, "arrayList");
329             assertNotNull("No ArrayList Write Method", descriptor.getWriteMethod());
330         } catch(Exception e) {
331             fail("Threw exception " + e);
332         }
333     }
334 
335     /***
336      * Test getting an array property
337      */
338     public void testGetArray() {
339         try {
340             assertEquals(testArray, 
341                          propertyUtilsBean.getProperty(bean, "stringArray"));
342         } catch(Exception e) {
343             fail("Threw exception " + e);
344         }
345     }
346 
347     /***
348      * Test getting an array property as a String
349      *
350      * NOTE: Why does retrieving array just return the first element in the array, whereas
351      *       retrieveing a List returns a comma separated list of all the elements?
352      */
353     public void testGetArrayAsString() {
354         try {
355             assertEquals("array-0", 
356                          beanUtilsBean.getProperty(bean, "stringArray"));
357         } catch(Exception e) {
358             fail("Threw exception " + e);
359         }
360     }
361 
362     /***
363      * Test getting an indexed item of an Array using getProperty("name[x]")
364      */
365     public void testGetArrayItemA() {
366 
367         try {
368             assertEquals("array-1",
369                          beanUtilsBean.getProperty(bean, "stringArray[1]"));
370         } catch(Exception e) {
371             fail("Threw exception " + e);
372         }
373     }
374 
375     /***
376      * Test getting an indexed item of an Array using getIndexedProperty("name")
377      */
378     public void testGetArrayItemB() {
379 
380         try {
381             assertEquals("array-1",
382                          beanUtilsBean.getIndexedProperty(bean, "stringArray", 1));
383         } catch(Exception e) {
384             fail("Threw exception " + e);
385         }
386     }
387 
388     /***
389      * Test getting a List
390      *
391      * JDK 1.3.1_04: Test Passes
392      * JDK 1.4.2_05: Test Fails - fails NoSuchMethodException, i.e. reason as testListReadMethod()
393      *                            failed.   
394      */
395     public void testGetList() {
396 
397         try {
398             assertEquals(testList, 
399                          propertyUtilsBean.getProperty(bean, "stringList"));
400         } catch(Exception e) {
401             fail("Threw exception " + e);
402         }
403     }
404 
405     /***
406      * Test getting a List property as a String
407      *
408      * JDK 1.3.1_04: Test Passes
409      * JDK 1.4.2_05: Test Fails - fails NoSuchMethodException, i.e. reason as testListReadMethod()
410      *                            failed.   
411      */
412     public void testGetListAsString() {
413 
414         try {
415             assertEquals("list-0", 
416                          beanUtilsBean.getProperty(bean, "stringList"));
417         } catch(Exception e) {
418             fail("Threw exception " + e);
419         }
420     }
421 
422     /***
423      * Test getting an indexed item of a List using getProperty("name[x]")
424      */
425     public void testGetListItemA() {
426 
427         try {
428             assertEquals("list-1",
429                          beanUtilsBean.getProperty(bean, "stringList[1]"));
430         } catch(Exception e) {
431             fail("Threw exception " + e);
432         }
433     }
434 
435     /***
436      * Test getting an indexed item of a List using getIndexedProperty("name")
437      */
438     public void testGetListItemB() {
439 
440         try {
441             assertEquals("list-1",
442                          beanUtilsBean.getIndexedProperty(bean, "stringList", 1));
443         } catch(Exception e) {
444             fail("Threw exception " + e);
445         }
446     }
447 
448     /***
449      * Test setting an Array property
450      *
451      * JDK 1.3.1_04 and 1.4.2_05: Test Fails - IllegalArgumentException can't invoke setter, argument type mismatch
452      *
453      * Fails because of a bug in BeanUtilsBean.setProperty() method. Value is always converted to the array's component
454      * type which in this case is a String. Then it calls the setStringArray(String[]) passing a String rather than
455      * String[] causing this exception. If there isn't an "index" value then the PropertyType (rather than
456      * IndexedPropertyType) should be used.
457      *
458      */
459     public void testSetArray() {
460         try {
461             beanUtilsBean.setProperty(bean, "stringArray", newArray);
462             Object value = bean.getStringArray();
463             assertEquals("Type is different", newArray.getClass(), value.getClass());
464             String[] array = (String[])value;
465             assertEquals("Array Length is different", newArray.length, array.length);
466             for (int i = 0; i < array.length; i++) {
467                 assertEquals("Element " + i + " is different", newArray[i], array[i]);
468             }
469         } catch(Exception e) {
470             log.error("testSetArray()", e);
471             fail("Threw exception " + e);
472         }
473     }
474 
475 
476     /***
477      * Test setting an indexed item of an Array using setProperty("name[x]", value)
478      */
479     public void testSetArrayItemA() {
480 
481         try {
482             beanUtilsBean.setProperty(bean, "stringArray[1]", "modified-1");
483             assertEquals("modified-1", bean.getStringArray(1));
484         } catch(Exception e) {
485             fail("Threw exception " + e);
486         }
487     }
488 
489     /***
490      * Test setting an indexed item of an Array using setIndexedProperty("name", value)
491      */
492     public void testSetArrayItemB() {
493 
494         try {
495             propertyUtilsBean.setIndexedProperty(bean, "stringArray", 1, "modified-1");
496             assertEquals("modified-1", bean.getStringArray(1));
497         } catch(Exception e) {
498             fail("Threw exception " + e);
499         }
500     }
501 
502     /***
503      * Test setting a List property
504      *
505      * JDK 1.3.1_04: Test Passes
506      * JDK 1.4.2_05: Test Fails - setter which returns java.util.List not returned
507      *                            by IndexedPropertyDescriptor.getWriteMethod() - therefore
508      *                            setProperty does nothing and values remain unchanged.
509      */
510     public void testSetList() {
511         try {
512             beanUtilsBean.setProperty(bean, "stringList", newList);
513             Object value = bean.getStringList();
514             assertEquals("Type is different", newList.getClass(), value.getClass());
515             List list  = (List)value;
516             assertEquals("List size is different", newList.size(), list.size());
517             for (int i = 0; i < list.size(); i++) {
518                 assertEquals("Element " + i + " is different", newList.get(i), list.get(i));
519             }
520         } catch(Exception e) {
521             log.error("testSetList()", e);
522             fail("Threw exception " + e);
523         }
524     }
525 
526 
527     /***
528      * Test setting an indexed item of a List using setProperty("name[x]", value)
529      */
530     public void testSetListItemA() {
531 
532         try {
533             beanUtilsBean.setProperty(bean, "stringList[1]", "modified-1");
534             assertEquals("modified-1", bean.getStringList(1));
535         } catch(Exception e) {
536             fail("Threw exception " + e);
537         }
538     }
539 
540     /***
541      * Test setting an indexed item of a List using setIndexedProperty("name", value)
542      */
543     public void testSetListItemB() {
544 
545         try {
546             propertyUtilsBean.setIndexedProperty(bean, "stringList", 1, "modified-1");
547             assertEquals("modified-1", bean.getStringList(1));
548         } catch(Exception e) {
549             fail("Threw exception " + e);
550         }
551     }
552 
553 
554     /***
555      * Test getting an ArrayList
556      */
557     public void testGetArrayList() {
558 
559         try {
560             assertEquals(arrayList, 
561                          propertyUtilsBean.getProperty(bean, "arrayList"));
562         } catch(Exception e) {
563             fail("Threw exception " + e);
564         }
565     }
566 
567     /***
568      * Test setting an ArrayList property
569      */
570     public void testSetArrayList() {
571         try {
572             beanUtilsBean.setProperty(bean, "arrayList", newList);
573             Object value = bean.getArrayList();
574             assertEquals("Type is different", newList.getClass(), value.getClass());
575             List list  = (List)value;
576             assertEquals("List size is different", newList.size(), list.size());
577             for (int i = 0; i < list.size(); i++) {
578                 assertEquals("Element " + i + " is different", newList.get(i), list.get(i));
579             }
580         } catch(Exception e) {
581             log.error("testSetList()", e);
582             fail("Threw exception " + e);
583         }
584     }
585 
586 }