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.configuration2.convert;
18  
19  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertNull;
22  import static org.junit.jupiter.api.Assertions.assertThrows;
23  import static org.junit.jupiter.api.Assertions.assertTrue;
24  
25  import java.util.ArrayList;
26  import java.util.Arrays;
27  import java.util.Calendar;
28  import java.util.Collection;
29  import java.util.Date;
30  import java.util.Iterator;
31  import java.util.List;
32  
33  import org.apache.commons.configuration2.ex.ConversionException;
34  import org.apache.commons.configuration2.interpol.ConfigurationInterpolator;
35  import org.junit.jupiter.api.BeforeEach;
36  import org.junit.jupiter.api.Test;
37  
38  /**
39   * Test class for {@code DefaultConversionHandler}.
40   */
41  public class TestDefaultConversionHandler {
42  
43      /** Constant for a variable. */
44      private static final String VAR = "${test}";
45  
46      /** Constant for the value to replace the variable. */
47      private static final String REPLACEMENT = "1";
48  
49      /**
50       * Creates a special test ConfigurationInterpolator. This object only replaces the test variable by its replacement.
51       * Other substitutions are not performed.
52       *
53       * @return the test {@code ConfigurationInterpolator}
54       */
55      private static ConfigurationInterpolator createInterpolator() {
56          return new ConfigurationInterpolator() {
57              @Override
58              public Object interpolate(final Object value) {
59                  if (VAR.equals(value)) {
60                      return REPLACEMENT;
61                  }
62                  return value;
63              }
64          };
65      }
66  
67      /** The conversion handler to be tested. */
68      private DefaultConversionHandler handler;
69  
70      /**
71       * Helper method for testing the result of the conversion of a single value.
72       *
73       * @param expResult the expected result
74       */
75      private void checkSingleValue(final Integer expResult) {
76          assertEquals(Integer.parseInt(REPLACEMENT), expResult.intValue());
77      }
78  
79      @BeforeEach
80      public void setUp() {
81          handler = new DefaultConversionHandler();
82      }
83  
84      /**
85       * Tests whether the default date format is used if no format has been set.
86       */
87      @Test
88      void testGetDateFormatNotSet() {
89          assertEquals(DefaultConversionHandler.DEFAULT_DATE_FORMAT, handler.getDateFormat());
90      }
91  
92      @Test
93      public synchronized void testListDelimiterHandler() {
94          assertEquals(DefaultConversionHandler.LIST_DELIMITER_HANDLER, handler.getListDelimiterHandler());
95          handler.setListDelimiterHandler(null);
96          assertEquals(DefaultConversionHandler.LIST_DELIMITER_HANDLER, handler.getListDelimiterHandler());
97          final LegacyListDelimiterHandler legacyListDelimiterHandler = new LegacyListDelimiterHandler(',');
98          handler.setListDelimiterHandler(legacyListDelimiterHandler);
99          assertEquals(legacyListDelimiterHandler, handler.getListDelimiterHandler());
100         handler.setListDelimiterHandler(null);
101         assertEquals(DefaultConversionHandler.LIST_DELIMITER_HANDLER, handler.getListDelimiterHandler());
102     }
103 
104     /**
105      * Tests whether the date format can be changed.
106      */
107     @Test
108     void testSetDateFormat() {
109         final String dateFormat = "dd.MM.yyyy";
110         handler.setDateFormat(dateFormat);
111         assertEquals(dateFormat, handler.getDateFormat());
112     }
113 
114     /**
115      * Tests a conversion to an array from an empty string. An empty string should be interpreted as an empty array.
116      */
117     @Test
118     void testToArrayEmptyString() {
119         final int[] array = (int[]) handler.toArray("", Integer.TYPE, null);
120         assertEquals(0, array.length);
121     }
122 
123     /**
124      * Tests toArray() if the source object is null.
125      */
126     @Test
127     void testToArrayNullInput() {
128         assertNull(handler.toArray(null, Integer.class, null));
129     }
130 
131     /**
132      * Tests a conversion to an array of Objects.
133      */
134     @Test
135     void testToArrayObject() {
136         final List<String> src = Arrays.asList(VAR, "100");
137         final Integer[] array = (Integer[]) handler.toArray(src, Integer.class, createInterpolator());
138         assertArrayEquals(new Integer[] {Integer.valueOf(REPLACEMENT), Integer.valueOf(src.get(1))}, array);
139     }
140 
141     /**
142      * Tests a conversion to an array of primitive type if the source object is something else.
143      */
144     @Test
145     void testToArrayPrimitiveOtherType() {
146         final List<String> src = Arrays.asList(VAR, "100");
147         final int[] array = (int[]) handler.toArray(src, Integer.TYPE, createInterpolator());
148         assertArrayEquals(new int[] {Integer.parseInt(REPLACEMENT), Integer.parseInt(src.get(1))}, array);
149     }
150 
151     /**
152      * Tests a conversion to an array of primitive type if the source array already has the correct type.
153      */
154     @Test
155     void testToArrayPrimitiveSameType() {
156         final int[] src = {1, 2, 3, 4, 5, 6};
157         final int[] array = (int[]) handler.toArray(src, Integer.TYPE, createInterpolator());
158         assertArrayEquals(src, array);
159     }
160 
161     /**
162      * Tests a conversion to an array of primitive type if the source array is of the corresponding wrapper type.
163      */
164     @Test
165     void testToArrayPrimitiveWrapperType() {
166         final Integer[] src = {0, 1, 2, 4, 8, 16, 32, 64, 128};
167         final int[] array = (int[]) handler.toArray(src, Integer.TYPE, createInterpolator());
168         assertArrayEquals(new int[] {0, 1, 2, 4, 8, 16, 32, 64, 128}, array);
169     }
170 
171     /**
172      * Tests a conversion to a Calendar object using the default format.
173      */
174     @Test
175     void testToCalendarWithDefaultFormat() {
176         final Calendar cal = handler.to("2013-08-19 21:17:22", Calendar.class, null);
177         assertEquals(19, cal.get(Calendar.DATE));
178         assertEquals(Calendar.AUGUST, cal.get(Calendar.MONTH));
179         assertEquals(2013, cal.get(Calendar.YEAR));
180         assertEquals(21, cal.get(Calendar.HOUR_OF_DAY));
181         assertEquals(17, cal.get(Calendar.MINUTE));
182         assertEquals(22, cal.get(Calendar.SECOND));
183     }
184 
185     /**
186      * Tests a conversion to a collection if an empty string is passed in. An empty string should be interpreted as a list
187      * with no values.
188      */
189     @Test
190     void testToCollectionEmptyString() {
191         final List<Integer> col = new ArrayList<>(1);
192         handler.toCollection("", Integer.class, null, col);
193         assertTrue(col.isEmpty());
194     }
195 
196     /**
197      * Tries to pass a null collection to toCollection().
198      */
199     @Test
200     void testToCollectionNullCollection() {
201         final List<Integer> src = Arrays.asList(1, 2, 3);
202         assertThrows(IllegalArgumentException.class, () -> handler.toCollection(src, Integer.class, null, null));
203     }
204 
205     /**
206      * Tests a conversion to a collection if the source object is null.
207      */
208     @Test
209     void testToCollectionNullInput() {
210         final ArrayList<Integer> col = new ArrayList<>();
211         handler.toCollection(null, Integer.class, null, col);
212         assertTrue(col.isEmpty());
213     }
214 
215     /**
216      * Tests a successful conversion to a collection.
217      */
218     @Test
219     void testToCollectionSuccess() {
220         final Object[] src = {VAR, "100"};
221         final List<Integer> col = new ArrayList<>(src.length);
222         handler.toCollection(src, Integer.class, createInterpolator(), col);
223         assertEquals(Arrays.asList(Integer.valueOf(REPLACEMENT), Integer.valueOf(src[1].toString())), col);
224     }
225 
226     @Test
227     void testToCustomNumber() {
228         // convertValue()
229         assertEquals(new MyNumber(1), DefaultConversionHandler.INSTANCE.convertValue(new MyNumber(1), MyNumber.class, null));
230         assertEquals(new MyNumber(2), DefaultConversionHandler.INSTANCE.convertValue(new MyNumber(2), MyNumber.class, null));
231         assertEquals(new MyNumber(3), DefaultConversionHandler.INSTANCE.convertValue("3", MyNumber.class, null));
232         assertNull(DefaultConversionHandler.INSTANCE.convertValue(null, MyNumber.class, null));
233         // to()
234         assertEquals(new MyNumber(1), DefaultConversionHandler.INSTANCE.to(new MyNumber(1), MyNumber.class, null));
235         assertEquals(new MyNumber(2), DefaultConversionHandler.INSTANCE.to(new MyNumber(2), MyNumber.class, null));
236         assertEquals(new MyNumber(3), DefaultConversionHandler.INSTANCE.to("3", MyNumber.class, null));
237         assertNull(DefaultConversionHandler.INSTANCE.to(null, MyNumber.class, null));
238     }
239 
240     /**
241      * Tests whether a conversion to a date object is possible if a specific date format is used.
242      */
243     @Test
244     void testToDateWithFormat() {
245         handler.setDateFormat("dd.MM.yyyy");
246         final Date dt = handler.to("19.08.2013", Date.class, null);
247         final Calendar cal = Calendar.getInstance();
248         cal.setTime(dt);
249         assertEquals(19, cal.get(Calendar.DATE));
250         assertEquals(Calendar.AUGUST, cal.get(Calendar.MONTH));
251         assertEquals(2013, cal.get(Calendar.YEAR));
252     }
253 
254     /**
255      * Tests a failed conversion.
256      */
257     @Test
258     void testToFailedConversion() {
259         assertThrows(ConversionException.class, () -> handler.to(VAR, Integer.class, null));
260     }
261 
262     /**
263      * Tests whether a conversion from an array is possible.
264      */
265     @Test
266     void testToFromArray() {
267         final Object[] src = {VAR, true, 20130808221759L};
268         checkSingleValue(handler.to(src, Integer.class, createInterpolator()));
269     }
270 
271     /**
272      * Tests whether a conversion from a collection is possible.
273      */
274     @Test
275     void testToFromCollection() {
276         final Collection<String> src = Arrays.asList(VAR, "true", "1000");
277         checkSingleValue(handler.to(src, Integer.class, createInterpolator()));
278     }
279 
280     /**
281      * Tests whether empty complex objects are handled when converting to a single value.
282      */
283     @Test
284     void testToFromEmptyCollection() {
285         assertNull(handler.to(new ArrayList<>(), Integer.class, createInterpolator()));
286     }
287 
288     /**
289      * Tests whether a conversion from an iterator is possible.
290      */
291     @Test
292     void testToFromIterator() {
293         final Iterator<String> src = Arrays.asList(VAR, "true", "1000").iterator();
294         checkSingleValue(handler.to(src, Integer.class, createInterpolator()));
295     }
296 
297     /**
298      * Tests whether a ConfigurationInterpolator is optional.
299      */
300     @Test
301     void testToNoInterpolator() {
302         final Integer result = handler.to(REPLACEMENT, Integer.class, null);
303         checkSingleValue(result);
304     }
305 
306     /**
307      * Tests whether null input is handled by to().
308      */
309     @Test
310     void testToNull() {
311         assertNull(handler.to(null, Integer.class, null));
312     }
313 
314     /**
315      * Tests a conversion to a primitive type.
316      */
317     @Test
318     void testToPrimitive() {
319         final Long value = 20130819214935L;
320         final Object result = handler.to(value.toString(), Long.TYPE, null);
321         assertEquals(value, result);
322     }
323 
324     /**
325      * Tests a conversion with a ConfigurationInterpolator.
326      */
327     @Test
328     void testToWithInterpolator() {
329         final Integer result = handler.to(VAR, Integer.class, createInterpolator());
330         checkSingleValue(result);
331     }
332 }