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.assertNotNull;
20  import static org.junit.jupiter.api.Assertions.assertNull;
21  import static org.junit.jupiter.api.Assertions.assertThrows;
22  import static org.junit.jupiter.api.Assertions.assertTrue;
23  
24  import java.beans.IntrospectionException;
25  import java.beans.PropertyDescriptor;
26  import java.net.URI;
27  import java.util.HashMap;
28  import java.util.Map;
29  
30  import org.junit.jupiter.api.Test;
31  
32  /**
33   * Test class for {@code FluentPropertyBeanIntrospector}.
34   */
35  public class FluentPropertyBeanIntrospectorTest {
36      public static final class CapsBean {
37          private URI mURI;
38  
39          public URI getURI() {
40              return mURI;
41          }
42  
43          public void setURI(final URI theURI) {
44              mURI = theURI;
45          }
46      }
47  
48      /**
49       * Puts all property descriptors into a map so that they can be accessed by property name.
50       *
51       * @param descs the array with descriptors
52       * @return a map with property names as keys
53       */
54      private static Map<String, PropertyDescriptor> createDescriptorMap(final PropertyDescriptor[] descs) {
55          final Map<String, PropertyDescriptor> map = new HashMap<>();
56          for (final PropertyDescriptor pd : descs) {
57              map.put(pd.getName(), pd);
58          }
59          return map;
60      }
61  
62      /**
63       * Convenience method for obtaining a specific property descriptor and checking whether it exists.
64       *
65       * @param props the map with property descriptors
66       * @param name  the name of the desired descriptor
67       * @return the descriptor from the map
68       */
69      private static PropertyDescriptor fetchDescriptor(final Map<String, PropertyDescriptor> props, final String name) {
70          assertTrue(props.containsKey(name), "Property not found: " + name);
71          return props.get(name);
72      }
73  
74      /**
75       * Tries to create an instance without a prefix for write methods.
76       */
77      @Test
78      public void testInitNoPrefix() {
79          assertThrows(NullPointerException.class, () -> new FluentPropertyBeanIntrospector(null));
80      }
81  
82      /**
83       * Tests whether correct property descriptors are detected.
84       */
85      @Test
86      public void testIntrospection() throws IntrospectionException {
87          final PropertyUtilsBean pu = new PropertyUtilsBean();
88          final FluentPropertyBeanIntrospector introspector = new FluentPropertyBeanIntrospector();
89          pu.addBeanIntrospector(introspector);
90          final Map<String, PropertyDescriptor> props = createDescriptorMap(pu.getPropertyDescriptors(FluentIntrospectionTestBean.class));
91          PropertyDescriptor pd = fetchDescriptor(props, "name");
92          assertNotNull(pd.getReadMethod(), "No read method for name");
93          assertNotNull(pd.getWriteMethod(), "No write method for name");
94          fetchDescriptor(props, "stringProperty");
95          pd = fetchDescriptor(props, "fluentProperty");
96          assertNull(pd.getReadMethod(), "Read method for fluentProperty");
97          assertNotNull(pd.getWriteMethod(), "No write method for fluentProperty");
98          pd = fetchDescriptor(props, "fluentGetProperty");
99          assertNotNull(pd.getReadMethod(), "No read method for fluentGetProperty");
100         assertNotNull(pd.getWriteMethod(), "No write method for fluentGetProperty");
101     }
102 
103     @Test
104     public void testIntrospectionCaps() throws Exception {
105         final PropertyUtilsBean pu = new PropertyUtilsBean();
106 
107         final FluentPropertyBeanIntrospector introspector = new FluentPropertyBeanIntrospector();
108 
109         pu.addBeanIntrospector(introspector);
110 
111         final Map<String, PropertyDescriptor> props = createDescriptorMap(pu.getPropertyDescriptors(CapsBean.class));
112 
113         final PropertyDescriptor aDescriptor = fetchDescriptor(props, "URI");
114 
115         assertNotNull(aDescriptor, "missing property");
116 
117         assertNotNull(aDescriptor.getReadMethod(), "No read method for uri");
118         assertNotNull(aDescriptor.getWriteMethod(), "No write method for uri");
119 
120         assertNull(props.get("uRI"), "Should not find mis-capitalized property");
121     }
122 }