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    *     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  
18  package org.apache.commons.configuration2.convert;
19  
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertSame;
22  import static org.junit.jupiter.api.Assertions.assertThrows;
23  
24  import java.io.File;
25  import java.lang.annotation.ElementType;
26  import java.math.BigDecimal;
27  import java.nio.file.Path;
28  import java.nio.file.Paths;
29  import java.util.regex.Pattern;
30  
31  import org.apache.commons.configuration2.ex.ConversionException;
32  import org.junit.jupiter.api.Disabled;
33  import org.junit.jupiter.api.Test;
34  
35  /**
36   * Test class for PropertyConverter.
37   */
38  public class TestPropertyConverter {
39      /** Constant for an enumeration class used by some tests. */
40      private static final Class<ElementType> ENUM_CLASS = ElementType.class;
41  
42      /**
43       * See CONFIGURATION-766.
44       */
45      @Test
46      public void testToBigDecimalDoubleConstructor() {
47          // If the conversion uses new BigDecimal(0.1) the result is not exact due to round off.
48          // The result is 0.1000000000000000055511151231257827021181583404541015625.
49          // See Sonar rule: https://rules.sonarsource.com/java/type/Bug/RSPEC-2111
50          final double d = 0.1;
51          // Use BigDecimal#valueOf() Fix PMD AvoidDecimalLiteralsInBigDecimalConstructor
52          assertEquals(BigDecimal.valueOf(d), PropertyConverter.toBigDecimal(d));
53      }
54  
55      /**
56       * See CONFIGURATION-766.
57       */
58      @Test
59      @Disabled
60      public void testToBigDecimalStringConstructor() {
61          // If the conversion uses new BigDecimal(0.1) the result is not exact due to round off.
62          // The result is 0.1000000000000000055511151231257827021181583404541015625.
63          // See Sonar rule: https://rules.sonarsource.com/java/type/Bug/RSPEC-2111
64          final double d = 0.1;
65          assertEquals(new BigDecimal(Double.toString(d)), PropertyConverter.toBigDecimal(d));
66      }
67  
68      /**
69       * Tests a failed conversion to character.
70       */
71      @Test
72      public void testToCharFailed() {
73          final DefaultConversionHandler conversionHandler = new DefaultConversionHandler();
74          assertThrows(ConversionException.class, () -> PropertyConverter.to(Character.TYPE, "FF", conversionHandler));
75      }
76  
77      /**
78       * Tests whether a conversion to character is possible.
79       */
80      @Test
81      public void testToCharSuccess() {
82          assertEquals(Character.valueOf('t'), PropertyConverter.to(Character.class, "t", new DefaultConversionHandler()));
83      }
84  
85      /**
86       * Tests whether other objects implementing a toString() method can be converted to character.
87       */
88      @Test
89      public void testToCharViaToString() {
90          final Object value = new Object() {
91              @Override
92              public String toString() {
93                  return "X";
94              }
95          };
96          assertEquals(Character.valueOf('X'), PropertyConverter.to(Character.TYPE, value, new DefaultConversionHandler()));
97      }
98  
99      @Test
100     public void testToEnumFromEnum() {
101         assertEquals(ElementType.METHOD, PropertyConverter.toEnum(ElementType.METHOD, ENUM_CLASS));
102     }
103 
104     @Test
105     public void testToEnumFromInvalidNumber() {
106         assertThrows(ConversionException.class, () -> PropertyConverter.toEnum(-1, ENUM_CLASS));
107     }
108 
109     @Test
110     public void testToEnumFromInvalidString() {
111         assertThrows(ConversionException.class, () -> PropertyConverter.toEnum("FOO", ENUM_CLASS));
112     }
113 
114     @Test
115     public void testToEnumFromNumber() {
116         assertEquals(PropertyConverter.toEnum(Integer.valueOf(ElementType.METHOD.ordinal()), ENUM_CLASS), ElementType.METHOD);
117     }
118 
119     @Test
120     public void testToEnumFromString() {
121         assertEquals(ElementType.METHOD, PropertyConverter.toEnum("METHOD", ENUM_CLASS));
122     }
123 
124     /**
125      * Tests conversion to files when the passed in objects are already files.
126      */
127     @Test
128     public void testToFileDirect() {
129         final File f = new File("dir", "file");
130         assertSame(f, PropertyConverter.toFile(f));
131     }
132 
133     /**
134      * Tests conversion to file when the passed in objects are paths.
135      */
136     @Test
137     public void testToFileFromPath() {
138         final Path p = Paths.get("dir", "file");
139         assertEquals(new File("dir", "file"), PropertyConverter.toFile(p));
140     }
141 
142     /**
143      * Tests conversion to file when the passed in objects have a compatible string representation.
144      */
145     @Test
146     public void testToFileFromString() {
147         assertEquals(new File("dir", "file"), PropertyConverter.toFile("dir/file"));
148     }
149 
150     /**
151      * Tests a trivial conversion: the value has already the desired type.
152      */
153     @Test
154     public void testToNoConversionNeeded() {
155         final String value = "testValue";
156         assertEquals(value, PropertyConverter.to(String.class, value, new DefaultConversionHandler()));
157     }
158 
159     /**
160      * Tests conversion to numbers when the passed in objects are already numbers.
161      */
162     @Test
163     public void testToNumberDirect() {
164         final Integer i = Integer.valueOf(42);
165         assertSame(i, PropertyConverter.toNumber(i, Integer.class));
166         final BigDecimal d = new BigDecimal("3.1415");
167         assertSame(d, PropertyConverter.toNumber(d, Integer.class));
168     }
169 
170     /**
171      * Tests conversion to numbers when the passed in objects are strings with prefixes for special radices.
172      */
173     @Test
174     public void testToNumberFromBinaryString() {
175         final Number n = PropertyConverter.toNumber("0b1111", Integer.class);
176         assertEquals(15, n.intValue());
177     }
178 
179     /**
180      * Tests conversion to numbers when the passed in objects are strings with prefixes for special radices.
181      */
182     @Test
183     public void testToNumberFromHexString() {
184         final Number n = PropertyConverter.toNumber("0x10", Integer.class);
185         assertEquals(16, n.intValue());
186     }
187 
188     /**
189      * Tests conversion to numbers when an invalid binary value is passed in. This should cause an exception.
190      */
191     @Test
192     public void testToNumberFromInvalidBinaryString() {
193         assertThrows(ConversionException.class, () -> PropertyConverter.toNumber("0bNotABinValue", Integer.class));
194     }
195 
196     /**
197      * Tests conversion to numbers when an invalid Hex value is passed in. This should cause an exception.
198      */
199     @Test
200     public void testToNumberFromInvalidHexString() {
201         assertThrows(ConversionException.class, () -> PropertyConverter.toNumber("0xNotAHexValue", Integer.class));
202     }
203 
204     /**
205      * Tests conversion to numbers when the passed in objects have no numeric String representation. This should cause an
206      * exception.
207      */
208     @Test
209     public void testToNumberFromInvalidString() {
210         assertThrows(ConversionException.class, () -> PropertyConverter.toNumber("Not a number", Byte.class));
211     }
212 
213     /**
214      * Tests conversion to numbers when the passed in objects have a compatible string representation.
215      */
216     @Test
217     public void testToNumberFromString() {
218         assertEquals(Integer.valueOf(42), PropertyConverter.toNumber("42", Integer.class));
219         assertEquals(Short.valueOf((short) 10), PropertyConverter.toNumber(new StringBuffer("10"), Short.class));
220     }
221 
222     /**
223      * Tests conversion to numbers when the passed in target class is invalid. This should cause an exception.
224      */
225     @Test
226     public void testToNumberWithInvalidClass() {
227         assertThrows(ConversionException.class, () -> PropertyConverter.toNumber("42", Object.class));
228     }
229 
230     /**
231      * Tests conversion to paths when the passed in objects are already paths.
232      */
233     @Test
234     public void testToPathDirect() {
235         final Path p = Paths.get("dir", "file");
236         assertSame(p, PropertyConverter.toPath(p));
237     }
238 
239     /**
240      * Tests conversion to path when the passed in objects are files.
241      */
242     @Test
243     public void testToPathFromFile() {
244         final File f = new File("dir", "file");
245         assertEquals(Paths.get("dir", "file"), PropertyConverter.toPath(f));
246     }
247 
248     /**
249      * Tests conversion to file when the passed in objects have a compatible string representation.
250      */
251     @Test
252     public void testToPathFromString() {
253         assertEquals(Paths.get("dir", "file"), PropertyConverter.toPath("dir/file"));
254     }
255 
256     /**
257      * Tests conversion to patterns when the passed in objects are already patterns.
258      */
259     @Test
260     public void testToPatternDirect() {
261         final Pattern p = Pattern.compile(".+");
262         assertSame(p, PropertyConverter.toPattern(p));
263     }
264 
265     /**
266      * Tests conversion to patterns when the passed in objects have a compatible string representation.
267      */
268     @Test
269     public void testToPatternFromString() {
270         final Pattern p = Pattern.compile(".+");
271         assertEquals(p.pattern(), PropertyConverter.toPattern(".+").pattern());
272     }
273 
274     /**
275      * Tests a conversion to a string.
276      */
277     @Test
278     public void testToStringConversion() {
279         final Integer src = 42;
280         final Object result = PropertyConverter.to(String.class, src, new DefaultConversionHandler());
281         assertEquals("42", result);
282     }
283 }