1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */ 
17  package org.apache.commons.beanutils;
18  
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.Date;
22  import java.util.HashMap;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Set;
27  import junit.framework.Test;
28  import junit.framework.TestCase;
29  import junit.framework.TestSuite;
30  
31  /***
32   * <p>Test Case for the <code>DynaBeanMapDecorator</code> implementation class.</p>
33   *
34   * @author Niall Pemberton
35   */
36  public class DynaBeanMapDecoratorTestCase extends TestCase {
37  
38      private static final DynaProperty stringProp = new DynaProperty("stringProp", String.class);
39      private static final DynaProperty nullProp   = new DynaProperty("nullProp",   String.class);
40      private static final DynaProperty intProp    = new DynaProperty("intProp",    Integer.class);
41      private static final DynaProperty dateProp   = new DynaProperty("dateProp",   Date.class);
42      private static final DynaProperty mapProp    = new DynaProperty("mapProp",    Map.class);
43      private static final DynaProperty[] properties = new DynaProperty[] {
44                        stringProp, nullProp, intProp, dateProp, mapProp};
45      private static final DynaClass dynaClass = new BasicDynaClass("testDynaClass", BasicDynaBean.class, properties);
46  
47      private static String  stringVal = "somevalue";
48      private static Integer intVal    = new Integer(5);
49      private static Date    dateVal   = new Date();
50      private Map     mapVal    = new HashMap();
51  
52      private Object[] values = new Object[] {stringVal, null, intVal, dateVal, mapVal};
53  
54      private BasicDynaBean dynaBean;
55      private Map decoratedMap;
56      private Map modifiableMap;
57      private static final Map emptyMap = new DynaBeanMapDecorator(new BasicDynaBean(new BasicDynaClass()));
58  
59      // ---------------------------------------------------------- Constructors
60  
61      /***
62       * Construct a new instance of this test case.
63       *
64       * @param name Name of the test case
65       */
66      public DynaBeanMapDecoratorTestCase(String name) {
67          super(name);
68      }
69  
70      // -------------------------------------------------- Overall Test Methods
71  
72      /***
73       * Run thus Test
74       */
75      public static void main(String[] args) {
76          junit.textui.TestRunner.run(suite());
77      }
78  
79      /***
80       * Return the tests included in this test suite.
81       */
82      public static Test suite() {
83          return (new TestSuite(DynaBeanMapDecoratorTestCase.class));
84      }
85  
86      /***
87       * Set up instance variables required by this test case.
88       */
89      public void setUp() throws Exception {
90  
91          mapVal.clear(); 
92          mapVal.put("key1", "key1Value");
93          mapVal.put("key2", "key2Value");
94  
95          // Initialize DynaBean and properties
96          dynaBean = new BasicDynaBean(dynaClass);
97          for (int i = 0; i < properties.length; i++) {
98              dynaBean.set(properties[i].getName(), values[i]);
99          }
100 
101         // Create decorated Maps
102         decoratedMap  = new DynaBeanMapDecorator(dynaBean);
103         modifiableMap = new DynaBeanMapDecorator(dynaBean, false);
104 
105     }
106 
107     /***
108      * Tear down instance variables required by this test case.
109      */
110     public void tearDown() {
111         dynaBean = null;
112         decoratedMap = null;
113         modifiableMap = null;
114     }
115 
116     // ------------------------------------------------ Individual Test Methods
117 
118     /***
119      * Test isReadOnly() method
120      */
121     public void testIsReadOnly() {
122         assertTrue("decoratedMap true",   ((DynaBeanMapDecorator)decoratedMap).isReadOnly());
123         assertFalse("modifiableMap false", ((DynaBeanMapDecorator)modifiableMap).isReadOnly());
124     }
125 
126     /***
127      * Test clear() method
128      */
129     public void testClear() {
130         try {
131             decoratedMap.clear();
132             fail("decoratedMap.clear()");
133         } catch(UnsupportedOperationException ignore) {
134             // expected result
135         }
136         try {
137             modifiableMap.clear();
138             fail("modifiableMap.clear()");
139         } catch(UnsupportedOperationException ignore) {
140             // expected result
141         }
142     }
143 
144     /***
145      * Test containsKey() method
146      */
147     public void testContainsKey() {
148         assertTrue("decoratedMap true",   decoratedMap.containsKey(stringProp.getName()));
149         assertFalse("decoratedMap false", decoratedMap.containsKey("xyz"));
150     }
151 
152     /***
153      * Test containsValue() method
154      */
155     public void testContainsValue() {
156         assertTrue("decoratedMap true",   decoratedMap.containsValue(stringVal));
157         assertFalse("decoratedMap false", decoratedMap.containsValue("xyz"));
158     }
159 
160     /***
161      * Test entrySet() method
162      */
163     public void testEntrySet() {
164         Set set = modifiableMap.entrySet();
165 
166         // Check the Set can't be modified
167         checkUnmodifiable("entrySet()", set);
168 
169         assertEquals("entrySet size", properties.length, set.size());
170 
171         Iterator iterator = set.iterator();
172         List namesList = new ArrayList();
173         int i = 0;
174         while (iterator.hasNext()) {
175             Map.Entry entry = (Map.Entry)iterator.next();
176             String name  = (String)entry.getKey();
177             namesList.add(name);
178             Object expectValue = decoratedMap.get(name);
179             assertEquals("entrySet("+i+") val", expectValue, entry.getValue());
180             i++;
181         }
182         for (int j = 0; j < properties.length; j++) {
183             String name = properties[j].getName();
184             assertTrue("Check property[" + j + "]", namesList.contains(name));
185         }
186     }
187 
188     /***
189      * Test get() method
190      */
191     public void testGet() {
192 
193         // valid property name
194         assertEquals("decoratedMap valid", stringVal, decoratedMap.get(stringProp.getName()));
195 
196         // invalid property name
197         try {
198             decoratedMap.get("xyz");
199             fail("decoratedMap invalid");
200         } catch(IllegalArgumentException ignore) {
201             // expected result
202         }
203     }
204 
205     /***
206      * Test isEmpty() method
207      */
208     public void testIsEmpty() {
209         assertTrue("Empty",      emptyMap.isEmpty());
210         assertFalse("Not Empty", decoratedMap.isEmpty());
211     }
212 
213     /***
214      * Test keySet() method
215      */
216     public void testKeySet() {
217         Set set = modifiableMap.keySet();
218 
219         // Check the Set can't be modified
220         checkUnmodifiable("keySet()", set);
221 
222         assertEquals("keySet size", properties.length, set.size());
223 
224         for (int i = 0; i < properties.length; i++) {
225             String name = properties[i].getName();
226             assertTrue("Check property[" + i + "]", set.contains(name));
227         }
228     }
229 
230     /***
231      * Test put() method
232      */
233     public void testPut() {
234 
235         String newValue = "ABC";
236 
237         // Test read only
238         try {
239             decoratedMap.put(stringProp.getName(), newValue);
240             fail("Not read only");
241         } catch(UnsupportedOperationException ignore) {
242             // expected result
243         }
244 
245         // Test Writable
246         assertEquals("modifiableMap put", stringVal, modifiableMap.put(stringProp.getName(), newValue));
247         assertEquals("dynaBean get", newValue, dynaBean.get(stringProp.getName()));
248         assertEquals("modifiableMap get", newValue, modifiableMap.get(stringProp.getName()));
249     }
250 
251     /***
252      * Test putAll() method
253      */
254     public void testPutAll() {
255 
256         String newValue = "ABC";
257         Map newMap = new HashMap();
258         newMap.put(stringProp.getName(), newValue);
259 
260         // Test read only
261         try {
262             decoratedMap.putAll(newMap);
263             fail("Not read only");
264         } catch(UnsupportedOperationException ignore) {
265             // expected result
266         }
267 
268         // Test Writable
269         assertEquals("before putAll", stringVal, dynaBean.get(stringProp.getName()));
270         modifiableMap.putAll(newMap);
271         assertEquals("after putAll",  newValue,  dynaBean.get(stringProp.getName()));
272     }
273 
274     /***
275      * Test remove() method
276      */
277     public void testRemove() {
278         try {
279             decoratedMap.remove(stringProp.getName());
280             fail("decoratedMap.remove()");
281         } catch(UnsupportedOperationException ignore) {
282             // expected result
283         }
284         try {
285             modifiableMap.remove(stringProp.getName());
286             fail("modifiableMap.remove()");
287         } catch(UnsupportedOperationException ignore) {
288             // expected result
289         }
290     }
291 
292     /***
293      * Test size() method
294      */
295     public void testSize() {
296         assertEquals("Empty", 0, emptyMap.size());
297         assertEquals("Not Empty", properties.length, decoratedMap.size());
298     }
299 
300     /***
301      * Test values() method
302      */
303     public void testValues() {
304         Collection collection = modifiableMap.values();
305 
306         // Check the Collection can't be modified
307         checkUnmodifiable("values()", collection);
308 
309         assertEquals("values size", values.length, collection.size());
310 
311         // Collection should be ordered in same sequence as properties
312         Iterator iterator = collection.iterator();
313         int i = 0;
314         while (iterator.hasNext()) {
315             assertEquals("values("+i+")", values[i], iterator.next());
316             i++;
317         }
318     }
319 
320     /***
321      * Check that a Collection is not modifiable
322      */
323     private void checkUnmodifiable(String desc, Collection collection) {
324         String testVal = "xyz";
325 
326         // Check can't add()
327         try {
328             collection.add(testVal);
329             fail(desc + ".add()");
330         } catch(UnsupportedOperationException ignore) {
331             // expected result
332         }
333 
334         // Check can't addAll()
335         List list = new ArrayList(1);
336         list.add(testVal);
337         try {
338             collection.addAll(list);
339             fail(desc + ".addAll()");
340         } catch(UnsupportedOperationException ignore) {
341             // expected result
342         }
343 
344         // Check can't clear()
345         try {
346             collection.clear();
347             fail(desc + ".clear()");
348         } catch(UnsupportedOperationException ignore) {
349             // expected result
350         }
351 
352         // Check can't remove()
353         try {
354             collection.remove("abc");
355             fail(desc + ".remove()");
356         } catch(UnsupportedOperationException ignore) {
357             // expected result
358         }
359 
360         // Check can't removeAll()
361         try {
362             collection.removeAll(list);
363             fail(desc + ".removeAll()");
364         } catch(UnsupportedOperationException ignore) {
365             // expected result
366         }
367 
368         // Check can't retainAll()
369         try {
370             collection.retainAll(list);
371             fail(desc + ".retainAll()");
372         } catch(UnsupportedOperationException ignore) {
373             // expected result
374         }
375     }
376 }