| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.commons.configuration2; |
| |
| import static org.junit.Assert.assertArrayEquals; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertSame; |
| import static org.junit.Assert.assertTrue; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.NoSuchElementException; |
| |
| import org.apache.commons.configuration2.convert.ConversionHandler; |
| import org.apache.commons.configuration2.convert.DefaultConversionHandler; |
| import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler; |
| import org.apache.commons.configuration2.convert.DisabledListDelimiterHandler; |
| import org.apache.commons.configuration2.event.ConfigurationEvent; |
| import org.apache.commons.configuration2.event.EventListener; |
| import org.apache.commons.configuration2.event.EventType; |
| import org.apache.commons.configuration2.interpol.ConfigurationInterpolator; |
| import org.apache.commons.configuration2.interpol.Lookup; |
| import org.apache.commons.lang3.ArrayUtils; |
| import org.easymock.EasyMock; |
| import org.junit.Test; |
| |
| /** |
| * A test class for some of the basic functionality implemented by |
| * AbstractConfiguration. |
| * |
| */ |
| public class TestAbstractConfigurationBasicFeatures |
| { |
| /** Constant for text to be used in tests for variable substitution. */ |
| private static final String SUBST_TXT = "The ${animal} jumps over the ${target}."; |
| |
| /** Constant for the prefix of test keys.*/ |
| private static final String KEY_PREFIX = "key"; |
| |
| /** Constant for the number of properties in tests for copy operations.*/ |
| private static final int PROP_COUNT = 12; |
| |
| /** |
| * Tests the clear() implementation of AbstractConfiguration if the iterator |
| * returned by getKeys() does not support the remove() operation. |
| */ |
| @Test |
| public void testClearIteratorNoRemove() |
| { |
| final AbstractConfiguration config = new TestConfigurationImpl( |
| new BaseConfiguration()) |
| { |
| // return an iterator that does not support remove operations |
| @Override |
| protected Iterator<String> getKeysInternal() |
| { |
| final Collection<String> keyCol = new ArrayList<>(); |
| ConfigurationAssert.appendKeys(getUnderlyingConfiguration(), keyCol); |
| final String[] keys = keyCol.toArray(new String[keyCol.size()]); |
| return Arrays.asList(keys).iterator(); |
| } |
| }; |
| for (int i = 0; i < 20; i++) |
| { |
| config.addProperty("key" + i, "value" + i); |
| } |
| config.clear(); |
| assertTrue("Configuration not empty", config.isEmpty()); |
| } |
| |
| /** |
| * Tests escaping the variable marker, so that no interpolation will be |
| * performed. |
| */ |
| @Test |
| public void testInterpolateEscape() |
| { |
| final AbstractConfiguration config = new TestConfigurationImpl( |
| new PropertiesConfiguration()); |
| config.setListDelimiterHandler(new DefaultListDelimiterHandler(',')); |
| config |
| .addProperty( |
| "mypath", |
| "$${DB2UNIVERSAL_JDBC_DRIVER_PATH}/db2jcc.jar\\,$${DB2UNIVERSAL_JDBC_DRIVER_PATH}/db2jcc_license_cu.jar"); |
| assertEquals( |
| "Wrong interpolated value", |
| "${DB2UNIVERSAL_JDBC_DRIVER_PATH}/db2jcc.jar,${DB2UNIVERSAL_JDBC_DRIVER_PATH}/db2jcc_license_cu.jar", |
| config.getString("mypath")); |
| } |
| |
| /** |
| * Tests adding list properties. The single elements of the list should be |
| * added. |
| */ |
| @Test |
| public void testAddPropertyList() |
| { |
| checkAddListProperty(new TestConfigurationImpl( |
| new PropertiesConfiguration())); |
| } |
| |
| /** |
| * Tests adding list properties if delimiter parsing is disabled. |
| */ |
| @Test |
| public void testAddPropertyListNoDelimiterParsing() |
| { |
| final AbstractConfiguration config = new TestConfigurationImpl( |
| new PropertiesConfiguration()); |
| checkAddListProperty(config); |
| } |
| |
| /** |
| * Helper method for adding properties with multiple values. |
| * |
| * @param config the configuration to be used for testing |
| */ |
| private void checkAddListProperty(final AbstractConfiguration config) |
| { |
| config.addProperty("test", "value1"); |
| final Object[] lstValues1 = new Object[] |
| { "value2", "value3" }; |
| final Object[] lstValues2 = new Object[] |
| { "value4", "value5", "value6" }; |
| config.addProperty("test", lstValues1); |
| config.addProperty("test", Arrays.asList(lstValues2)); |
| final List<Object> lst = config.getList("test"); |
| assertEquals("Wrong number of list elements", 6, lst.size()); |
| for (int i = 0; i < lst.size(); i++) |
| { |
| assertEquals("Wrong list element at " + i, "value" + (i + 1), lst |
| .get(i)); |
| } |
| } |
| |
| /** |
| * Tests the copy() method. |
| */ |
| @Test |
| public void testCopy() |
| { |
| final AbstractConfiguration config = setUpDestConfig(); |
| final Configuration srcConfig = setUpSourceConfig(); |
| config.copy(srcConfig); |
| for (int i = 0; i < PROP_COUNT; i++) |
| { |
| final String key = KEY_PREFIX + i; |
| if (srcConfig.containsKey(key)) |
| { |
| assertEquals("Value not replaced: " + key, srcConfig |
| .getProperty(key), config.getProperty(key)); |
| } |
| else |
| { |
| assertEquals("Value modified: " + key, "value" + i, config |
| .getProperty(key)); |
| } |
| } |
| } |
| |
| /** |
| * Tests the copy() method if properties with multiple values and escaped |
| * list delimiters are involved. |
| */ |
| @Test |
| public void testCopyWithLists() |
| { |
| final Configuration srcConfig = setUpSourceConfig(); |
| final AbstractConfiguration config = setUpDestConfig(); |
| config.copy(srcConfig); |
| checkListProperties(config); |
| } |
| |
| /** |
| * Tests the events generated by a copy() operation. |
| */ |
| @Test |
| public void testCopyEvents() |
| { |
| final AbstractConfiguration config = setUpDestConfig(); |
| final Configuration srcConfig = setUpSourceConfig(); |
| final CollectingConfigurationListener l = new CollectingConfigurationListener(); |
| config.addEventListener(ConfigurationEvent.ANY, l); |
| config.copy(srcConfig); |
| checkCopyEvents(l, srcConfig, ConfigurationEvent.SET_PROPERTY); |
| } |
| |
| /** |
| * Tests copying a null configuration. This should be a noop. |
| */ |
| @Test |
| public void testCopyNull() |
| { |
| final AbstractConfiguration config = setUpDestConfig(); |
| config.copy(null); |
| ConfigurationAssert.assertConfigurationEquals(setUpDestConfig(), config); |
| } |
| |
| /** |
| * Tests whether list delimiters are correctly handled when copying a |
| * configuration. |
| */ |
| @Test |
| public void testCopyDelimiterHandling() |
| { |
| final BaseConfiguration srcConfig = new BaseConfiguration(); |
| final BaseConfiguration dstConfig = new BaseConfiguration(); |
| dstConfig.setListDelimiterHandler(new DefaultListDelimiterHandler(',')); |
| srcConfig.setProperty(KEY_PREFIX, "C:\\Temp\\,D:\\Data"); |
| dstConfig.copy(srcConfig); |
| assertEquals("Wrong property value", srcConfig.getString(KEY_PREFIX), |
| dstConfig.getString(KEY_PREFIX)); |
| } |
| |
| /** |
| * Tests the append() method. |
| */ |
| @Test |
| public void testAppend() |
| { |
| final AbstractConfiguration config = setUpDestConfig(); |
| final Configuration srcConfig = setUpSourceConfig(); |
| config.append(srcConfig); |
| for (int i = 0; i < PROP_COUNT; i++) |
| { |
| final String key = KEY_PREFIX + i; |
| if (srcConfig.containsKey(key)) |
| { |
| final List<Object> values = config.getList(key); |
| assertEquals("Value not added: " + key, 2, values.size()); |
| assertEquals("Wrong value 1 for " + key, "value" + i, values |
| .get(0)); |
| assertEquals("Wrong value 2 for " + key, "src" + i, values |
| .get(1)); |
| } |
| else |
| { |
| assertEquals("Value modified: " + key, "value" + i, config |
| .getProperty(key)); |
| } |
| } |
| } |
| |
| /** |
| * Tests the append() method when properties with multiple values and |
| * escaped list delimiters are involved. |
| */ |
| @Test |
| public void testAppendWithLists() |
| { |
| final AbstractConfiguration config = setUpDestConfig(); |
| config.append(setUpSourceConfig()); |
| checkListProperties(config); |
| } |
| |
| /** |
| * Tests the events generated by an append() operation. |
| */ |
| @Test |
| public void testAppendEvents() |
| { |
| final AbstractConfiguration config = setUpDestConfig(); |
| final Configuration srcConfig = setUpSourceConfig(); |
| final CollectingConfigurationListener l = new CollectingConfigurationListener(); |
| config.addEventListener(ConfigurationEvent.ANY, l); |
| config.append(srcConfig); |
| checkCopyEvents(l, srcConfig, ConfigurationEvent.ADD_PROPERTY); |
| } |
| |
| /** |
| * Tests appending a null configuration. This should be a noop. |
| */ |
| @Test |
| public void testAppendNull() |
| { |
| final AbstractConfiguration config = setUpDestConfig(); |
| config.append(null); |
| ConfigurationAssert.assertConfigurationEquals(setUpDestConfig(), config); |
| } |
| |
| /** |
| * Tests whether the list delimiter is correctly handled if a configuration |
| * is appended. |
| */ |
| @Test |
| public void testAppendDelimiterHandling() |
| { |
| final BaseConfiguration srcConfig = new BaseConfiguration(); |
| final BaseConfiguration dstConfig = new BaseConfiguration(); |
| dstConfig.setListDelimiterHandler(new DefaultListDelimiterHandler(',')); |
| srcConfig.setProperty(KEY_PREFIX, "C:\\Temp\\,D:\\Data"); |
| dstConfig.append(srcConfig); |
| assertEquals("Wrong property value", srcConfig.getString(KEY_PREFIX), |
| dstConfig.getString(KEY_PREFIX)); |
| } |
| |
| /** |
| * Tests whether environment variables can be interpolated. |
| */ |
| @Test |
| public void testInterpolateEnvironmentVariables() |
| { |
| final AbstractConfiguration config = new TestConfigurationImpl( |
| new PropertiesConfiguration()); |
| InterpolationTestHelper.testInterpolationEnvironment(config); |
| } |
| |
| /** |
| * Tests whether prefix lookups can be added to an existing |
| * {@code ConfigurationInterpolator}. |
| */ |
| @Test |
| public void testSetPrefixLookupsExistingInterpolator() |
| { |
| final Lookup look = EasyMock.createMock(Lookup.class); |
| EasyMock.replay(look); |
| final AbstractConfiguration config = |
| new TestConfigurationImpl(new PropertiesConfiguration()); |
| final int count = config.getInterpolator().getLookups().size(); |
| final Map<String, Lookup> lookups = new HashMap<>(); |
| lookups.put("test", look); |
| config.setPrefixLookups(lookups); |
| final Map<String, Lookup> lookups2 = config.getInterpolator().getLookups(); |
| assertEquals("Not added", count + 1, lookups2.size()); |
| assertSame("Not found", look, lookups2.get("test")); |
| } |
| |
| /** |
| * Tests whether prefix lookups can be added if no |
| * {@code ConfigurationInterpolator} exists yet. |
| */ |
| @Test |
| public void testSetPrefixLookupsNoInterpolator() |
| { |
| final Lookup look = EasyMock.createMock(Lookup.class); |
| EasyMock.replay(look); |
| final AbstractConfiguration config = |
| new TestConfigurationImpl(new PropertiesConfiguration()); |
| config.setInterpolator(null); |
| config.setPrefixLookups(Collections.singletonMap("test", look)); |
| final Map<String, Lookup> lookups = config.getInterpolator().getLookups(); |
| assertEquals("Wrong number of lookups", 1, lookups.size()); |
| assertSame("Not found", look, lookups.get("test")); |
| } |
| |
| /** |
| * Tests whether default lookups can be added to an already existing |
| * {@code ConfigurationInterpolator}. |
| */ |
| @Test |
| public void testSetDefaultLookupsExistingInterpolator() |
| { |
| final Lookup look = EasyMock.createMock(Lookup.class); |
| EasyMock.replay(look); |
| final AbstractConfiguration config = |
| new TestConfigurationImpl(new PropertiesConfiguration()); |
| config.getInterpolator().addDefaultLookup( |
| new ConfigurationLookup(new PropertiesConfiguration())); |
| config.setDefaultLookups(Collections.singleton(look)); |
| final List<Lookup> lookups = config.getInterpolator().getDefaultLookups(); |
| assertEquals("Wrong number of default lookups", 3, lookups.size()); |
| assertSame("Wrong lookup at 1", look, lookups.get(1)); |
| assertTrue("Wrong lookup at 2: " + lookups, |
| lookups.get(2) instanceof ConfigurationLookup); |
| } |
| |
| /** |
| * Tests whether default lookups can be added if not |
| * {@code ConfigurationInterpolator} exists yet. |
| */ |
| @Test |
| public void testSetDefaultLookupsNoInterpolator() |
| { |
| final Lookup look = EasyMock.createMock(Lookup.class); |
| EasyMock.replay(look); |
| final AbstractConfiguration config = |
| new TestConfigurationImpl(new PropertiesConfiguration()); |
| config.setInterpolator(null); |
| config.setDefaultLookups(Collections.singleton(look)); |
| final List<Lookup> lookups = config.getInterpolator().getDefaultLookups(); |
| assertEquals("Wrong number of default lookups", 2, lookups.size()); |
| assertSame("Wrong lookup at 0", look, lookups.get(0)); |
| assertTrue("Wrong lookup at 1", |
| lookups.get(1) instanceof ConfigurationLookup); |
| } |
| |
| /** |
| * Tests whether a new {@code ConfigurationInterpolator} can be installed |
| * without providing custom lookups. |
| */ |
| @Test |
| public void testInstallInterpolatorNull() |
| { |
| final AbstractConfiguration config = |
| new TestConfigurationImpl(new PropertiesConfiguration()); |
| config.installInterpolator(null, null); |
| assertTrue("Got prefix lookups", config.getInterpolator().getLookups() |
| .isEmpty()); |
| final List<Lookup> defLookups = config.getInterpolator().getDefaultLookups(); |
| assertEquals("Wrong number of default lookups", 1, defLookups.size()); |
| assertTrue("Wrong default lookup", |
| defLookups.get(0) instanceof ConfigurationLookup); |
| } |
| |
| /** |
| * Tests whether a parent {@code ConfigurationInterpolator} can be set if |
| * already a {@code ConfigurationInterpolator} is available. |
| */ |
| @Test |
| public void testSetParentInterpolatorExistingInterpolator() |
| { |
| final ConfigurationInterpolator parent = |
| EasyMock.createMock(ConfigurationInterpolator.class); |
| EasyMock.replay(parent); |
| final AbstractConfiguration config = |
| new TestConfigurationImpl(new PropertiesConfiguration()); |
| final ConfigurationInterpolator ci = config.getInterpolator(); |
| config.setParentInterpolator(parent); |
| assertSame("Parent was not set", parent, config.getInterpolator() |
| .getParentInterpolator()); |
| assertSame("Interpolator was changed", ci, config.getInterpolator()); |
| } |
| |
| /** |
| * Tests whether a parent {@code ConfigurationInterpolator} can be set if |
| * currently no {@code ConfigurationInterpolator} is available. |
| */ |
| @Test |
| public void testSetParentInterpolatorNoInterpolator() |
| { |
| final ConfigurationInterpolator parent = |
| EasyMock.createMock(ConfigurationInterpolator.class); |
| EasyMock.replay(parent); |
| final AbstractConfiguration config = |
| new TestConfigurationImpl(new PropertiesConfiguration()); |
| config.setInterpolator(null); |
| config.setParentInterpolator(parent); |
| assertSame("Parent was not set", parent, config.getInterpolator() |
| .getParentInterpolator()); |
| } |
| |
| /** |
| * Tests whether a property can reference an array using interpolation. |
| * This is related to CONFIGURATION-633. |
| */ |
| @Test |
| public void testInterpolateArray() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| final String[] values = {"some", "test", "values"}; |
| final String keyArray = "testArray"; |
| config.addProperty(keyArray, values); |
| config.addProperty(KEY_PREFIX, "${" + keyArray + "}"); |
| |
| assertArrayEquals("Wrong property", values, config.getStringArray(KEY_PREFIX)); |
| } |
| |
| /** |
| * Tests whether a property can reference a list using interpolation. |
| * This is related to CONFIGURATION-633. |
| */ |
| @Test |
| public void testInterpolateList() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| final List<String> values = Arrays.asList("some", "test", "values"); |
| final String keyList = "testList"; |
| config.addProperty(keyList, values); |
| config.addProperty(KEY_PREFIX, "${" + keyList + "}"); |
| |
| assertEquals("Wrong property", values, config.getList(String.class, KEY_PREFIX)); |
| } |
| |
| /** |
| * Tests getList() for single non-string values. |
| */ |
| @Test |
| public void testGetListNonString() |
| { |
| checkGetListScalar(Integer.valueOf(42)); |
| checkGetListScalar(Long.valueOf(42)); |
| checkGetListScalar(Short.valueOf((short) 42)); |
| checkGetListScalar(Byte.valueOf((byte) 42)); |
| checkGetListScalar(Float.valueOf(42)); |
| checkGetListScalar(Double.valueOf(42)); |
| checkGetListScalar(Boolean.TRUE); |
| } |
| |
| /** |
| * Tests getStringArray() for single son-string values. |
| */ |
| @Test |
| public void testGetStringArrayNonString() |
| { |
| checkGetStringArrayScalar(Integer.valueOf(42)); |
| checkGetStringArrayScalar(Long.valueOf(42)); |
| checkGetStringArrayScalar(Short.valueOf((short) 42)); |
| checkGetStringArrayScalar(Byte.valueOf((byte) 42)); |
| checkGetStringArrayScalar(Float.valueOf(42)); |
| checkGetStringArrayScalar(Double.valueOf(42)); |
| checkGetStringArrayScalar(Boolean.TRUE); |
| } |
| |
| /** |
| * Tests getStringArray() if the key cannot be found. |
| */ |
| @Test |
| public void testGetStringArrayUnknown() |
| { |
| final BaseConfiguration config = new BaseConfiguration(); |
| final String[] array = config.getStringArray(KEY_PREFIX); |
| assertEquals("Got elements", 0, array.length); |
| } |
| |
| /** |
| * Helper method for checking getList() if the property value is a scalar. |
| * @param value the value of the property |
| */ |
| private void checkGetListScalar(final Object value) |
| { |
| final BaseConfiguration config = new BaseConfiguration(); |
| config.addProperty(KEY_PREFIX, value); |
| final List<Object> lst = config.getList(KEY_PREFIX); |
| assertEquals("Wrong number of values", 1, lst.size()); |
| assertEquals("Wrong value", value.toString(), lst.get(0)); |
| } |
| |
| /** |
| * Helper method for checking getStringArray() if the property value is a |
| * scalar. |
| * |
| * @param value the value of the property |
| */ |
| private void checkGetStringArrayScalar(final Object value) |
| { |
| final BaseConfiguration config = new BaseConfiguration(); |
| config.addProperty(KEY_PREFIX, value); |
| final String[] array = config.getStringArray(KEY_PREFIX); |
| assertEquals("Weong number of elements", 1, array.length); |
| assertEquals("Wrong value", value.toString(), array[0]); |
| } |
| |
| /** |
| * Tests whether interpolation works in variable names. |
| */ |
| @Test |
| public void testNestedVariableInterpolation() |
| { |
| final BaseConfiguration config = new BaseConfiguration(); |
| config.getInterpolator().setEnableSubstitutionInVariables(true); |
| config.addProperty("java.version", "1.4"); |
| config.addProperty("jre-1.4", "C:\\java\\1.4"); |
| config.addProperty("jre.path", "${jre-${java.version}}"); |
| assertEquals("Wrong path", "C:\\java\\1.4", |
| config.getString("jre.path")); |
| } |
| |
| /** |
| * Tries to set a null list delimiter handler. |
| */ |
| @Test(expected = IllegalArgumentException.class) |
| public void testSetListDelimiterHandlerNull() |
| { |
| final BaseConfiguration config = new BaseConfiguration(); |
| config.setListDelimiterHandler(null); |
| } |
| |
| /** |
| * Tests the default list delimiter hander. |
| */ |
| @Test |
| public void testDefaultListDelimiterHandler() |
| { |
| final BaseConfiguration config = new BaseConfiguration(); |
| assertTrue( |
| "Wrong list delimiter handler", |
| config.getListDelimiterHandler() instanceof DisabledListDelimiterHandler); |
| } |
| |
| /** |
| * Tests the interpolation features. |
| */ |
| @Test |
| public void testInterpolateString() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| config.addProperty("animal", "quick brown fox"); |
| config.addProperty("target", "lazy dog"); |
| config.addProperty(KEY_PREFIX, SUBST_TXT); |
| assertEquals("Wrong interpolation", |
| "The quick brown fox jumps over the lazy dog.", |
| config.getString(KEY_PREFIX)); |
| } |
| |
| /** |
| * Tests complex interpolation where the variables' values contain in turn |
| * other variables. |
| */ |
| @Test |
| public void testInterpolateRecursive() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| config.addProperty("animal", "${animal_attr} fox"); |
| config.addProperty("target", "${target_attr} dog"); |
| config.addProperty("animal_attr", "quick brown"); |
| config.addProperty("target_attr", "lazy"); |
| config.addProperty(KEY_PREFIX, SUBST_TXT); |
| assertEquals("Wrong complex interpolation", |
| "The quick brown fox jumps over the lazy dog.", |
| config.getString(KEY_PREFIX)); |
| } |
| |
| /** |
| * Tests an interpolation that leads to a cycle. This should throw an |
| * exception. |
| */ |
| @Test(expected = IllegalStateException.class) |
| public void testCyclicInterpolation() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| config.addProperty("animal", "${animal_attr} ${species}"); |
| config.addProperty("animal_attr", "quick brown"); |
| config.addProperty("species", "${animal}"); |
| config.addProperty(KEY_PREFIX, "This is a ${animal}"); |
| config.getString(KEY_PREFIX); |
| } |
| |
| /** |
| * Tests interpolation if a variable is unknown. Then the variable won't be |
| * substituted. |
| */ |
| @Test |
| public void testInterpolationUnknownVariable() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| config.addProperty("animal", "quick brown fox"); |
| config.addProperty(KEY_PREFIX, SUBST_TXT); |
| assertEquals("Wrong interpolation", |
| "The quick brown fox jumps over the ${target}.", |
| config.getString(KEY_PREFIX)); |
| } |
| |
| /** |
| * Tests interpolate() if the configuration does not have a |
| * {@code ConfigurationInterpolator}. |
| */ |
| @Test |
| public void testInterpolationNoInterpolator() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| config.addProperty("animal", "quick brown fox"); |
| config.addProperty("target", "lazy dog"); |
| config.addProperty(KEY_PREFIX, SUBST_TXT); |
| config.setInterpolator(null); |
| assertEquals("Interpolation was performed", SUBST_TXT, |
| config.getString(KEY_PREFIX)); |
| } |
| |
| /** |
| * Tests whether a configuration instance has a default conversion hander. |
| */ |
| @Test |
| public void testDefaultConversionHandler() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| assertEquals("Wrong default conversion handler", |
| DefaultConversionHandler.class, config.getConversionHandler() |
| .getClass()); |
| } |
| |
| /** |
| * Tests that the default conversion handler is shared between all |
| * configuration instances. |
| */ |
| @Test |
| public void testDefaultConversionHandlerSharedInstance() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| final PropertiesConfiguration config2 = new PropertiesConfiguration(); |
| assertSame("Multiple conversion handlers", |
| config.getConversionHandler(), config2.getConversionHandler()); |
| } |
| |
| /** |
| * Tests whether the conversion handler can be changed. |
| */ |
| @Test |
| public void testSetDefaultConversionHandler() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| final ConversionHandler handler = new DefaultConversionHandler(); |
| config.setConversionHandler(handler); |
| assertSame("Handler not set", handler, config.getConversionHandler()); |
| } |
| |
| /** |
| * Tries to set a null value for the conversion handler. |
| */ |
| @Test(expected = IllegalArgumentException.class) |
| public void testSetDefaultConversionHandlerNull() |
| { |
| new PropertiesConfiguration().setConversionHandler(null); |
| } |
| |
| /** |
| * Tests the generic get() method. |
| */ |
| @Test |
| public void testGet() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| final Integer value = 20130816; |
| config.addProperty(KEY_PREFIX, value.toString()); |
| assertEquals("Wrong result", value, config.get(Integer.class, KEY_PREFIX)); |
| } |
| |
| /** |
| * Tests get() for an unknown property if no default value is provided. |
| */ |
| @Test |
| public void testGetUnknownNoDefaultValue() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| assertNull("Wrong result", config.get(Integer.class, KEY_PREFIX)); |
| } |
| |
| /** |
| * Tests get() for an unknown property if a default value is provided. |
| */ |
| @Test |
| public void testGetUnknownWithDefaultValue() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| final Integer defaultValue = 2121; |
| assertEquals("Wrong result", defaultValue, |
| config.get(Integer.class, KEY_PREFIX, defaultValue)); |
| } |
| |
| /** |
| * Tests get() for an unknown property if the throwExceptionOnMissing |
| * flag is set. |
| */ |
| @Test(expected = NoSuchElementException.class) |
| public void testGetUnknownWithThrowExceptionOnMissing() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| config.setThrowExceptionOnMissing(true); |
| config.get(Integer.class, KEY_PREFIX); |
| } |
| |
| /** |
| * Tests get() for an unknown property with a default value and the |
| * throwExceptionOnMissing flag. Because of the default value no exception |
| * should be thrown. |
| */ |
| @Test |
| public void testGetUnownWithDefaultValueThrowExceptionOnMissing() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| config.setThrowExceptionOnMissing(true); |
| final Integer defaultValue = 2121; |
| assertEquals("Wrong result", defaultValue, |
| config.get(Integer.class, KEY_PREFIX, defaultValue)); |
| } |
| |
| /** |
| * Tests whether conversion to an array is possible. |
| */ |
| @Test |
| public void testGetArray() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| final Integer[] expected = new Integer[PROP_COUNT]; |
| for (int i = 0; i < PROP_COUNT; i++) |
| { |
| config.addProperty(KEY_PREFIX, String.valueOf(i)); |
| expected[i] = Integer.valueOf(i); |
| } |
| final Integer[] result = config.get(Integer[].class, KEY_PREFIX); |
| assertArrayEquals("Wrong result", expected, result); |
| } |
| |
| /** |
| * Tests a conversion to an array of primitive types. |
| */ |
| @Test |
| public void testGetArrayPrimitive() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| final short[] expected = new short[PROP_COUNT]; |
| for (int i = 0; i < PROP_COUNT; i++) |
| { |
| config.addProperty(KEY_PREFIX, String.valueOf(i)); |
| expected[i] = (short) i; |
| } |
| final short[] result = |
| config.get(short[].class, KEY_PREFIX, ArrayUtils.EMPTY_SHORT_ARRAY); |
| assertArrayEquals("Wrong result", expected, result); |
| } |
| |
| /** |
| * Tests get() for an unknown array property if no default value is provided. |
| */ |
| @Test |
| public void testGetArrayUnknownNoDefault() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| assertNull("Wrong result", config.get(Integer[].class, KEY_PREFIX)); |
| } |
| |
| /** |
| * Tests get() for an unknown array property if a default value is provided. |
| */ |
| @Test |
| public void testGetArrayUnknownWithDefault() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| final int[] defValue = { |
| 1, 2, 3 |
| }; |
| assertArrayEquals("Wrong result", defValue, |
| config.get(int[].class, KEY_PREFIX, defValue)); |
| } |
| |
| /** |
| * Tests getArray() if the default value is not an array. |
| */ |
| @Test(expected = IllegalArgumentException.class) |
| public void testGetArrayDefaultValueNotAnArray() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| config.getArray(Integer.class, KEY_PREFIX, this); |
| } |
| |
| /** |
| * Tests getArray() if the default value is an array with a different |
| * component type. |
| */ |
| @Test(expected = IllegalArgumentException.class) |
| public void testGetArrayDefaultValueWrongComponentClass() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| config.getArray(Integer.class, KEY_PREFIX, new short[1]); |
| } |
| |
| /** |
| * Prepares a test configuration for a test for a list conversion. The |
| * configuration is populated with a list property. The returned list |
| * contains the expected list values converted to integers. |
| * |
| * @param config the test configuration |
| * @return the list with expected values |
| */ |
| private static List<Integer> prepareListTest(final PropertiesConfiguration config) |
| { |
| final List<Integer> expected = new ArrayList<>(PROP_COUNT); |
| for (int i = 0; i < PROP_COUNT; i++) |
| { |
| config.addProperty(KEY_PREFIX, String.valueOf(i)); |
| expected.add(i); |
| } |
| return expected; |
| } |
| |
| /** |
| * Tests a conversion to a list. |
| */ |
| @Test |
| public void testGetList() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| final List<Integer> expected = prepareListTest(config); |
| final List<Integer> result = config.getList(Integer.class, KEY_PREFIX); |
| assertEquals("Wrong result", expected, result); |
| } |
| |
| /** |
| * Tests a conversion to a list if the property is unknown and no default |
| * value is provided. |
| */ |
| @Test |
| public void testGetListUnknownNoDefault() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| assertNull("Wrong result", config.getList(Integer.class, KEY_PREFIX)); |
| } |
| |
| /** |
| * Tests a conversion to a list if the property is unknown and a default |
| * list is provided. |
| */ |
| @Test |
| public void testGetListUnknownWithDefault() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| final List<Integer> defValue = Arrays.asList(1, 2, 3); |
| assertEquals("Wrong result", defValue, config.getList(Integer.class, KEY_PREFIX, defValue)); |
| } |
| |
| /** |
| * Tests a conversion to a collection. |
| */ |
| @Test |
| public void testGetCollection() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| final List<Integer> expected = prepareListTest(config); |
| final List<Integer> result = new ArrayList<>(PROP_COUNT); |
| assertSame("Wrong result", result, config.getCollection(Integer.class, KEY_PREFIX, result)); |
| assertEquals("Wrong converted content", expected, result); |
| } |
| |
| /** |
| * Tests getCollection() if no target collection is provided. |
| */ |
| @Test |
| public void testGetCollectionNullTarget() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| final List<Integer> expected = prepareListTest(config); |
| final Collection<Integer> result = config.getCollection(Integer.class, KEY_PREFIX, null, new ArrayList<Integer>()); |
| assertEquals("Wrong result", expected, result); |
| } |
| |
| /** |
| * Tests whether a single value property can be converted to a collection. |
| */ |
| @Test |
| public void testGetCollectionSingleValue() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| config.addProperty(KEY_PREFIX, "1"); |
| final List<Integer> result = new ArrayList<>(1); |
| config.getCollection(Integer.class, KEY_PREFIX, result); |
| assertEquals("Wrong number of elements", 1, result.size()); |
| assertEquals("Wrong element", Integer.valueOf(1), result.get(0)); |
| } |
| |
| /** |
| * Tests getCollection() for an unknown property if no default value is |
| * provided. |
| */ |
| @Test |
| public void testGetCollectionUnknownNoDefault() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| final List<Integer> result = new ArrayList<>(); |
| assertNull("Wrong result", config.getCollection(Integer.class, KEY_PREFIX, result)); |
| assertTrue("Got elements", result.isEmpty()); |
| } |
| |
| /** |
| * Tests getCollection() for an unknown property if a default collection is |
| * provided. |
| */ |
| @Test |
| public void testGetCollectionUnknownWithDefault() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| final List<Integer> defValue = Arrays.asList(1, 2, 4, 8, 16, 32); |
| final Collection<Integer> result = config.getCollection(Integer.class, KEY_PREFIX, null, defValue); |
| assertEquals("Wrong result", defValue, result); |
| } |
| |
| /** |
| * Tries to query an encoded string without a decoder. |
| */ |
| @Test(expected = IllegalArgumentException.class) |
| public void testGetEncodedStringNoDecoder() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| config.getEncodedString(KEY_PREFIX, null); |
| } |
| |
| /** |
| * Tests whether undefined keys are handled when querying encoded strings. |
| */ |
| @Test |
| public void testGetEncodedStringNoValue() |
| { |
| final ConfigurationDecoder decoder = |
| EasyMock.createMock(ConfigurationDecoder.class); |
| EasyMock.replay(decoder); |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| assertNull("Got a value", config.getEncodedString(KEY_PREFIX, decoder)); |
| } |
| |
| /** |
| * Tests whether an encoded value can be retrieved. |
| */ |
| @Test |
| public void testGetEncodedStringValue() |
| { |
| final ConfigurationDecoder decoder = |
| EasyMock.createMock(ConfigurationDecoder.class); |
| final String value = "original value"; |
| final String decodedValue = "decoded value"; |
| EasyMock.expect(decoder.decode(value)).andReturn(decodedValue); |
| EasyMock.replay(decoder); |
| |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| config.addProperty(KEY_PREFIX, value); |
| assertEquals("Wrong decoded value", decodedValue, |
| config.getEncodedString(KEY_PREFIX, decoder)); |
| } |
| |
| /** |
| * Tries to query an encoded string with the default decoder if this property is not |
| * defined. |
| */ |
| @Test(expected = IllegalStateException.class) |
| public void testGetEncodedStringNoDefaultDecoderDefined() |
| { |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| config.getEncodedString(KEY_PREFIX); |
| } |
| |
| /** |
| * Tests whether a default decoder can be set which is queried for encoded strings. |
| */ |
| @Test |
| public void testGetEncodedStringWithDefaultDecoder() |
| { |
| final ConfigurationDecoder decoder = |
| EasyMock.createMock(ConfigurationDecoder.class); |
| final String value = "original value"; |
| final String decodedValue = "decoded value"; |
| EasyMock.expect(decoder.decode(value)).andReturn(decodedValue); |
| EasyMock.replay(decoder); |
| |
| final PropertiesConfiguration config = new PropertiesConfiguration(); |
| config.setConfigurationDecoder(decoder); |
| config.addProperty(KEY_PREFIX, value); |
| assertEquals("Wrong decoded value", decodedValue, |
| config.getEncodedString(KEY_PREFIX)); |
| } |
| |
| /** |
| * Tests the default implementation of sizeInternal(). |
| */ |
| @Test |
| public void testSizeInternal() |
| { |
| final AbstractConfiguration config = |
| new TestConfigurationImpl(new PropertiesConfiguration()); |
| for (int i = 0; i < PROP_COUNT; i++) |
| { |
| config.addProperty(KEY_PREFIX + i, "value" + i); |
| } |
| assertEquals("Wrong size", PROP_COUNT, config.size()); |
| } |
| |
| /** |
| * Creates the source configuration for testing the copy() and append() |
| * methods. This configuration contains keys with an odd index and values |
| * starting with the prefix "src". There are also some list properties. |
| * |
| * @return the source configuration for copy operations |
| */ |
| private Configuration setUpSourceConfig() |
| { |
| final BaseConfiguration config = new BaseConfiguration(); |
| config.setListDelimiterHandler(new DefaultListDelimiterHandler(',')); |
| for (int i = 1; i < PROP_COUNT; i += 2) |
| { |
| config.addProperty(KEY_PREFIX + i, "src" + i); |
| } |
| config.addProperty("list1", "1,2,3"); |
| config.addProperty("list2", "3\\,1415,9\\,81"); |
| return config; |
| } |
| |
| /** |
| * Creates the destination configuration for testing the copy() and append() |
| * methods. This configuration contains keys with a running index and |
| * corresponding values starting with the prefix "value". |
| * |
| * @return the destination configuration for copy operations |
| */ |
| private AbstractConfiguration setUpDestConfig() |
| { |
| final AbstractConfiguration config = new TestConfigurationImpl( |
| new PropertiesConfiguration()); |
| config.setListDelimiterHandler(new DefaultListDelimiterHandler(',')); |
| for (int i = 0; i < PROP_COUNT; i++) |
| { |
| config.addProperty(KEY_PREFIX + i, "value" + i); |
| } |
| return config; |
| } |
| |
| /** |
| * Tests the values of list properties after a copy operation. |
| * |
| * @param config the configuration to test |
| */ |
| private void checkListProperties(final Configuration config) |
| { |
| List<Object> values = config.getList("list1"); |
| assertEquals("Wrong number of elements in list 1", 3, values.size()); |
| values = config.getList("list2"); |
| assertEquals("Wrong number of elements in list 2", 2, values.size()); |
| assertEquals("Wrong value 1", "3,1415", values.get(0)); |
| assertEquals("Wrong value 2", "9,81", values.get(1)); |
| } |
| |
| /** |
| * Tests whether the correct events are received for a copy operation. |
| * |
| * @param l the event listener |
| * @param src the configuration that was copied |
| * @param eventType the expected event type |
| */ |
| private void checkCopyEvents(final CollectingConfigurationListener l, |
| final Configuration src, final EventType<?> eventType) |
| { |
| final Map<String, ConfigurationEvent> events = new HashMap<>(); |
| for (final ConfigurationEvent e : l.events) |
| { |
| assertEquals("Wrong event type", eventType, e.getEventType()); |
| assertTrue("Unknown property: " + e.getPropertyName(), src |
| .containsKey(e.getPropertyName())); |
| if (!e.isBeforeUpdate()) |
| { |
| assertTrue("After event without before event", events |
| .containsKey(e.getPropertyName())); |
| } |
| else |
| { |
| events.put(e.getPropertyName(), e); |
| } |
| } |
| |
| for (final Iterator<String> it = src.getKeys(); it.hasNext();) |
| { |
| final String key = it.next(); |
| assertTrue("No event received for key " + key, events |
| .containsKey(key)); |
| } |
| } |
| |
| /** |
| * A test configuration implementation. This implementation inherits |
| * directly from AbstractConfiguration. For implementing the required |
| * functionality another implementation of AbstractConfiguration is used; |
| * all methods that need to be implemented delegate to this wrapped |
| * configuration. |
| */ |
| static class TestConfigurationImpl extends AbstractConfiguration |
| { |
| /** Stores the underlying configuration. */ |
| private final AbstractConfiguration config; |
| |
| public AbstractConfiguration getUnderlyingConfiguration() |
| { |
| return config; |
| } |
| |
| public TestConfigurationImpl(final AbstractConfiguration wrappedConfig) |
| { |
| config = wrappedConfig; |
| } |
| |
| @Override |
| protected void addPropertyDirect(final String key, final Object value) |
| { |
| config.addPropertyDirect(key, value); |
| } |
| |
| @Override |
| protected boolean containsKeyInternal(final String key) |
| { |
| return config.containsKey(key); |
| } |
| |
| @Override |
| protected Iterator<String> getKeysInternal() |
| { |
| return config.getKeys(); |
| } |
| |
| @Override |
| protected Object getPropertyInternal(final String key) |
| { |
| return config.getProperty(key); |
| } |
| |
| @Override |
| protected boolean isEmptyInternal() |
| { |
| return config.isEmpty(); |
| } |
| |
| @Override |
| protected void clearPropertyDirect(final String key) |
| { |
| config.clearPropertyDirect(key); |
| } |
| } |
| |
| /** |
| * An event listener implementation that simply collects all received |
| * configuration events. |
| */ |
| private static class CollectingConfigurationListener implements |
| EventListener<ConfigurationEvent> |
| { |
| final List<ConfigurationEvent> events = new ArrayList<>(); |
| |
| @Override |
| public void onEvent(final ConfigurationEvent event) |
| { |
| events.add(event); |
| } |
| } |
| } |