View Javadoc
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    *      https://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.beanutils2;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertThrows;
22  import static org.junit.jupiter.api.Assertions.assertTrue;
23  
24  import java.util.ArrayList;
25  import java.util.Collection;
26  import java.util.Date;
27  import java.util.HashMap;
28  import java.util.Iterator;
29  import java.util.List;
30  import java.util.Map;
31  import java.util.Map.Entry;
32  import java.util.Set;
33  
34  import org.junit.jupiter.api.AfterEach;
35  import org.junit.jupiter.api.BeforeEach;
36  import org.junit.jupiter.api.Test;
37  
38  /**
39   * <p>
40   * Test Case for the {@code DynaBeanMapDecorator} implementation class.
41   * </p>
42   */
43  @SuppressWarnings("deprecation")
44  public class DynaBeanMapDecoratorTest {
45  
46      private static final DynaProperty stringProp = new DynaProperty("stringProp", String.class);
47      private static final DynaProperty nullProp = new DynaProperty("nullProp", String.class);
48      private static final DynaProperty intProp = new DynaProperty("intProp", Integer.class);
49      private static final DynaProperty dateProp = new DynaProperty("dateProp", Date.class);
50      private static final DynaProperty mapProp = new DynaProperty("mapProp", Map.class);
51      private static final DynaProperty[] properties = { stringProp, nullProp, intProp, dateProp, mapProp };
52      private static final DynaClass dynaClass = new BasicDynaClass("testDynaClass", BasicDynaBean.class, properties);
53  
54      private static final String stringVal = "somevalue";
55      private static final Integer intVal = Integer.valueOf(5);
56      private static final Date dateVal = new Date();
57      private static final Map<String, Object> emptyMap = new DynaBeanPropertyMapDecorator(new BasicDynaBean(new BasicDynaClass()));
58  
59      private final Map<Object, Object> mapVal = new HashMap<>();
60      private final Object[] values = { stringVal, null, intVal, dateVal, mapVal };
61      private BasicDynaBean dynaBean;
62  
63      private Map<String, Object> decoratedMap;
64  
65      private Map<String, Object> modifiableMap;
66  
67      /**
68       * Check that a Collection is not modifiable
69       */
70      private <E> void checkUnmodifiable(final String desc, final Collection<E> collection, final E addElem) {
71          // Check can't add()
72          assertThrows(UnsupportedOperationException.class, () -> collection.add(addElem));
73          // Check can't addAll()
74          final List<E> list = new ArrayList<>(1);
75          list.add(addElem);
76          assertThrows(UnsupportedOperationException.class, () -> collection.addAll(list));
77          // Check can't clear()
78          assertThrows(UnsupportedOperationException.class, () -> collection.clear());
79          // Check can't remove()
80          assertThrows(UnsupportedOperationException.class, () -> collection.remove("abc"));
81          // Check can't removeAll()
82          assertThrows(UnsupportedOperationException.class, () -> collection.removeAll(list));
83          // Check can't retainAll()
84          assertThrows(UnsupportedOperationException.class, () -> collection.retainAll(list));
85      }
86  
87      /**
88       * Sets up instance variables required by this test case.
89       */
90      @BeforeEach
91      public void setUp() throws Exception {
92  
93          mapVal.clear();
94          mapVal.put("key1", "key1Value");
95          mapVal.put("key2", "key2Value");
96  
97          // Initialize DynaBean and properties
98          dynaBean = new BasicDynaBean(dynaClass);
99          for (int i = 0; i < properties.length; i++) {
100             dynaBean.set(properties[i].getName(), values[i]);
101         }
102 
103         // Create decorated Maps
104         decoratedMap = new DynaBeanPropertyMapDecorator(dynaBean);
105         modifiableMap = new DynaBeanPropertyMapDecorator(dynaBean, false);
106 
107     }
108 
109     /**
110      * Tear down instance variables required by this test case.
111      */
112     @AfterEach
113     public void tearDown() {
114         dynaBean = null;
115         decoratedMap = null;
116         modifiableMap = null;
117     }
118 
119     /**
120      * Test clear() method
121      */
122     @Test
123     public void testClear() {
124         assertThrows(UnsupportedOperationException.class, () -> decoratedMap.clear());
125         assertThrows(UnsupportedOperationException.class, () -> modifiableMap.clear());
126     }
127 
128     /**
129      * Test containsKey() method
130      */
131     @Test
132     public void testContainsKey() {
133         assertTrue(decoratedMap.containsKey(stringProp.getName()), "decoratedMap true");
134         assertFalse(decoratedMap.containsKey("xyz"), "decoratedMap false");
135     }
136 
137     /**
138      * Test containsValue() method
139      */
140     @Test
141     public void testContainsValue() {
142         assertTrue(decoratedMap.containsValue(stringVal), "decoratedMap true");
143         assertFalse(decoratedMap.containsValue("xyz"), "decoratedMap false");
144     }
145 
146     /**
147      * Test entrySet() method
148      */
149     @Test
150     public void testEntrySet() {
151         final Set<Map.Entry<String, Object>> set = modifiableMap.entrySet();
152 
153         // Check the Set can't be modified
154         final Map<String, Object> m = new HashMap<>();
155         m.put("key", "value");
156         checkUnmodifiable("entrySet()", set, m.entrySet().iterator().next());
157 
158         assertEquals(properties.length, set.size(), "entrySet size");
159 
160         final List<String> namesList = new ArrayList<>();
161         int i = 0;
162         for (final Entry<String, Object> entry : set) {
163             final String name = entry.getKey();
164             namesList.add(name);
165             final Object expectValue = decoratedMap.get(name);
166             assertEquals(expectValue, entry.getValue(), "entrySet(" + i + ") val");
167             i++;
168         }
169         for (int j = 0; j < properties.length; j++) {
170             final String name = properties[j].getName();
171             assertTrue(namesList.contains(name), "Check property[" + j + "]");
172         }
173     }
174 
175     /**
176      * Test get() method
177      */
178     @Test
179     public void testGet() {
180         // valid property name
181         assertEquals(stringVal, decoratedMap.get(stringProp.getName()), "decoratedMap valid");
182         // invalid property name
183         assertThrows(IllegalArgumentException.class, () -> decoratedMap.get("xyz"));
184     }
185 
186     /**
187      * Test isEmpty() method
188      */
189     @Test
190     public void testIsEmpty() {
191         assertTrue(emptyMap.isEmpty(), "Empty");
192         assertFalse(decoratedMap.isEmpty(), "Not Empty");
193     }
194 
195     /**
196      * Test isReadOnly() method
197      */
198     @Test
199     public void testIsReadOnly() {
200         assertTrue(((DynaBeanPropertyMapDecorator) decoratedMap).isReadOnly(), "decoratedMap true");
201         assertFalse(((DynaBeanPropertyMapDecorator) modifiableMap).isReadOnly(), "modifiableMap false");
202     }
203 
204     /**
205      * Test keySet() method
206      */
207     @Test
208     public void testKeySet() {
209         final Set<String> set = modifiableMap.keySet();
210 
211         // Check the Set can't be modified
212         checkUnmodifiable("keySet()", set, "xyz");
213 
214         assertEquals(properties.length, set.size(), "keySet size");
215 
216         for (int i = 0; i < properties.length; i++) {
217             final String name = properties[i].getName();
218             assertTrue(set.contains(name), "Check property[" + i + "]");
219         }
220     }
221 
222     /**
223      * Test put() method
224      */
225     @Test
226     public void testPut() {
227         final String newValue = "ABC";
228         // Test read only
229         assertThrows(UnsupportedOperationException.class, () -> decoratedMap.put(stringProp.getName(), newValue));
230         // Test Writable
231         assertEquals(stringVal, modifiableMap.put(stringProp.getName(), newValue), "modifiableMap put");
232         assertEquals(newValue, dynaBean.get(stringProp.getName()), "dynaBean get");
233         assertEquals(newValue, modifiableMap.get(stringProp.getName()), "modifiableMap get");
234     }
235 
236     /**
237      * Test putAll() method
238      */
239     @Test
240     public void testPutAll() {
241         final String newValue = "ABC";
242         final Map<String, Object> newMap = new HashMap<>();
243         newMap.put(stringProp.getName(), newValue);
244         // Test read only
245         assertThrows(UnsupportedOperationException.class, () -> decoratedMap.putAll(newMap));
246         // Test Writable
247         assertEquals(stringVal, dynaBean.get(stringProp.getName()), "before putAll");
248         modifiableMap.putAll(newMap);
249         assertEquals(newValue, dynaBean.get(stringProp.getName()), "after putAll");
250     }
251 
252     /**
253      * Test remove() method
254      */
255     @Test
256     public void testRemove() {
257         assertThrows(UnsupportedOperationException.class, () -> decoratedMap.remove(stringProp.getName()));
258         assertThrows(UnsupportedOperationException.class, () -> modifiableMap.remove(stringProp.getName()));
259     }
260 
261     /**
262      * Test size() method
263      */
264     @Test
265     public void testSize() {
266         assertEquals(0, emptyMap.size(), "Empty");
267         assertEquals(properties.length, decoratedMap.size(), "Not Empty");
268     }
269 
270     /**
271      * Test values() method
272      */
273     @Test
274     public void testValues() {
275         final Collection<Object> collection = modifiableMap.values();
276 
277         // Check the Collection can't be modified
278         checkUnmodifiable("values()", collection, "xyz");
279 
280         assertEquals(values.length, collection.size(), "values size");
281 
282         // Collection should be ordered in same sequence as properties
283         final Iterator<Object> iterator = collection.iterator();
284         int i = 0;
285         while (iterator.hasNext()) {
286             assertEquals(values[i], iterator.next(), "values(" + i + ")");
287             i++;
288         }
289     }
290 }