| /* |
| * 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.beanutils; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.List; |
| |
| import junitx.framework.ObjectAssert; |
| |
| import org.apache.commons.beanutils.DynaProperty; |
| import org.apache.commons.configuration2.BaseConfiguration; |
| import org.apache.commons.configuration2.Configuration; |
| import org.apache.commons.configuration2.MapConfiguration; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| /** |
| * <p>Test Case for the {@code ConfigurationDynaBean} implementation class. |
| * These tests were based on the ones in {@code BasicDynaBeanTestCase} |
| * because the two classes provide similar levels of functionality.</p> |
| * |
| */ |
| public class TestConfigurationDynaBean |
| { |
| /** |
| * The basic test bean for each test. |
| */ |
| private ConfigurationDynaBean bean; |
| |
| /** |
| * The set of property names we expect to have returned when calling |
| * {@code getDynaProperties()}. You should update this list |
| * when new properties are added to TestBean. |
| */ |
| String[] properties = { |
| "booleanProperty", |
| "booleanSecond", |
| "doubleProperty", |
| "floatProperty", |
| "intProperty", |
| "longProperty", |
| "mappedProperty.key1", |
| "mappedProperty.key2", |
| "mappedProperty.key3", |
| "mappedIntProperty.key1", |
| "shortProperty", |
| "stringProperty", |
| "byteProperty", |
| "charProperty" |
| }; |
| |
| Object[] values = { |
| Boolean.TRUE, |
| Boolean.TRUE, |
| new Double(Double.MAX_VALUE), |
| new Float(Float.MAX_VALUE), |
| new Integer(Integer.MAX_VALUE), |
| new Long(Long.MAX_VALUE), |
| "First Value", |
| "Second Value", |
| "Third Value", |
| new Integer(Integer.MAX_VALUE), |
| new Short(Short.MAX_VALUE), |
| "This is a string", |
| new Byte(Byte.MAX_VALUE), |
| new Character(Character.MAX_VALUE) |
| }; |
| |
| int[] intArray = {0, 10, 20, 30, 40}; |
| boolean[] booleanArray = {true, false, true, false, true}; |
| char[] charArray = {'a', 'b', 'c', 'd', 'e'}; |
| byte[] byteArray = {0, 10, 20, 30, 40}; |
| long[] longArray = {0, 10, 20, 30, 40}; |
| short[] shortArray = {0, 10, 20, 30, 40}; |
| float[] floatArray = {0, 10, 20, 30, 40}; |
| double[] doubleArray = {0.0, 10.0, 20.0, 30.0, 40.0}; |
| String[] stringArray = {"String 0", "String 1", "String 2", "String 3", "String 4"}; |
| |
| |
| /** |
| * Set up instance variables required by this test case. |
| */ |
| @Before |
| public void setUp() throws Exception |
| { |
| final Configuration configuration = createConfiguration(); |
| |
| for (int i = 0; i < properties.length; i++) |
| { |
| configuration.setProperty(properties[i], values[i]); |
| } |
| |
| for (final int element : intArray) { |
| configuration.addProperty("intIndexed", new Integer(element)); |
| } |
| |
| for (final String element : stringArray) { |
| configuration.addProperty("stringIndexed", element); |
| } |
| |
| final List<String> list = Arrays.asList(stringArray); |
| configuration.addProperty("listIndexed", list); |
| |
| bean = new ConfigurationDynaBean(configuration); |
| |
| bean.set("listIndexed", list); |
| bean.set("intArray", intArray); |
| bean.set("booleanArray", booleanArray); |
| bean.set("charArray", charArray); |
| bean.set("longArray", longArray); |
| bean.set("shortArray", shortArray); |
| bean.set("floatArray", floatArray); |
| bean.set("doubleArray", doubleArray); |
| bean.set("byteArray", byteArray); |
| bean.set("stringArray", stringArray); |
| } |
| |
| /** |
| * Creates the underlying configuration object for the dyna bean. |
| * @return the underlying configuration object |
| */ |
| protected Configuration createConfiguration() |
| { |
| return new BaseConfiguration(); |
| } |
| |
| /** |
| * Corner cases on getDynaProperty invalid arguments. |
| */ |
| @Test(expected = IllegalArgumentException.class) |
| public void testGetDescriptorArguments() |
| { |
| final DynaProperty descriptor = bean.getDynaClass().getDynaProperty("unknown"); |
| assertNull("Unknown property descriptor should be null", descriptor); |
| bean.getDynaClass().getDynaProperty(null); |
| } |
| |
| /** |
| * Positive getDynaProperty on property {@code booleanProperty}. |
| */ |
| @Test |
| public void testGetDescriptorBoolean() |
| { |
| testGetDescriptorBase("booleanProperty", Boolean.TYPE); |
| } |
| |
| /** |
| * Positive getDynaProperty on property {@code doubleProperty}. |
| */ |
| @Test |
| public void testGetDescriptorDouble() |
| { |
| testGetDescriptorBase("doubleProperty", Double.TYPE); |
| } |
| |
| /** |
| * Positive getDynaProperty on property {@code floatProperty}. |
| */ |
| @Test |
| public void testGetDescriptorFloat() |
| { |
| testGetDescriptorBase("floatProperty", Float.TYPE); |
| } |
| |
| /** |
| * Positive getDynaProperty on property {@code intProperty}. |
| */ |
| @Test |
| public void testGetDescriptorInt() |
| { |
| testGetDescriptorBase("intProperty", Integer.TYPE); |
| } |
| |
| /** |
| * Positive getDynaProperty on property {@code longProperty}. |
| */ |
| @Test |
| public void testGetDescriptorLong() |
| { |
| testGetDescriptorBase("longProperty", Long.TYPE); |
| } |
| |
| /** |
| * Positive getDynaProperty on property {@code booleanSecond} |
| * that uses an "is" method as the getter. |
| */ |
| @Test |
| public void testGetDescriptorSecond() |
| { |
| testGetDescriptorBase("booleanSecond", Boolean.TYPE); |
| } |
| |
| /** |
| * Positive getDynaProperty on property {@code shortProperty}. |
| */ |
| @Test |
| public void testGetDescriptorShort() |
| { |
| testGetDescriptorBase("shortProperty", Short.TYPE); |
| } |
| |
| /** |
| * Positive getDynaProperty on property {@code stringProperty}. |
| */ |
| @Test |
| public void testGetDescriptorString() |
| { |
| testGetDescriptorBase("stringProperty", String.class); |
| } |
| |
| /** |
| * Positive test for getDynaPropertys(). Each property name |
| * listed in {@code properties} should be returned exactly once. |
| */ |
| @Test |
| public void testGetDescriptors() |
| { |
| final DynaProperty pd[] = bean.getDynaClass().getDynaProperties(); |
| assertNotNull("Got descriptors", pd); |
| final int count[] = new int[properties.length]; |
| for (final DynaProperty element : pd) { |
| final String name = element.getName(); |
| for (int j = 0; j < properties.length; j++) |
| { |
| if (name.equals(properties[j])) |
| { |
| count[j]++; |
| } |
| } |
| } |
| |
| for (int j = 0; j < properties.length; j++) |
| { |
| if (count[j] < 0) |
| { |
| fail("Missing property " + properties[j]); |
| } |
| else if (count[j] > 1) |
| { |
| fail("Duplicate property " + properties[j]); |
| } |
| } |
| } |
| |
| /** |
| * Corner cases on getIndexedProperty invalid arguments. |
| */ |
| @Test(expected = IndexOutOfBoundsException.class) |
| public void testGetIndexedArguments() |
| { |
| bean.get("intArray", -1); |
| } |
| |
| /** |
| * Positive and negative tests on getIndexedProperty valid arguments. |
| */ |
| @Test |
| public void testGetIndexedValues() |
| { |
| for (int i = 0; i < 5; i++) |
| { |
| Object value = bean.get("intArray", i); |
| |
| assertNotNull("intArray index " + i + " did not return value.", value); |
| ObjectAssert.assertInstanceOf("intArray index " + i, Integer.class, value); |
| assertEquals("intArray " + i + " returned incorrect value.", i * 10, ((Integer) value).intValue()); |
| |
| value = bean.get("intIndexed", i); |
| |
| assertNotNull("intIndexed index " + i + "returned value " + i, value); |
| ObjectAssert.assertInstanceOf("intIndexed index " + i, Integer.class, value); |
| assertEquals("intIndexed index " + i + "returned correct " + i, i * 10, ((Integer) value).intValue()); |
| |
| value = bean.get("listIndexed", i); |
| |
| assertNotNull("listIndexed index " + i + "returned value " + i, value); |
| ObjectAssert.assertInstanceOf("list index " + i, String.class, value); |
| assertEquals("listIndexed index " + i + "returned correct " + i, "String " + i, value); |
| |
| value = bean.get("stringArray", i); |
| |
| assertNotNull("stringArray index " + i + " returnde null.", value); |
| assertFalse("stringArray index " + i + " returned array instead of String.", value.getClass().isArray()); |
| ObjectAssert.assertInstanceOf("stringArray index " + i, String.class, value); |
| assertEquals("stringArray returned correct " + i, "String " + i, value); |
| |
| value = bean.get("stringIndexed", i); |
| |
| assertNotNull("stringIndexed returned value " + i, value); |
| ObjectAssert.assertInstanceOf("stringIndexed", String.class, value); |
| assertEquals("stringIndexed returned correct " + i, "String " + i, value); |
| } |
| } |
| |
| /** |
| * Corner cases on getMappedProperty invalid arguments. |
| */ |
| @Test |
| public void testGetMappedArguments() |
| { |
| try |
| { |
| final Object value = bean.get("mappedProperty", "unknown"); |
| assertNull("Should not return a value", value); |
| } |
| catch (final Throwable t) |
| { |
| fail("Threw " + t + " instead of returning null"); |
| } |
| } |
| |
| /** |
| * Positive and negative tests on getMappedProperty valid arguments. |
| */ |
| @Test |
| public void testGetMappedValues() |
| { |
| Object value = bean.get("mappedProperty", "key1"); |
| assertEquals("Can find first value", "First Value", value); |
| |
| value = bean.get("mappedProperty", "key2"); |
| assertEquals("Can find second value", "Second Value", value); |
| |
| value = bean.get("mappedProperty", "key3"); |
| assertNotNull("Cannot find third value", value); |
| } |
| |
| /** |
| * Corner cases on getSimpleProperty invalid arguments. |
| */ |
| @Test(expected = IllegalArgumentException.class) |
| public void testGetSimpleArguments() |
| { |
| bean.get("a non existing property"); |
| } |
| |
| /** |
| * Test getSimpleProperty on a boolean property. |
| */ |
| @Test |
| public void testGetSimpleBoolean() |
| { |
| final Object value = bean.get("booleanProperty"); |
| assertNotNull("Got a value", value); |
| ObjectAssert.assertInstanceOf("Got correct type", Boolean.class, value); |
| assertTrue("Got correct value", ((Boolean) value).booleanValue()); |
| } |
| |
| /** |
| * Test getSimpleProperty on a double property. |
| */ |
| @Test |
| public void testGetSimpleDouble() |
| { |
| final Object value = bean.get("doubleProperty"); |
| assertNotNull("Got a value", value); |
| ObjectAssert.assertInstanceOf("Got correct type", Double.class, value); |
| assertEquals("Got correct value", ((Double) value).doubleValue(), Double.MAX_VALUE, 0.005); |
| } |
| |
| /** |
| * Test getSimpleProperty on a float property. |
| */ |
| @Test |
| public void testGetSimpleFloat() |
| { |
| final Object value = bean.get("floatProperty"); |
| assertNotNull("Got a value", value); |
| ObjectAssert.assertInstanceOf("Got correct type", Float.class, value); |
| assertEquals("Got correct value", ((Float) value).floatValue(), Float.MAX_VALUE, 0.005f); |
| } |
| |
| /** |
| * Test getSimpleProperty on a int property. |
| */ |
| @Test |
| public void testGetSimpleInt() |
| { |
| final Object value = bean.get("intProperty"); |
| assertNotNull("Failed to get value", value); |
| ObjectAssert.assertInstanceOf("Incorrect type", Integer.class, value); |
| assertEquals("Incorrect value", ((Integer) value).intValue(), Integer.MAX_VALUE); |
| } |
| |
| /** |
| * Test getSimpleProperty on a long property. |
| */ |
| @Test |
| public void testGetSimpleLong() |
| { |
| final Object value = bean.get("longProperty"); |
| assertNotNull("Got a value", value); |
| ObjectAssert.assertInstanceOf("Returned incorrect type", Long.class, value); |
| assertEquals("Returned value of Incorrect value", ((Long) value).longValue(), Long.MAX_VALUE); |
| } |
| |
| /** |
| * Test getSimpleProperty on a short property. |
| */ |
| @Test |
| public void testGetSimpleShort() |
| { |
| final Object value = bean.get("shortProperty"); |
| assertNotNull("Got a value", value); |
| ObjectAssert.assertInstanceOf("Got correct type", Short.class, value); |
| assertEquals("Got correct value", ((Short) value).shortValue(), Short.MAX_VALUE); |
| } |
| |
| /** |
| * Test getSimpleProperty on a String property. |
| */ |
| @Test |
| public void testGetSimpleString() |
| { |
| final Object value = bean.get("stringProperty"); |
| assertNotNull("Got a value", value); |
| ObjectAssert.assertInstanceOf("Got correct type", String.class, value); |
| assertEquals("Got correct value", value, "This is a string"); |
| } |
| |
| /** |
| * Test {@code contains()} method for mapped properties. |
| */ |
| @Test |
| public void testMappedContains() |
| { |
| assertTrue("Can't see first key", bean.contains("mappedProperty", "key1")); |
| assertTrue("Can see unknown key", !bean.contains("mappedProperty", "Unknown Key")); |
| } |
| |
| /** |
| * Test {@code remove()} method for mapped properties. |
| */ |
| @Test |
| public void testMappedRemove() |
| { |
| assertTrue("Can see first key", bean.contains("mappedProperty", "key1")); |
| bean.remove("mappedProperty", "key1"); |
| assertTrue("Can not see first key", !bean.contains("mappedProperty", "key1")); |
| |
| assertTrue("Can not see unknown key", !bean.contains("mappedProperty", "key4")); |
| bean.remove("mappedProperty", "key4"); |
| assertTrue("Can not see unknown key", !bean.contains("mappedProperty", "key4")); |
| } |
| |
| /** |
| * Corner cases on setIndexedProperty invalid arguments. |
| */ |
| @Test(expected = IndexOutOfBoundsException.class) |
| public void testSetIndexedArguments() |
| { |
| bean.set("intArray", -1, new Integer(0)); |
| } |
| |
| /** |
| * Positive and negative tests on setIndexedProperty valid arguments. |
| */ |
| @Test |
| public void testSetIndexedValues() |
| { |
| bean.set("intArray", 0, new Integer(1)); |
| Object value = bean.get("intArray", 0); |
| |
| assertNotNull("Returned new value 0", value); |
| ObjectAssert.assertInstanceOf("Returned Integer new value 0", Integer.class, value); |
| assertEquals("Returned correct new value 0", 1, ((Integer) value).intValue()); |
| |
| |
| bean.set("intIndexed", 1, new Integer(11)); |
| value = bean.get("intIndexed", 1); |
| |
| assertNotNull("Returned new value 1", value); |
| ObjectAssert.assertInstanceOf("Returned Integer new value 1", Integer.class, value); |
| assertEquals("Returned correct new value 1", 11, ((Integer) value).intValue()); |
| |
| |
| bean.set("listIndexed", 2, "New Value 2"); |
| value = bean.get("listIndexed", 2); |
| |
| assertNotNull("Returned new value 2", value); |
| ObjectAssert.assertInstanceOf("Returned String new value 2", String.class, value); |
| assertEquals("Returned correct new value 2", "New Value 2", value); |
| |
| |
| bean.set("stringArray", 3, "New Value 3"); |
| value = bean.get("stringArray", 3); |
| |
| assertNotNull("Returned new value 3", value); |
| ObjectAssert.assertInstanceOf("Returned String new value 3", String.class, value); |
| assertEquals("Returned correct new value 3", "New Value 3", value); |
| |
| |
| bean.set("stringIndexed", 4, "New Value 4"); |
| value = bean.get("stringIndexed", 4); |
| |
| assertNotNull("Returned new value 4", value); |
| ObjectAssert.assertInstanceOf("Returned String new value 4", String.class, value); |
| assertEquals("Returned correct new value 4", "New Value 4", value); |
| } |
| |
| /** |
| * Test the modification of a configuration property stored internally as an array. |
| */ |
| @Test |
| public void testSetArrayValue() |
| { |
| final MapConfiguration configuration = new MapConfiguration(new HashMap<String, Object>()); |
| configuration.getMap().put("objectArray", new Object[] {"value1", "value2", "value3"}); |
| |
| final ConfigurationDynaBean bean = new ConfigurationDynaBean(configuration); |
| |
| bean.set("objectArray", 1, "New Value 1"); |
| final Object value = bean.get("objectArray", 1); |
| |
| assertNotNull("Returned new value 1", value); |
| ObjectAssert.assertInstanceOf("Returned String new value 1", String.class, value); |
| assertEquals("Returned correct new value 1", "New Value 1", value); |
| } |
| |
| /** |
| * Positive and negative tests on setMappedProperty valid arguments. |
| */ |
| @Test |
| public void testSetMappedValues() |
| { |
| bean.set("mappedProperty", "First Key", "New First Value"); |
| assertEquals("Can replace old value", "New First Value", bean.get("mappedProperty", "First Key")); |
| |
| bean.set("mappedProperty", "Fourth Key", "Fourth Value"); |
| assertEquals("Can set new value", "Fourth Value", bean.get("mappedProperty", "Fourth Key")); |
| } |
| |
| /** |
| * Test setSimpleProperty on a boolean property. |
| */ |
| @Test |
| public void testSetSimpleBoolean() |
| { |
| final boolean oldValue = ((Boolean) bean.get("booleanProperty")).booleanValue(); |
| final boolean newValue = !oldValue; |
| bean.set("booleanProperty", new Boolean(newValue)); |
| assertTrue("Matched new value", newValue == ((Boolean) bean.get("booleanProperty")).booleanValue()); |
| } |
| |
| /** |
| * Test setSimpleProperty on a double property. |
| */ |
| @Test |
| public void testSetSimpleDouble() |
| { |
| final double oldValue = ((Double) bean.get("doubleProperty")).doubleValue(); |
| final double newValue = oldValue + 1.0; |
| bean.set("doubleProperty", new Double(newValue)); |
| assertEquals("Matched new value", newValue, ((Double) bean.get("doubleProperty")).doubleValue(), 0.005); |
| } |
| |
| /** |
| * Test setSimpleProperty on a float property. |
| */ |
| @Test |
| public void testSetSimpleFloat() |
| { |
| final float oldValue = ((Float) bean.get("floatProperty")).floatValue(); |
| final float newValue = oldValue + (float) 1.0; |
| bean.set("floatProperty", new Float(newValue)); |
| assertEquals("Matched new value", newValue, ((Float) bean.get("floatProperty")).floatValue(), 0.005f); |
| } |
| |
| /** |
| * Test setSimpleProperty on a int property. |
| */ |
| @Test |
| public void testSetSimpleInt() |
| { |
| final int oldValue = ((Integer) bean.get("intProperty")).intValue(); |
| final int newValue = oldValue + 1; |
| bean.set("intProperty", new Integer(newValue)); |
| assertEquals("Matched new value", newValue, ((Integer) bean.get("intProperty")).intValue()); |
| } |
| |
| /** |
| * Test setSimpleProperty on a long property. |
| */ |
| @Test |
| public void testSetSimpleLong() |
| { |
| final long oldValue = ((Long) bean.get("longProperty")).longValue(); |
| final long newValue = oldValue + 1; |
| bean.set("longProperty", new Long(newValue)); |
| assertEquals("Matched new value", newValue, ((Long) bean.get("longProperty")).longValue()); |
| } |
| |
| /** |
| * Test setSimpleProperty on a short property. |
| */ |
| @Test |
| public void testSetSimpleShort() |
| { |
| final short oldValue = ((Short) bean.get("shortProperty")).shortValue(); |
| final short newValue = (short) (oldValue + 1); |
| bean.set("shortProperty", new Short(newValue)); |
| assertEquals("Matched new value", newValue, ((Short) bean.get("shortProperty")).shortValue()); |
| } |
| |
| /** |
| * Test setSimpleProperty on a String property. |
| */ |
| @Test |
| public void testSetSimpleString() |
| { |
| final String oldValue = (String) bean.get("stringProperty"); |
| final String newValue = oldValue + " Extra Value"; |
| bean.set("stringProperty", newValue); |
| assertEquals("Matched new value", newValue, bean.get("stringProperty")); |
| } |
| |
| /** |
| * Tests set on a null value: should throw NPE. |
| */ |
| @Test(expected = NullPointerException.class) |
| public void testAddNullPropertyValue() |
| { |
| bean.set("nullProperty", null); |
| } |
| |
| /** |
| * Test the retrieval of a non-existent property. |
| */ |
| @Test(expected = IllegalArgumentException.class) |
| public void testGetNonExistentProperty() |
| { |
| bean.get("nonexistProperty"); |
| } |
| |
| /** |
| * Base for testGetDescriptorXxxxx() series of tests. |
| * |
| * @param name Name of the property to be retrieved |
| * @param type Expected class type of this property |
| */ |
| protected void testGetDescriptorBase(final String name, final Class<?> type) |
| { |
| final DynaProperty descriptor = bean.getDynaClass().getDynaProperty(name); |
| |
| assertNotNull("Failed to get descriptor", descriptor); |
| assertEquals("Got incorrect type", type, descriptor.getType()); |
| } |
| |
| /** |
| * Tests whether nested properties can be accessed. |
| */ |
| @Test |
| public void testNestedPropeties() |
| { |
| final ConfigurationDynaBean nested = (ConfigurationDynaBean) bean.get("mappedProperty"); |
| |
| final String value = (String) nested.get("key1"); |
| assertEquals("Can find first value", "First Value", value); |
| |
| nested.set("key1", "undefined"); |
| assertEquals("Incorrect value returned", "undefined", bean.get("mappedProperty.key1")); |
| } |
| |
| /** |
| * Tests if reading a non-indexed property using the index |
| * get method throws an IllegalArgumentException as it |
| * should. |
| */ |
| @Test(expected = IllegalArgumentException.class) |
| public void testGetNonIndexedProperties() |
| { |
| bean.get("booleanProperty", 0); |
| } |
| |
| /** |
| * Tests whether accessing a non-indexed string property using the index get |
| * method causes an exception. |
| */ |
| @Test(expected = IllegalArgumentException.class) |
| public void testGetIndexedString() |
| { |
| bean.set("stringProp", "value"); |
| bean.get("stringProp", 0); |
| } |
| |
| /** |
| * Tests whether an indexed access to a non-existing property causes an |
| * exception. |
| */ |
| @Test(expected = IllegalArgumentException.class) |
| public void testGetIndexedNonExisting() |
| { |
| bean.get("Non existing property", 0); |
| } |
| |
| /** |
| * Tests if writing a non-indexed property using the index |
| * set method with an index > 0 throws an IllegalArgumentException as it |
| * should. |
| */ |
| @Test(expected = IllegalArgumentException.class) |
| public void testSetNonIndexedProperties() |
| { |
| bean.set("booleanProperty", 1, Boolean.TRUE); |
| } |
| } |