001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.configuration;
019    
020    import static org.junit.Assert.assertEquals;
021    import static org.junit.Assert.assertFalse;
022    import static org.junit.Assert.assertNotNull;
023    import static org.junit.Assert.assertNull;
024    import static org.junit.Assert.assertTrue;
025    
026    import java.math.BigDecimal;
027    import java.math.BigInteger;
028    import java.util.Iterator;
029    import java.util.List;
030    import java.util.NoSuchElementException;
031    import java.util.Properties;
032    
033    import org.junit.Before;
034    import org.junit.Test;
035    
036    /**
037     * Tests some basic functions of the BaseConfiguration class. Missing keys might
038     * return null.
039     *
040     * @version $Id: TestBaseNullConfiguration.java 1222842 2011-12-23 20:56:58Z oheger $
041     */
042    public class TestBaseNullConfiguration
043    {
044        protected BaseConfiguration config;
045    
046        @Before
047        public void setUp() throws Exception
048        {
049            config = new BaseConfiguration();
050            config.setThrowExceptionOnMissing(false);
051        }
052    
053        @Test
054        public void testThrowExceptionOnMissing()
055        {
056            assertFalse("Throw Exception Property is set!", config.isThrowExceptionOnMissing());
057        }
058    
059        @Test
060        public void testGetProperty()
061        {
062            /* should be empty and return null */
063            assertEquals("This returns null", config.getProperty("foo"), null);
064    
065            /* add a real value, and get it two different ways */
066            config.setProperty("number", "1");
067            assertEquals("This returns '1'", config.getProperty("number"), "1");
068            assertEquals("This returns '1'", config.getString("number"), "1");
069        }
070    
071        @Test
072        public void testGetByte()
073        {
074            config.setProperty("number", "1");
075            byte oneB = 1;
076            byte twoB = 2;
077            assertEquals("This returns 1(byte)", oneB, config.getByte("number"));
078            assertEquals("This returns 1(byte)", oneB, config.getByte("number", twoB));
079            assertEquals("This returns 2(default byte)", twoB, config.getByte("numberNotInConfig", twoB));
080            assertEquals("This returns 1(Byte)", new Byte(oneB), config.getByte("number", new Byte("2")));
081        }
082    
083        @Test(expected = NoSuchElementException.class)
084        public void testGetByteUnknown()
085        {
086            config.getByte("numberNotInConfig");
087        }
088    
089        @Test(expected = ConversionException.class)
090        public void testGetByteIncompatibleType()
091        {
092            config.setProperty("test.empty", "");
093            config.getByte("test.empty");
094        }
095    
096        @Test
097        public void testGetShort()
098        {
099            config.setProperty("numberS", "1");
100            short oneS = 1;
101            short twoS = 2;
102            assertEquals("This returns 1(short)", oneS, config.getShort("numberS"));
103            assertEquals("This returns 1(short)", oneS, config.getShort("numberS", twoS));
104            assertEquals("This returns 2(default short)", twoS, config.getShort("numberNotInConfig", twoS));
105            assertEquals("This returns 1(Short)", new Short(oneS), config.getShort("numberS", new Short("2")));
106        }
107    
108        @Test(expected = NoSuchElementException.class)
109        public void testGetShortUnknown()
110        {
111            config.getShort("numberNotInConfig");
112        }
113    
114        @Test(expected = ConversionException.class)
115        public void testGetShortIncompatibleType()
116        {
117            config.setProperty("test.empty", "");
118            config.getShort("test.empty");
119        }
120    
121        @Test
122        public void testGetLong()
123        {
124            config.setProperty("numberL", "1");
125            long oneL = 1;
126            long twoL = 2;
127            assertEquals("This returns 1(long)", oneL, config.getLong("numberL"));
128            assertEquals("This returns 1(long)", oneL, config.getLong("numberL", twoL));
129            assertEquals("This returns 2(default long)", twoL, config.getLong("numberNotInConfig", twoL));
130            assertEquals("This returns 1(Long)", new Long(oneL), config.getLong("numberL", new Long("2")));
131        }
132    
133        @Test(expected = NoSuchElementException.class)
134        public void testGetLongUnknown()
135        {
136            config.getLong("numberNotInConfig");
137        }
138    
139        @Test(expected = ConversionException.class)
140        public void testGetLongIncompatibleTypes()
141        {
142            config.setProperty("test.empty", "");
143            config.getLong("test.empty");
144        }
145    
146        @Test
147        public void testGetFloat()
148        {
149            config.setProperty("numberF", "1.0");
150            float oneF = 1;
151            float twoF = 2;
152            assertEquals("This returns 1(float)", oneF, config.getFloat("numberF"), 0);
153            assertEquals("This returns 1(float)", oneF, config.getFloat("numberF", twoF), 0);
154            assertEquals("This returns 2(default float)", twoF, config.getFloat("numberNotInConfig", twoF), 0);
155            assertEquals("This returns 1(Float)", new Float(oneF), config.getFloat("numberF", new Float("2")));
156        }
157    
158        @Test(expected = NoSuchElementException.class)
159        public void testGetFloatUnknown()
160        {
161            config.getFloat("numberNotInConfig");
162        }
163    
164        @Test(expected = ConversionException.class)
165        public void testGetFloatIncompatibleType()
166        {
167            config.setProperty("test.empty", "");
168            config.getFloat("test.empty");
169        }
170    
171        @Test
172        public void testGetDouble()
173        {
174            config.setProperty("numberD", "1.0");
175            double oneD = 1;
176            double twoD = 2;
177            assertEquals("This returns 1(double)", oneD, config.getDouble("numberD"), 0);
178            assertEquals("This returns 1(double)", oneD, config.getDouble("numberD", twoD), 0);
179            assertEquals("This returns 2(default double)", twoD, config.getDouble("numberNotInConfig", twoD), 0);
180            assertEquals("This returns 1(Double)", new Double(oneD), config.getDouble("numberD", new Double("2")));
181        }
182    
183        @Test(expected = NoSuchElementException.class)
184        public void testGetDoubleUnknown()
185        {
186            config.getDouble("numberNotInConfig");
187        }
188    
189        @Test(expected = ConversionException.class)
190        public void testGetDoubleIncompatibleType()
191        {
192            config.setProperty("test.empty", "");
193            config.getDouble("test.empty");
194        }
195    
196        @Test
197        public void testGetBigDecimal()
198        {
199            config.setProperty("numberBigD", "123.456");
200            BigDecimal number = new BigDecimal("123.456");
201            BigDecimal defaultValue = new BigDecimal("654.321");
202    
203            assertEquals("Existing key", number, config.getBigDecimal("numberBigD"));
204            assertEquals("Existing key with default value", number, config.getBigDecimal("numberBigD", defaultValue));
205            assertEquals("Missing key with default value", defaultValue, config.getBigDecimal("numberNotInConfig", defaultValue));
206        }
207    
208        @Test
209        public void testGetBigDecimalUnknown()
210        {
211            assertNull("Missing Key is not null!", config.getBigDecimal("numberNotInConfig"));
212        }
213    
214        @Test(expected = ConversionException.class)
215        public void testGetBigDecimalIncompatibleType()
216        {
217            config.setProperty("test.empty", "");
218            config.getBigDecimal("test.empty");
219        }
220    
221        @Test
222        public void testGetBigInteger()
223        {
224            config.setProperty("numberBigI", "1234567890");
225            BigInteger number = new BigInteger("1234567890");
226            BigInteger defaultValue = new BigInteger("654321");
227    
228            assertEquals("Existing key", number, config.getBigInteger("numberBigI"));
229            assertEquals("Existing key with default value", number, config.getBigInteger("numberBigI", defaultValue));
230            assertEquals("Missing key with default value", defaultValue, config.getBigInteger("numberNotInConfig", defaultValue));
231        }
232    
233        @Test
234        public void testGetBigIntegerUnknown()
235        {
236            assertNull("Missing Key is not null!", config.getBigInteger("numberNotInConfig"));
237        }
238    
239        @Test(expected = ConversionException.class)
240        public void testGetBigIntegerIncompatibleType()
241        {
242            config.setProperty("test.empty", "");
243            config.getBigInteger("test.empty");
244        }
245    
246    
247        @Test
248        public void testGetString()
249        {
250            config.setProperty("testString", "The quick brown fox");
251            String string = new String("The quick brown fox");
252            String defaultValue = new String("jumps over the lazy dog");
253    
254            assertEquals("Existing key", string, config.getString("testString"));
255            assertEquals("Existing key with default value", string, config.getString("testString", defaultValue));
256            assertEquals("Missing key with default value", defaultValue, config.getString("stringNotInConfig", defaultValue));
257        }
258    
259        @Test
260        public void testGetStringUnknown()
261        {
262            assertNull("Missing Key is not null!", config.getString("stringNotInConfig"));
263        }
264    
265        @Test
266        public void testGetBoolean()
267        {
268            config.setProperty("boolA", Boolean.TRUE);
269            boolean boolT = true, boolF = false;
270            assertEquals("This returns true", boolT, config.getBoolean("boolA"));
271            assertEquals("This returns true, not the default", boolT, config.getBoolean("boolA", boolF));
272            assertEquals("This returns false(default)", boolF, config.getBoolean("boolNotInConfig", boolF));
273            assertEquals("This returns true(Boolean)", new Boolean(boolT), config.getBoolean("boolA", new Boolean(boolF)));
274        }
275    
276        @Test(expected = NoSuchElementException.class)
277        public void testGetBooleanUnknown()
278        {
279            config.getBoolean("numberNotInConfig");
280        }
281    
282        @Test(expected = ConversionException.class)
283        public void testGetBooleanIncompatibleType()
284        {
285            config.setProperty("test.empty", "");
286            config.getBoolean("test.empty");
287        }
288    
289        @Test
290        public void testGetList()
291        {
292            config.addProperty("number", "1");
293            config.addProperty("number", "2");
294            List<Object> list = config.getList("number");
295            assertNotNull("The list is null", list);
296            assertEquals("List size", 2, list.size());
297            assertTrue("The number 1 is missing from the list", list.contains("1"));
298            assertTrue("The number 2 is missing from the list", list.contains("2"));
299        }
300    
301        @Test
302        public void testGetListAsScalar()
303        {
304            config.addProperty("number", "1");
305            config.addProperty("number", "2");
306            assertEquals("Wrong value", "1", config.getString("number"));
307        }
308    
309        @Test
310        public void testCommaSeparatedString()
311        {
312            String prop = "hey, that's a test";
313            config.setProperty("prop.string", prop);
314            List<Object> list = config.getList("prop.string");
315            assertEquals("Wrong number of elements", 2, list.size());
316            assertEquals("Wrong element 1", "hey", list.get(0));
317        }
318    
319        @Test
320        public void testCommaSeparatedStringEscaped()
321        {
322            String prop2 = "hey\\, that's a test";
323            config.clearProperty("prop.string");
324            config.setProperty("prop.string", prop2);
325            assertEquals("Wrong value", "hey, that's a test", config.getString("prop.string"));
326        }
327    
328        @Test
329        public void testPropertyAccess()
330        {
331            config.clearProperty("prop.properties");
332            config.setProperty("prop.properties", "");
333            assertEquals(
334                "This returns an empty Properties object",
335                config.getProperties("prop.properties"),
336                new Properties());
337            config.clearProperty("prop.properties");
338            config.setProperty("prop.properties", "foo=bar, baz=moo, seal=clubber");
339    
340            Properties p = new Properties();
341            p.setProperty("foo", "bar");
342            p.setProperty("baz", "moo");
343            p.setProperty("seal", "clubber");
344            assertEquals(
345                "This returns a filled in Properties object",
346                config.getProperties("prop.properties"),
347                p);
348        }
349    
350        @Test
351        public void testSubset()
352        {
353            /*
354             * test subset : assure we don't reprocess the data elements
355             * when generating the subset
356             */
357    
358            String prop = "hey, that's a test";
359            String prop2 = "hey\\, that's a test";
360            config.setProperty("prop.string", prop2);
361            config.setProperty("property.string", "hello");
362    
363            Configuration subEprop = config.subset("prop");
364    
365            assertEquals(
366                "Returns the full string",
367                prop,
368                subEprop.getString("string"));
369            assertEquals("Wrong list size", 1, subEprop.getList("string").size());
370    
371            Iterator<String> it = subEprop.getKeys();
372            it.next();
373            assertFalse(it.hasNext());
374    
375            subEprop = config.subset("prop.");
376            it = subEprop.getKeys();
377            assertFalse(it.hasNext());
378        }
379    
380        @Test
381        public void testInterpolation() throws Exception
382        {
383            config.setProperty("applicationRoot", "/home/applicationRoot");
384            config.setProperty("db", "${applicationRoot}/db/hypersonic");
385            String unInterpolatedValue = "${applicationRoot2}/db/hypersonic";
386            config.setProperty("dbFailedInterpolate", unInterpolatedValue);
387            String dbProp = "/home/applicationRoot/db/hypersonic";
388    
389            //construct a new config, using config as the defaults config for it.
390            BaseConfiguration superProp = config;
391    
392            assertEquals(
393                "Checking interpolated variable",dbProp,
394                superProp.getString("db"));
395            assertEquals(
396                "lookup fails, leave variable as is",
397                superProp.getString("dbFailedInterpolate"),
398                unInterpolatedValue);
399    
400            superProp.setProperty("arrayInt", "${applicationRoot}/1");
401            String[] arrayInt = superProp.getStringArray("arrayInt");
402            assertEquals(
403                "check first entry was interpolated",
404                "/home/applicationRoot/1",
405                arrayInt[0]);
406        }
407    
408        @Test
409        public void testMultipleInterpolation() throws Exception
410        {
411            config.setProperty("test.base-level", "/base-level");
412            config.setProperty("test.first-level", "${test.base-level}/first-level");
413            config.setProperty(
414                "test.second-level",
415                "${test.first-level}/second-level");
416            config.setProperty(
417                "test.third-level",
418                "${test.second-level}/third-level");
419    
420            String expectedValue =
421                "/base-level/first-level/second-level/third-level";
422    
423            assertEquals(config.getString("test.third-level"), expectedValue);
424        }
425    
426        @Test(expected = IllegalStateException.class)
427        public void testInterpolationLoop() throws Exception
428        {
429            config.setProperty("test.a", "${test.b}");
430            config.setProperty("test.b", "${test.a}");
431            config.getString("test.a");
432        }
433    }
434