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;
19  
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertFalse;
22  import static org.junit.jupiter.api.Assertions.assertNull;
23  import static org.junit.jupiter.api.Assertions.assertThrows;
24  
25  import java.math.BigDecimal;
26  import java.math.BigInteger;
27  import java.util.Arrays;
28  import java.util.Iterator;
29  import java.util.List;
30  import java.util.NoSuchElementException;
31  import java.util.Properties;
32  
33  import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
34  import org.apache.commons.configuration2.ex.ConversionException;
35  import org.junit.jupiter.api.BeforeEach;
36  import org.junit.jupiter.api.Test;
37  
38  /**
39   * Tests some basic functions of the BaseConfiguration class. Missing keys might return null.
40   */
41  public class TestBaseNullConfiguration {
42      protected BaseConfiguration config;
43  
44      @BeforeEach
45      public void setUp() throws Exception {
46          config = new BaseConfiguration();
47          config.setListDelimiterHandler(new DefaultListDelimiterHandler(','));
48          config.setThrowExceptionOnMissing(false);
49      }
50  
51      @Test
52      public void testCommaSeparatedString() {
53          final String prop = "hey, that's a test";
54          config.setProperty("prop.string", prop);
55          final List<Object> list = config.getList("prop.string");
56          assertEquals(Arrays.asList("hey", "that's a test"), list);
57      }
58  
59      @Test
60      public void testCommaSeparatedStringEscaped() {
61          final String prop2 = "hey\\, that's a test";
62          config.clearProperty("prop.string");
63          config.setProperty("prop.string", prop2);
64          assertEquals("hey, that's a test", config.getString("prop.string"));
65      }
66  
67      @Test
68      public void testGetBigDecimal() {
69          config.setProperty("numberBigD", "123.456");
70          final BigDecimal number = new BigDecimal("123.456");
71          final BigDecimal defaultValue = new BigDecimal("654.321");
72  
73          assertEquals(number, config.getBigDecimal("numberBigD"));
74          assertEquals(number, config.getBigDecimal("numberBigD", defaultValue));
75          assertEquals(defaultValue, config.getBigDecimal("numberNotInConfig", defaultValue));
76      }
77  
78      @Test
79      public void testGetBigDecimalIncompatibleType() {
80          config.setProperty("test.empty", "");
81          assertThrows(ConversionException.class, () -> config.getBigDecimal("test.empty"));
82      }
83  
84      @Test
85      public void testGetBigDecimalUnknown() {
86          assertNull(config.getBigDecimal("numberNotInConfig"));
87      }
88  
89      @Test
90      public void testGetBigInteger() {
91          config.setProperty("numberBigI", "1234567890");
92          final BigInteger number = new BigInteger("1234567890");
93          final BigInteger defaultValue = new BigInteger("654321");
94  
95          assertEquals(number, config.getBigInteger("numberBigI"));
96          assertEquals(number, config.getBigInteger("numberBigI", defaultValue));
97          assertEquals(defaultValue, config.getBigInteger("numberNotInConfig", defaultValue));
98      }
99  
100     @Test
101     public void testGetBigIntegerIncompatibleType() {
102         config.setProperty("test.empty", "");
103         assertThrows(ConversionException.class, () -> config.getBigInteger("test.empty"));
104     }
105 
106     @Test
107     public void testGetBigIntegerUnknown() {
108         assertNull(config.getBigInteger("numberNotInConfig"));
109     }
110 
111     @Test
112     public void testGetBoolean() {
113         config.setProperty("boolA", Boolean.TRUE);
114         final boolean boolT = true, boolF = false;
115         assertEquals(boolT, config.getBoolean("boolA"));
116         assertEquals(boolT, config.getBoolean("boolA", boolF));
117         assertEquals(boolF, config.getBoolean("boolNotInConfig", boolF));
118         assertEquals(Boolean.valueOf(boolT), config.getBoolean("boolA", Boolean.valueOf(boolF)));
119     }
120 
121     @Test
122     public void testGetBooleanIncompatibleType() {
123         config.setProperty("test.empty", "");
124         assertThrows(ConversionException.class, () -> config.getBoolean("test.empty"));
125     }
126 
127     @Test
128     public void testGetBooleanUnknown() {
129         assertThrows(NoSuchElementException.class, () -> config.getBoolean("numberNotInConfig"));
130     }
131 
132     @Test
133     public void testGetByte() {
134         config.setProperty("number", "1");
135         final byte oneB = 1;
136         final byte twoB = 2;
137         assertEquals(oneB, config.getByte("number"));
138         assertEquals(oneB, config.getByte("number", twoB));
139         assertEquals(twoB, config.getByte("numberNotInConfig", twoB));
140         assertEquals(Byte.valueOf(oneB), config.getByte("number", Byte.valueOf("2")));
141     }
142 
143     @Test
144     public void testGetByteIncompatibleType() {
145         config.setProperty("test.empty", "");
146         assertThrows(ConversionException.class, () -> config.getByte("test.empty"));
147     }
148 
149     @Test
150     public void testGetByteUnknown() {
151         assertThrows(NoSuchElementException.class, () -> config.getByte("numberNotInConfig"));
152     }
153 
154     @Test
155     public void testGetDouble() {
156         config.setProperty("numberD", "1.0");
157         final double oneD = 1;
158         final double twoD = 2;
159         assertEquals(oneD, config.getDouble("numberD"), 0);
160         assertEquals(oneD, config.getDouble("numberD", twoD), 0);
161         assertEquals(twoD, config.getDouble("numberNotInConfig", twoD), 0);
162         assertEquals(Double.valueOf(oneD), config.getDouble("numberD", Double.valueOf("2")));
163     }
164 
165     @Test
166     public void testGetDoubleIncompatibleType() {
167         config.setProperty("test.empty", "");
168         assertThrows(ConversionException.class, () -> config.getDouble("test.empty"));
169     }
170 
171     @Test
172     public void testGetDoubleUnknown() {
173         assertThrows(NoSuchElementException.class, () -> config.getDouble("numberNotInConfig"));
174     }
175 
176     @Test
177     public void testGetFloat() {
178         config.setProperty("numberF", "1.0");
179         final float oneF = 1;
180         final float twoF = 2;
181         assertEquals(oneF, config.getFloat("numberF"), 0);
182         assertEquals(oneF, config.getFloat("numberF", twoF), 0);
183         assertEquals(twoF, config.getFloat("numberNotInConfig", twoF), 0);
184         assertEquals(Float.valueOf(oneF), config.getFloat("numberF", Float.valueOf("2")));
185     }
186 
187     @Test
188     public void testGetFloatIncompatibleType() {
189         config.setProperty("test.empty", "");
190         assertThrows(ConversionException.class, () -> config.getFloat("test.empty"));
191     }
192 
193     @Test
194     public void testGetFloatUnknown() {
195         assertThrows(NoSuchElementException.class, () -> config.getFloat("numberNotInConfig"));
196     }
197 
198     @Test
199     public void testGetList() {
200         config.addProperty("number", "1");
201         config.addProperty("number", "2");
202         final List<Object> list = config.getList("number");
203         assertEquals(Arrays.asList("1", "2"), list);
204     }
205 
206     @Test
207     public void testGetListAsScalar() {
208         config.addProperty("number", "1");
209         config.addProperty("number", "2");
210         assertEquals("1", config.getString("number"));
211     }
212 
213     @Test
214     public void testGetLong() {
215         config.setProperty("numberL", "1");
216         final long oneL = 1;
217         final long twoL = 2;
218         assertEquals(oneL, config.getLong("numberL"));
219         assertEquals(oneL, config.getLong("numberL", twoL));
220         assertEquals(twoL, config.getLong("numberNotInConfig", twoL));
221         assertEquals(Long.valueOf(oneL), config.getLong("numberL", Long.valueOf("2")));
222     }
223 
224     @Test
225     public void testGetLongIncompatibleTypes() {
226         config.setProperty("test.empty", "");
227         assertThrows(ConversionException.class, () -> config.getLong("test.empty"));
228     }
229 
230     @Test
231     public void testGetLongUnknown() {
232         assertThrows(NoSuchElementException.class, () -> config.getLong("numberNotInConfig"));
233     }
234 
235     @Test
236     public void testGetProperty() {
237         /* should be empty and return null */
238         assertNull(config.getProperty("foo"));
239 
240         /* add a real value, and get it two different ways */
241         config.setProperty("number", "1");
242         assertEquals("1", config.getProperty("number"));
243         assertEquals("1", config.getString("number"));
244     }
245 
246     @Test
247     public void testGetShort() {
248         config.setProperty("numberS", "1");
249         final short oneS = 1;
250         final short twoS = 2;
251         assertEquals(oneS, config.getShort("numberS"));
252         assertEquals(oneS, config.getShort("numberS", twoS));
253         assertEquals(twoS, config.getShort("numberNotInConfig", twoS));
254         assertEquals(Short.valueOf(oneS), config.getShort("numberS", Short.valueOf("2")));
255     }
256 
257     @Test
258     public void testGetShortIncompatibleType() {
259         config.setProperty("test.empty", "");
260         assertThrows(ConversionException.class, () -> config.getShort("test.empty"));
261     }
262 
263     @Test
264     public void testGetShortUnknown() {
265         assertThrows(NoSuchElementException.class, () -> config.getShort("numberNotInConfig"));
266     }
267 
268     @Test
269     public void testGetString() {
270         config.setProperty("testString", "The quick brown fox");
271         final String string = "The quick brown fox";
272         final String defaultValue = "jumps over the lazy dog";
273 
274         assertEquals(string, config.getString("testString"));
275         assertEquals(string, config.getString("testString", defaultValue));
276         assertEquals(defaultValue, config.getString("stringNotInConfig", defaultValue));
277     }
278 
279     @Test
280     public void testGetStringUnknown() {
281         assertNull(config.getString("stringNotInConfig"));
282     }
283 
284     @Test
285     public void testInterpolation() throws Exception {
286         config.setProperty("applicationRoot", "/home/applicationRoot");
287         config.setProperty("db", "${applicationRoot}/db/hypersonic");
288         final String unInterpolatedValue = "${applicationRoot2}/db/hypersonic";
289         config.setProperty("dbFailedInterpolate", unInterpolatedValue);
290         final String dbProp = "/home/applicationRoot/db/hypersonic";
291 
292         // construct a new config, using config as the defaults config for it.
293         final BaseConfiguration superProp = config;
294 
295         assertEquals(dbProp, superProp.getString("db"));
296         assertEquals(unInterpolatedValue, superProp.getString("dbFailedInterpolate"));
297 
298         superProp.setProperty("arrayInt", "${applicationRoot}/1");
299         final String[] arrayInt = superProp.getStringArray("arrayInt");
300         assertEquals("/home/applicationRoot/1", arrayInt[0]);
301     }
302 
303     @Test
304     public void testInterpolationLoop() throws Exception {
305         config.setProperty("test.a", "${test.b}");
306         config.setProperty("test.b", "${test.a}");
307         assertThrows(IllegalStateException.class, () -> config.getString("test.a"));
308     }
309 
310     @Test
311     public void testMultipleInterpolation() throws Exception {
312         config.setProperty("test.base-level", "/base-level");
313         config.setProperty("test.first-level", "${test.base-level}/first-level");
314         config.setProperty("test.second-level", "${test.first-level}/second-level");
315         config.setProperty("test.third-level", "${test.second-level}/third-level");
316 
317         final String expectedValue = "/base-level/first-level/second-level/third-level";
318 
319         assertEquals(expectedValue, config.getString("test.third-level"));
320     }
321 
322     @Test
323     public void testPropertyAccess() {
324         config.clearProperty("prop.properties");
325         config.setProperty("prop.properties", "");
326         assertEquals(new Properties(), config.getProperties("prop.properties"));
327         config.clearProperty("prop.properties");
328         config.setProperty("prop.properties", "foo=bar, baz=moo, seal=clubber");
329 
330         final Properties p = new Properties();
331         p.setProperty("foo", "bar");
332         p.setProperty("baz", "moo");
333         p.setProperty("seal", "clubber");
334         assertEquals(p, config.getProperties("prop.properties"));
335     }
336 
337     @Test
338     public void testSubset() {
339         /*
340          * test subset : assure we don't reprocess the data elements when generating the subset
341          */
342 
343         final String prop = "hey, that's a test";
344         final String prop2 = "hey\\, that's a test";
345         config.setProperty("prop.string", prop2);
346         config.setProperty("property.string", "hello");
347 
348         Configuration subEprop = config.subset("prop");
349 
350         assertEquals(prop, subEprop.getString("string"));
351         assertEquals(1, subEprop.getList("string").size());
352 
353         Iterator<String> it = subEprop.getKeys();
354         it.next();
355         assertFalse(it.hasNext());
356 
357         subEprop = config.subset("prop.");
358         it = subEprop.getKeys();
359         assertFalse(it.hasNext());
360     }
361 
362     @Test
363     public void testThrowExceptionOnMissing() {
364         assertFalse(config.isThrowExceptionOnMissing());
365     }
366 }